php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76573 Log file is created with wrong permissions if deprecated configuration found
Submitted: 2018-07-03 15:49 UTC Modified: 2018-07-23 13:38 UTC
From: mbiebl at messageconcept dot com Assigned:
Status: Open Package: IIS related
PHP Version: 7.2.7 OS: Windows Server 2016
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: mbiebl at messageconcept dot com
New email:
PHP Version: OS:

 

 [2018-07-03 15:49 UTC] mbiebl at messageconcept dot com
Description:
------------
We run PHP 7.2.7 under IIS/Windows Server 2016.
php.ini is setup to log to
error_log = "C:\Windows\temp\PHP72_errors.log"

We also use PHP Manager for IIS. If you use PHP Manager to switch into Development mode, it will add the following to php.ini:
track_errors = On

With 7.2.7 this will trigger a deprecation warning.
A side effect of this is, that if the log file C:\Windows\temp\PHP72_errors.log does not exist, it will be created containing this line

[03-Jul-2018 17:37:22 Europe/Berlin] PHP Deprecated:  Directive 'track_errors' is deprecated in Unknown on line 0

but more importantly the file permissions will be wrong. The IUSR (which is used by IIS) will have no read/write/access permissions at all. So subsequent calls to error_log() will fail.

If I remove "track_errors = On" from php.ini and trigger the file creation via error_log() the file permissions are correct.

It seems when the php.ini is parsed and the deprecation notice logged, a different code path is used to create the log file which does not setup proper file permissions.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-07-04 14:15 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2018-07-04 14:15 UTC] ab@php.net
Thanks for the report. Does your INI have fastcgi.impersonate=1? The deprecation warnings are thrown at startup, so any relevant operation at that stage happens under a user configured in IIS.

Thanks.
 [2018-07-05 15:25 UTC] mbiebl at messageconcept dot com
-Status: Feedback +Status: Open
 [2018-07-05 15:25 UTC] mbiebl at messageconcept dot com
Hi, thanks for your reply.
We have the following cgi related settings ini php.ini:

cgi.fix_pathinfo=1
cgi.force_redirect=0
fastcgi.impersonate=1
 [2018-07-05 19:04 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2018-07-05 19:04 UTC] ab@php.net
Thanks for checking. Yes, the impersonation is the only relevant point here. A debug session has confirmed the first assumption I've mentioned. The flow is as follows

- IIS itself runs under system or perhaps network service
- the PHP process launched by IIS has same privileges
- once the PHP process encounters a request, it will impersonate by calling ImpersonateNamedPipeClient()
- when the PHP process finishes a request, it'll revert the impersonation by calling RevertToSelf)(

That looks like a general collision. As long as the process didn't impersonate, the security will be different. Like in this case - the first warning creates a non existent log file with the privileges insufficient for the impersonated access. A solution to this can be tricky if possible at all.

So far some possible workarounds

- switch to the syslog facility
- if feasible, pre create the log file with acceptable permissions
- use a predefined unprivileged account for PHP, might work but not sure

Turning off the impersonation is not a solution at all, security-wise! At least you can check to confirm my hypoteses.

I'm still looking through the APIs for a solution. If you have some ideas, please share. If there is a way to impersonate the process before it actually accepts a connection, a solution were thinkable. However, it might have impacts in other areas.

Thanks.
 [2018-07-05 19:26 UTC] mbiebl at messageconcept dot com
-Status: Feedback +Status: Open
 [2018-07-05 19:26 UTC] mbiebl at messageconcept dot com
Would it be possible to delay the logging of those deprecation warnings until the PHP process runs with the correct privileges?
 [2018-07-05 19:53 UTC] mbiebl at messageconcept dot com
Just tried to use syslog but then got only 500 errors (php-cgi.exe crashing).
 [2018-07-05 19:55 UTC] spam2 at rhsoft dot net
where would you store and delay them? logs are written when they happen

just make sure that your defined logfiles exist from the begin and have the correct permissions and you are done
 [2018-07-05 20:17 UTC] mbiebl at messageconcept dot com
Well, even if I pre-create the log file somehow (say in the application installer), it's not unthinkable that the admin cleans up C:\Windows\Temp at some point (along with the log file). So I'd need a separate daemon which is running all the time and watches C:\Windows\Temp and immediately re-creates the file.
Otherwise, on the next connection attempt the file will be created by php with the wrong permissions again leading to a very hard to debug problem for the admin.
 [2018-07-05 20:18 UTC] spam2 at rhsoft dot net
well, having logfiles in C:\Windows\temp\PHP72_errors.log must be a Windows attitude, i am out here...
 [2018-07-05 21:00 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2018-07-05 21:00 UTC] ab@php.net
@mbiebl could you please share a backtrace or a crash dump from the case the syslog scenario crashes? See https://bugs.php.net/bugs-generating-backtrace-win32.php

Thanks.
 [2018-07-05 21:01 UTC] ab@php.net
Or some relevant configs, at least.

Thanks.
 [2018-07-05 21:31 UTC] mbiebl at messageconcept dot com
-Status: Feedback +Status: Open
 [2018-07-05 21:31 UTC] mbiebl at messageconcept dot com
Hi Anatol,
I'd say let's focus on the issue at hand in this bug report. If I find time to generate a backtrace I'll file a separate bug report for the php-cgi.exe crash
 [2018-07-23 13:38 UTC] ab@php.net
There seems no good way to solve this issue. Perhaps, one could temporarily redirect all the logging to syslog while in the startup phase. I had a partial try on that and it seems like it could work. But that way the information would go into a non obvious location where error_log where configured to be a file.

Another idea were to touch the error log file with permissions for IUSRS after the startup was done. Here is the obvious issue, that we can't reliably determine whether the FCGI process indeed runs under IIS. Even if fastcgi.impresonate is set. 

Another solution that should work better is to use some path outside c:\windows\temp. The permission issue exists, because any file inside c:\windows inherits very strict permissions. Once the log file was created as system, an impersonated process won't be able to access it because the created file inherits the security attributes from c:\windows. Putting the log file into some other location with less strict permissions would solve this.

Otherwise I would say it is a documentation issue. I think, c:\windows should not be used for any writing operations anyway. The solution would be either usisg syslog or using a path outside c:\windows with a bit more lose permissions.

@mbiebl btw the syslog issues should be fixed now. Not sure they're released yet, but the latest snapshots should be fine in that regard.

Thanks.
 
PHP Copyright © 2001-2018 The PHP Group
All rights reserved.
Last updated: Tue Dec 18 10:01:25 2018 UTC