Viewed   133 times

I have a built a script around class.upload from http://www.verot.net/php_class_upload.htm

Basically what it is that all my images are stored on the server in a directory called /images/

The script I built basically takes some parameters from my website such as /xyzDir/tomnjerry.jpg?w=100&h=100&fill=1&color=fff

Then I have mod_rewrite which reads the file from /xyzDir/ into a php script which then translates the width and height and returns the image.

Lately I have noticed some idiots from Turkey trying to input weird characters into the parameters w= and h=

On my script I do check to make sure only integer is allowed in width and heigh and fill can be either 1 or 2 and color can only be certain values which i check via array.

I just want to see if there is anything else I should be doing in order to avoid getting hacked.

Thanks

 Answers

4

Always remember, Filter In, Escape Out for all user supplied (or untrusted) input.

When reading user supplied data, filter it to known values. DO NOT BLACKLIST! Always always always always whitelist what you are expecting to get. If you're expecting a hex number, validate it with a regex like: ^[a-f0-9]+$. Figure out what you expect, and filter towards that. Do none of your filenames have anything but alpha, numeric and .? Then filter to ^[a-z0-9.]+$. But don't start thinking blacklisting against things. It won't work.

When using user-data, escape it properly for the use at hand. If it's going in a database, either bind it as a parameterized query, or escape it with the database's escape function. If you're calling a shell command, escape it with escapeshellarg(). If you're using it in a regex pattern, escape it with preg_quote(). There are more than that, but you get the idea.

When outputting user data, escape it properly for the format you're outputting it as. If you're outputting it to HTML or XML, use htmlspecialchars(). If you're outputting to raw headers for some reason, escape any linebreaks (str_replace(array("r", "n"), array('r', 'n'), $string)). Etc, etc, etc.

But always filter using a white-list, and always escape using the correct method for the context. Otherwise there's a significant chance you'll miss something...

Friday, September 16, 2022
2

I applaud your efforts. You must, friendly community member, consider decoupling your operations.

1) Have one function/routine/class/method for filtering input (filter_input_array(), strip_tags(), str_ireplace(), trim(), etc ...). You may want to create functions that use loops to do filtering. Tricks such as double encoding, one-time-strip-spoofing, and more can defeat single usage of things like strip_tags().

Here is a strip_tags() wrapper method from my Sanitizer class. Notice how it compares the old value to the new value to see if they are equal. If they are not equal, it keeps on using strip_tags(). Although, there is quite of bit of preliminary INPUT_POST / $_POST checking done before this method is executed. Another version of this using trim() is actually executed before this one.

private function removeHtml(&$value)
{    
    if (is_scalar($value)) {
        do {
            $old = $value;
            $value = strip_tags($value);

            if ($value === $old) {
                break;
            }
        } while(1);
    } else if (is_array($value) && !empty($value)) {
        foreach ($value as $field => &$string) {
            do {
                $old = $string;
                $string = strip_tags($string);

                if ($string === $old) {
                    break;
                }
            } while (1);
        }
    } else {
       throw new Exception('The data being HTML sanitized is neither scalar nor in an array.');
    }

    return;
}

2) Have another one for validating input (filter_var_array(), preg_match(), mb_strlen, etc...)

Then, when your data needs to switch contexts ...

A) For databases, use prepared statements (PDO, preferably).

B) For returning / transmitting user input to the browser, escape the output with htmlentities() or htmlspecialchars accordingly.

In terms of magic quotes, the best thing to do is just disable that in the php.ini.

Now, with those various constructs having their own areas of responsibility, all you have to do is manage the flow of logic and data inside of your handler file. This includes providing error messages to the user (when necessary) and handling errors/exceptions.

There is no need to use htmlentities() or htmlspecialchars immediately if the data is going from the HTML form directly into the database. The point of escaping data is to prevent it from being interpreted as executable instructions inside a new context. There is no danger htmlentities() or htmlspecialchars can resolve when passing data to a SQL query engine (that is why you filter and validate the input, and use (PDO) prepared statements).

However, after the data is retrieved from database tables and is directly destined for the browser, ok, now use htmlentities() or htmlspecialchars. Create a function that uses a for or foreach loop to handle that scenario.

Here is a snippet from my Escaper class

public function superHtmlSpecialChars($html)
{
     return htmlspecialchars($html, ENT_QUOTES | ENT_HTML5, 'UTF-8', false);
}

public function superHtmlEntities(&$html)
{
    $html = htmlentities($html, ENT_QUOTES | ENT_HTML5, 'UTF-8', false);
}

public function htmlSpecialCharsArray(array &$html)
{       
    foreach ($html as &$value) {
        $value = $this->superHtmlSpecialChars($value);
    }

    unset($value);
}

public function htmlEntitiesArray(array &$html)
{       
    foreach ($html as &$value) {
        $this->superHtmlEntities($value);
    }

    unset($value);
}

You'll have to tailor your code to your own personal tastes and situation.

Note, if you plan on processing the data before sending it to the browser, do the processing first, then escape with your handy-dandy htmlentities() or htmlspecialchars looping function.

You can do it!

Wednesday, October 12, 2022
 
sudoplz
 
1

One thing I've seen a lot that gets developed as a feature and not seen as a security hole until it's too late are state-changing GET requests. These can easily result in cross-site request forgery. For example, your application could have a link to http://mysite.com/logout which logs users out. But a third party site can add code like this:

<!-- on evil.com site -->
<img src="http://mysite.com/logout">

Then when users load the page on evil.com, they are logged out of mysite.com!

The worst problems happen when sites implement an API using state-changing GET requests. For example, if I ran a social networking site with urls like site.com/addfriend, site.com/sendmessage, etc. and I gave out those urls to developers who were going to make applications for my site, the developers would have to deal with an API change when the security vulnerability was discovered.

Saturday, October 22, 2022
1

If you are talking about someone else's server, then the short answer is no. If third parties could read your PHP source code, that would be quite a security hole, since PHP files tend to contain database passwords, hash keys, proprietary algorithms and other goodies that you don't want falling in the wrong hands.

If you are talking about your own server (ie. that you yourself have access to), then there are simple scripts that you can put on the server, that allow you to specify a path to any file on the server and have it returned as plaintext. However, you NEVER EVER want to place such a script on a production server, for the reasons mentioned above.

Monday, November 21, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :