It is quite common to not let any process on a web server run longer
then a specified time. This is usually made possible by some trivial
shell scripting that checks the running time of certain processes.
This annoyance is also not limited to PHP. Any scripting language that
has the ability to execute something with the means of system() can
create and call a script that uses memory and waits indefinitely.
This is also an annoyance that will not be seen as a bug or will be
"fixed" because it would leave the language almost useless. Although
some do attempt to fix this by disabling all possible functions that can
execute something like exec, system, eval, etc. but it is not limited to
that. The same long wait can be achieved with fsockopen or any other
stream function like fread, fwrite, etc. Even if your wait is limited to
60 seconds you can just repeat it in a simple loop and still maintain
the very low actual cpu time usage.
This is and has never been a security hole or threat. It will also never
be. It is just an annoyance for which many solutions are already available.
Greetings,
Mark Sanders.
Which are the avalaible solutions ?
Thanks.
„Using PHP as an in-process script interpreter grants script authors control over the httpd children.”
It is possible to make DoS (block all sockets/memory exe.). (more in Xploit magazin)
Reason: Use PHP via a CGI interpreter with RLimit* directives.
Anyone how use PHP as an in-process script interpreter, can be dangerous.
Best Regards,
Maksymilian Arciemowicz
securityreason.com
http://securityreason.com/key/Arciemowicz.Maksymilian.gpg
The reasoning behind this is behind the definition of vulnerability,
and here is a good one:
"a weakness in a system allowing unauthorized action [(NRC91:301;
Amo94:2) Sandia] A flaw or weakness in a system's design,
implementation, or operation and management that could be exploited to
violate the system's security policy. ..."
[http://www.terena.org/activities/tf-csirt/iodef/docs/i-taxonomy_terms.html]
In this case a security policy has been designated with the
"max_execution_time" directive and that policy is being violated by
the blocking code. As you say there are ways around this, (kill
script, resource limiting, etc..) however there can be similar
mitigating circumstances in any situation where you have a
vulnerability (firewall, executable stack protection, etc..).
As with any vulnerability it is the vendor's responsibility to provide
a fix and protect it's users. Many web developers or administrators
may not know of this issue, and therefore will not be providing a mitigation.
I am of the opinion that PHP (As PHP (not Apache) is the one providing
the "max_execution_time" directive) should automatically interrupt any
processes in the process tree from the current script execution to
avoid violation of the directive.
--
Charles Morris
cmo...@cs.odu.edu,
cmo...@occs.odu.edu
Network Security Administrator,
Software Developer
Office of Computing and Communications Services,
CS Systems Group Old Dominion University
http://www.cs.odu.edu/~cmorris
-Michael
> I agree with you that this is a known issue, and that there are ways
> around it, however I would in fact call it a vulnerability.
That depends upon your threat model.
If you are treating max_execution_time as protection against malicious
scripts, then it's a vulnerability, and not one which is easily fixed.
OTOH, if you merely consider it a precaution against "runaway"
scripts, which aren't actively trying to evade such constraints, then
it's just a limitation (and, AFAICT, an intentional one, i.e. it's
only intended to limit CPU usage).
> I am of the opinion that PHP ... should automatically interrupt any
> processes in the process tree from the current script execution
That's easier said than done, particularly if you are trying to
protect against malicious scripts.
A child which is trying to evade such termination can fork() and have
the parent exit. This will leave a gap in the chain of parent/child
relationships, so it can no longer be traced back to the original
child process. Even if PHP runs each child in a separate process group
or session, the child can just move itself to a new process group or
session.
Almost anything which is inherited across a fork() can be discarded or
changed. The things which can't (UID, GIDs, chroot, etc) would need
root privilege to initialise.
Essentially, once PHP has spawned a child, it's control over the child
and its descendents is limited to whatever features the kernel
provides. If you limit yourself to bare-bones POSIX (no capabilities,
or extensions such as SELinux or RSBAC), the set of features is rather
lacking in this regard.
--
Glynn Clements <gl...@gclements.plus.com>
That definition, however useful it may be in some contexts, is
sufficiently broad that it can be used to argue that essentially any
affordance is a vulnerability.
For example: password-based login systems enforce security using secrets
held by humans, and we know humans are inherently unreliable, so
password-based login systems are a vulnerability.
That's true (and indeed password-based login has been widely critiqued
as a really lousy authentication mechanism), but in itself it's a vapid
observation.
> In this case a security policy has been designated with the
> "max_execution_time" directive and that policy is being
> violated by the blocking code.
No, it is not, since "execution time" here is defined as CPU time. This
"vulnerability" report is factually incorrect, as well as pointless.
> As with any vulnerability it is the vendor's responsibility
> to provide a fix and protect it's users.
No, it is not. My desktop machine, as supplied by the vendor, was
vulnerable to the dreaded "power failure" denial of service attack. Was
it Dell's responsibility to supply me with a UPS? (And what if the UPS
battery fails? Maybe Dell should be required to provide me with a
guaranteed unlimited supply of electricity.)
> I am of the opinion that PHP (As PHP (not Apache) is the one
> providing the "max_execution_time" directive) should
> automatically interrupt any processes in the process tree
> from the current script execution to avoid violation of the directive.
You're proposing the subsystem implement an asynchronous watchdog that
uses some as-yet-unspecified, platform-dependent mechanism to terminate
processes out of band, with no recovery? Nothing could possibly go wrong
with *that*.
Let me see if I have this straight. The threat is that an attacker can
get PHP running on a server to make a sleep() call with a large
argument, and thus consume resources. The solution is a fragile,
unpredictable, arbitrary hack.
I'd say the attacker's already won - a good trick, since this
hypothetical attacker doesn't even exist.
A better question might be: just what branch of the attack tree are you
trying to prune? If your attacker can run arbitrary PHP code on your
server, why would he waste time with this sleep() nonsense?
--
Michael Wojcik
Principal Software Systems Developer, Micro Focus