0

In a web application, I control the call of pages via an URL parameter e.g. "Page". As a security feature, I created a whitelist as an array like this:

$validPageValues = ['foo', 'bar', 'baz'];

Before loading a page, the application checks whether the value of the page parameter corresponds to an entry in the whitelist. In the example above, the valid values ​​would be "foo", "bar" and "baz" but not "evilfolder"

Each page also has its own folder in which there is a template for each page.

templates/
    foo
    bar
    baz

I am now considering to fill the whitelist automatically based on the existing folders inside "templates". However, I am not sure whether this could lead to a security vulnerability. If e.g. Someone manages to create a folder on this server and store malicious code in it.

Trying a comparison: You could say that someone who manages to create a folder and place malicious code could also go into the php-file with the whitelist and adjust it. But I think there is a difference between them. Creating a folder with malicious content is certainly possible in several ways and without access to the entire file system. Modifying a PHP file in a "protected" system is certainly more difficult.

Another similar consideration: Dynamic loading of PHP classes or methods based on the page parameter. There is also a class for each page, I am also considering PHP classes or methods of an interface class to be loaded automatically via this parameter and instantiated with an autoloader. It feels even more problematic for me to load a class based on user requests. I didn't really want to do that, but I wanted to know if there was such a possibility and it was worth considering.

I read something similar here - Dynamic php class generation based on url parameters in the end the solution was different from the one I'm looking for.

  • Can you elaborate a bit who would be able to create folders and/or whitelist them in your scenario? It sounds a bit like you are trying to build a free hosting website or something like that, so I'd like to know who are the actors and what each of them can or can not do before I respond. Thanks! – ArSeN Apr 04 '20 at 14:34
  • Thank you for your reply! No, this is not a free hosting Website. It's more a platform where users interact with each other. Only the developer(s) is(are) able to create folders as described above. Users can trigger a method that creates a folder if he for example uploads a profile Image, but thats all. Letting a folder be created to manipulate the whitelist was just one of many examples. Quite apart from the fact that it is certainly already difficult enough to create a folder, you are probably right, it may be totally unlikely, ...(see next comment) – Leto Casonic Apr 04 '20 at 15:04
  • ... but we developers are always one step behind. I just wonder whether it is more unsafe to generate the whitlist than to create it manually. – Leto Casonic Apr 04 '20 at 15:05

1 Answers1

0

I really like your question and think it is interestering, thus I am going to attempt to answer it. If you feel like I should put more detail on certain aspects of the answer, feel free to comment and I will expand the answer as good as I can.

After you elaborated in the comments it appears your question boils down to:

Is it unsafe to dynamically check if a directory exists, depending on user input?

To answer this we must look at multiple aspects of security but first and foremost ask ourselves what "safe" really means.

What is safety?

What I want to point out here is that safety is always a ratio between "work done to compromise the system" and "damage that can be done to the system by doing so". I.e., if you put a lot of effort into it (for arguments sake, lets say infinite effort), you would most likely break every system sooner or later (that is, with either more or with less effort).

Having said that, we should tighten the scope of this topic to PHP. As you may or may not know, PHP is mostly written in C and C++, which both have their own flaws on top of the issues that might exist with PHP on its own (which would be because of the authors of PHP did miss something). I am only mentioning this to point out that there are several layers of security to consider and thus, answers of the sorts "is this safe" should never be taken for 100% answers.

Is it "safe" to dynamically check for folders by user input?

It depends!

Before getting into details, please note that whether:

  1. you build your whitelist dynamically from user input or
  2. you dynamically check if there is a folder with a name from user input

can be considered the same thing from a security standpoint and only the timing of flaw would be different.

Now on to the details, and as I already said: It depends! There are plenty of possible implementations that would really open the gates to every evil input, such as running system commands to check if a folder exists, here is an example:

$input = $_GET['folder']; // let's say this is called like /?folder=foo
exec("test -d " . $input, $output, $return);
$doesFolderExist = ($return == 0); // variable would be true if folder exists

This is one way to implement whether a folder exists, however it is a deliberately stupid one to demonstrate how one could be going wrong about this. Why is it stupid? It is widely open for Command Injection. For example, an attacker could call the URL like /?folder=foo;rm -rf / and the servers entire disk would possibly be deleted.

Back to reasonable solutions

After I rambled about a bit on how nothing is entirely safe above, there are certainly some ways which - at least from my point of view - can be considered safe enough to be trusted with user input. One option would be to use glob() and check whether the folder is there, but I think this is even unnecessarily complicated.

For your specific use case I think a simple file_exists() check should suffice and not open a gate to evil user input, let's revisit the example from above:

$input = $_GET['folder']; // again, imagine this is called like /?folder=foo
$doesFolderExist = file_exists(__DIR__ . $input); // variable would be true if folder exists

As you can see I added the __DIR__ constant to make checking of folder existance relative to the current PHP file, you might have to adjust that depending on your use case.

There is however one pitfall, so please do not use this solution as it is, but keep reading!

Nifty attackers might figure out that you are using a relative path and try and sneak a weird parameter in that cascades through your file system to check whether certain things are there or not. For example, an attacker might call the URL like /?folder=../../home/admin which could possibly give him some insight on whether there is a user with the name "admin" in this system or not.

The possible use cases for this are plenty, which is why such file/directory checks with user input should always be limited to a very specific scope. For example, you could make sure that walking folders up is not possible by replacing away the syntax, and therefore the final solution would look like this:

$input = $_GET['folder']; // attacker might call /?folder=../../user/foo
$input = str_replace('../', '', $input); // sanitize
$doesFolderExist = file_exists(__DIR__ . $input); // variable would be true if folder exists

This way the attacker would "only" know if within the same directory where your PHP file is there is a subfolder named user/foo but not actually find out if there is a system user with the name "foo". Of course more sanitization is always possible depending on your expected structure. For example, if you only allow one level of subfolders, you could replace away (same way as in the example) all the slashes in the user input.

In a nutshell

I hope I could point out that security is never absolute but as long as you take the required measures you can be pretty much on the safe side, here are some ground rules you should (almost) always follow:

  1. All input is evil, treat it as such
  2. Try and think of ways to break your own solution
  3. When in doubt, expect the worst possible scenario

Hope this helps!

ArSeN
  • 5,133
  • 3
  • 19
  • 26
  • Thank you for your detailed explanation. The question of security in software development will probably have to be rethought on the spot and based on your feedback, because it is not about making software secure, but trusting on the basis of the experience of as many developers as possible - that was what I tried in the question to install. This process is clearly visible in this short correspondence, I think. I will let your thoughts flow into my question but do not change the question itself so that this process remains visible. The question "is it safe" is probably not enough. – Leto Casonic Apr 05 '20 at 11:17