php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #79324 Alternative to safe_mode_protected_env_vars
Submitted: 2020-02-29 18:45 UTC Modified: 2020-03-01 17:32 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:2 (100.0%)
From: diego dot blanco at treitos dot com Assigned:
Status: Open Package: Scripting Engine problem
PHP Version: 7.4.3 OS:
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: diego dot blanco at treitos dot com
New email:
PHP Version: OS:

 

 [2020-02-29 18:45 UTC] diego dot blanco at treitos dot com
Description:
------------
In old versions of PHP it was possible to prevent end users to set sensitive environment variables such as LD_PRELOAD or LD_LIBRARY_PATH using safe_mode_protected_env_vars.

After safe_mod was deprecated I cannot find any way of doing this. The only workaround is to absolutely disable the putenv function.

Is this feature hidden anywhere? If so, it might be good to update the documentation and add links in this page: https://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-protected-env-vars

If it is not, I think this should be implemented.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-03-01 00:19 UTC] stas@php.net
-Type: Security +Type: Feature/Change Request -Package: PHP Language Specification +Package: Scripting Engine problem
 [2020-03-01 17:06 UTC] diego dot blanco at treitos dot com
I see that the type was changed from Security to a "Feature Request". I am not saying that this change is wrong but I'd like to provide more information to describe why this has an important security impact.

It is common to add some security measures when installing a PHP environment. Things like "open_basedir", "disable_functions", etc. This way if a website is compromised you can limit the impact in other websites or services in the same server.

With the current PHP configuration options it is not possible to prevent users from setting environment variables like LD_PRELOAD. Due to this a user can upload a custom library and use LD_PRELOAD to execute code from that library that will effectively bypass any of the previous restrictions.

In other words, a user that can execute custom PHP code can easily bypass restrictions like "open_basedir" or "disabled_functions" because systems administrators do not have a way to prevent users from setting LD_PRELOAD (other than disabling "putenv" function).

I think this has a significant impact in security.
 [2020-03-01 17:10 UTC] bugreports at gmail dot com
and how is that user supposed to load any binary code in a sensible setup with dl() not enabled to begin with? LD_PRELOAD in the middle of the process is completly meaningless
 [2020-03-01 17:22 UTC] diego dot blanco at treitos dot com
You can use "strace" to see what external functions some PHP functions. For example the "mail" function calls "geteuid". So you can code a library that reimplements that function (i.e. "geteuid") and do whatever you want. Then you use LD_PRELOAD to load your custom library and then call the PHP function (i.e. "mail") so it will trigger your custom code.

You have a good example here using these very same functions: https://github.com/0verl0ad/sifilis-PoC/
 [2020-03-01 17:29 UTC] bugreports at gmail dot com
when your setup is able to start a suid binary like sendmail and mail() is not disabled you have much more things to worry

again: in a *sensibke* setup with security in mind there are nol libraries loaded and binaries executed at the runtime of a script, all the php extensions and tehir libraries are lareay loaded long before you can call setenv()
 [2020-03-01 17:32 UTC] nikic@php.net
To clarify, the "Security" category is for bugs that need to be kept private until the fix has been released. The classification change is not supposed to imply that there is no relation to security here, just that it doesn't need to be confidential.
 [2020-03-01 17:49 UTC] diego dot blanco at treitos dot com
Thank you for your clarification Nikic. I just wanted to give more information about the problem so the implications are better understood. If you consider this is the right category, that is totally fine for me.

Regarding disabling mail() for a secure setup, although I agree it would be safer, it is an expected feature for most of legit users so disabling it is not as an easy choice as disabling shell_exec(). For this reason it is usually enabled and the use of LD_PRELOAD to bypass restrictions is well known among web hackers (both white and black hats)
 [2020-03-01 17:52 UTC] bugreports at gmail dot com
i don't know any software which don't support smtp via phpmailer and mail() is in disabled_functions() here since 2002 which is 18 years now
 [2020-03-01 18:12 UTC] diego dot blanco at treitos dot com
My point here is to have a sensible solution that has a minimal impact on end users and having a way to limit what environment variables a user is able to set seems the right way.

There are users that still use mail() in their custom code. I agree that disabling mail() would solve the problem (in case there aren't any other common external runtime calls) but that would have impact in some users. Disabling putenv() will also solve the problem but again, although most of the software does not require it, it is a feature that some users might miss.

In any case, I already said that I am ok with considering this a feature request. I just wanted to give some more information regarding some of its security implications.

I think it could be useful to have some configuration that allowed to do this as it was possible in the past. If you do not think that is the case, feel free to disregard this bug report and mark it as wontfix.
 [2020-05-26 18:47 UTC] diego dot blanco at treitos dot com
> I don't know any software which don't support smtp via phpmailer and mail() is in disabled_functions() here since 2002 which is 18 years now.

I am afraid that Wordpress (version 5.4.1, latest as of today) relies by default on mail(). Despite using PHPMailer, it seems to default to mail(). With mail() in disabled_functions, things like password reset mails won't work.

I've been trying to workaround this but there isn't a good alternative. I wish this wasn't disregarded so easily.
 [2020-05-26 18:59 UTC] bugreports at gmail dot com
https://www.siteground.com/tutorials/wordpress/use-smtp/
 [2020-05-26 22:45 UTC] diego dot blanco at treitos dot com
Yes, it is possible to do it if you install a plugin to send mails via SMTP using localhost. The default wordpress installation does not allow that.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 30 17:01:29 2024 UTC