3

I'm trying to enforce a policy of mutually exclusive write and execute. Since the interpreter only needs read access to be able to execute a file, it becomes very tricky to avoid loading php code that is not trusted.

So, in essence, if a php file can be opened for writing by the interpreter, or if the file is owned (ie, can change permissions to have write access) by the user running the php process I'd like to stop the file from being loaded. Does anyone know of a way to achieve this?

This presumably only makes sense in a hosting type environment where the user uploading legitimate PHP code and the php interpreter's user are different users. As such, this would probably need to be some config option as the restriction only make sense in certain configurations and goes straight against all "best practices" recommendations I could find on the matter.

3
  • just run your untrusted code in a virtual machine. Upload, spin up machine, push php file into VM, execute, gather output, spin down machine, remove image, put back pristine image, rinse and repeat. Commented Apr 20, 2018 at 11:43
  • Really not a viable solution. Commented Apr 20, 2018 at 12:04
  • Your post might be more suited on either security.stackexchange or webmasters.stackexchange I think. Commented Apr 20, 2018 at 12:28

1 Answer 1

2

There's a much easier way to accomplish this property than worrying about filesystem permissions:

  1. Ship all of your code in a Phar (PHP Archive).
  2. Use a digital signature for your Phars.

By default, PHP treats PHP archives as read-only. See SitePoint's guide for serving websites from a PHP Archive.

But even if someone can circumvent PHP through misconfiguration, by using a digital signature (for which the private key must NOT be stored on the webserver, only the public key), they will not be able to tamper with the Phar (unless they steal your private key).


Additionally, Snuffleupagus seems helpful for locking down what PHP scripts are allowed to do.

Sign up to request clarification or add additional context in comments.

8 Comments

Mostly I don't control the code being deployed, nor does the suggestion really solve my problem. A vulnerability in that code could still enable an attacker to create a custom .php file in the documentroot that end up then being executable. Essentially what I'm trying to sort out is the class of attacks where an upload weakness ends up being a shell exploit.
Are you looking for a total solution? Then only allow .phar files to be executed, and create a deployment script that forces people to publish their arbitrary code as a .phar. Security is about tradeoffs; you won't find a trivial, absolute solution to all threats. In general, your time is better spent making the code itself secure than trying to use configuration to protect insecure code.
No. This is a small piece of a much larger scheme. Unfortunately I don't have the luxury of being able to enforce .phar files. Specifically I'm looking to solve two classes of issues currently, and I've got a handle on the one currently.
Okay, it sounds like you're trying to do something extremely specific. Too specific for a Stack Overflow question, I'd wager. If you still need help, my only suggestion is posting a listing in the Jobs section and hoping someone knowledgeable can give this problem the attention it deserves.
Thanks for the feedback. I engaged because I hoped there is a better solution. We've started adding a shim between php-fpm process and glibc (By way of LD_PRELOAD) in order to intercept certain system calls to essentially enforce some checks (eg, opening any .php file for reading is only allowed if write access would be denied). So far only one wordpress plugin seems to break irrecoverably so we were forced to add an exception for that. We haven't switched it into enforcing mode just yet. Other checks includes similar for execve() family of calls.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.