How to Secure Your PHP Script (PHP SECURITY)

Collapse
This is a sticky topic.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    info How to Secure Your PHP Script (PHP SECURITY)

    When offering an Internet service, you must always keep security in mind as you develop your code. It may appear that most PHP scripts aren't sensitive to security concerns; this is mainly due to the large number of inexperienced programmers working in the language. However, there is no reason for you to have an inconsistent security policy based on a rough guess at your code's significance. The moment you put anything financially interesting on your server, it becomes likely that someone will try to casually hack it. Create a forum program or any sort of shopping cart, and the probability of attack rises to a dead certainty.

    Here are a few general security guidelines, I've found from internet for my next .mobi product.


    Don't trust forms.

    Hacking forms is trivial. Yes, by using a silly JavaScript trick, you may be able to limit your form to allow only the numbers 1 through 5 in a rating field. The moment someone turns JavaScript off in their browser or posts custom form data, your client-side validation flies out the window.

    Users interact with your scripts primarily through form parameters, and therefore they're the biggest security risk. What's the lesson? Always validate the data that gets passed to any PHP script in the PHP script.

    Don't trust users.
    Assume that every piece of data your website gathers is laden with harmful code. Sanitize every piece, even if you're positive that nobody would ever try to attack your site. Paranoia pays off.

    Turn off global variables.
    The biggest security hole you can have is having the register_globals configuration parameter enabled. Mercifully, it's turned off by default in PHP 4.2 and later.
    Novice programmers view registered globals as a convenience, but they don't realize how dangerous this setting is. A server with global variables enabled automatically assigns global variables to any form parameters. For an idea of how this works and why this is dangerous, let's look at an example.
    Let's say that you have a script named process.php that enters form data into your user database. The original form looked like this:
    PHP Code:
    <input name="username" type="text" size="15" maxlength="64"
    PHP Code:
    <?php
    // Define $authorized = true only if user is authenticated
    if (authenticated_user()) {
        
    $authorized true;
    }
    ?>
    Recommended Security Configuration Options

    There are several PHP configuration settings that affect security features. Here are the ones that I use for production servers:In general, if you find code that wants to use these features, you shouldn't trust it. Be especially careful of anything that wants to use a function such as system,it's almost certainly flawed.

    With these settings now behind us, let's look at some specific attacks and the methods that will help you protect your server.
    Last edited by firemax; 04.03.10, 08:07.

    Free Mobile Web Scripts by me: Free Youtube Downloader, Tweets Reader, Facebook Wall Posts Reader
    PHP Tutorials: How to Secure Your PHP Script (PHP SECURITY)
    Want to Develop/Edit your WAP/Web Site? Add me to Gtalk (gmail) 'lakshan1989' or PM me.

    #2
    SQL Injection Attacks

    Because the queries that PHP passes to MySQL databases are written in the powerful SQL programming language, you run the risk of someone attempting an SQL injection attack by using MySQL in web query parameters. By inserting malicious SQL code fragments into form parameters, an attacker attempts to break into (or disable) your server.

    Let's say that you have a form parameter that you eventually place into a variable named $product, and you create some SQL like this:

    $sql = "select * from pinfo where product = '$product'";


    If that parameter came straight from the form, use database-specific escapes with PHP's native functions, like this:

    $sql = 'Select * from pinfo where product = '"'
    mysql_real_escape_string($product) . '"';


    If you don't, someone might just decide to throw this fragment into the form parameter:

    39'; DROP pinfo; SELECT 'FOO


    Then the result of $sql is:

    select product from pinfo where product = '39'; DROP pinfo; SELECT 'FOO'


    Because the semicolon is MySQL's statement delimiter, the database processes these three statements:

    select * from pinfo where product = '39'
    DROP pinfo
    SELECT 'FOO'


    Well, there goes your table.

    Note that this particular syntax won't actually work with PHP and MySQL, because the mysql_query() function allows just one statement to be processed per request. However, a subquery will still work.

    To prevent SQL injection attacks, do two things:

    Always validate all parameters. For example, if something needs to be a number, make sure that it's a number.

    Always use the mysql_real_escape_string() function on data to escape any quotes or double quotes in your data.


    --------------------------------------------------------------------------------
    Note: To automatically escape any form data, you can turn on Magic Quotes.
    --------------------------------------------------------------------------------

    Some MySQL damage can be avoided by restricting your MySQL user privileges. Any MySQL account can be restricted to only do certain kinds of queries on selected tables. For example, you could create a MySQL user who can select rows but nothing else. However, this is not terribly useful for dynamic data, and, furthermore, if you have sensitive customer information, it might be possible for someone to have access to some data that you didn't intend to make available. For example, a user accessing account data could try to inject some code that accesses another account number instead of the one assigned to the current session.
    Last edited by firemax; 04.03.10, 07:56.

    Free Mobile Web Scripts by me: Free Youtube Downloader, Tweets Reader, Facebook Wall Posts Reader
    PHP Tutorials: How to Secure Your PHP Script (PHP SECURITY)
    Want to Develop/Edit your WAP/Web Site? Add me to Gtalk (gmail) 'lakshan1989' or PM me.

    Comment


      #3
      Preventing Basic XSS Attacks

      XSS stands for cross-site scripting. Unlike most attacks, this exploit works on the client side. The most basic form of XSS is to put some JavaScript in user-submitted content to steal the data in a user's cookie. Since most sites use cookies and sessions to identify visitors, the stolen data can then be used to impersonate that user—which is deeply troublesome when it's a typical user account, and downright disastrous if it's the administrative account. If you don't use cookies or session IDs on your site, your users aren't vulnerable, but you should still be aware of how this attack works.

      Unlike MySQL injection attacks, XSS attacks are difficult to prevent. Yahoo!, eBay, Apple, and Microsoft have all been affected by XSS. Although the attack doesn't involve PHP, you can use PHP to strip user data in order to prevent attacks. To stop an XSS attack, you have to restrict and filter the data a user submits to your site. It is for this precise reason that most online bulletin boards don't allow the use of HTML tags in posts and instead replace them with custom tag formats such as [b] and [linkto].

      Let's look at a simple script that illustrates how to prevent some of these attacks. For a more complete solution, use SafeHTML, discussed later in this chapter.

      function transform_HTML($string, $length = null) {
      // Helps prevent XSS attacks

      // Remove dead space.
      $string = trim($string);

      // Prevent potential Unicode codec problems.
      $string = utf8_decode($string);

      // HTMLize HTML-specific characters.
      $string = htmlentities($string, ENT_NOQUOTES);
      $string = str_replace("#", "#", $string);
      $string = str_replace("%", "%", $string);

      $length = intval($length);
      if ($length > 0) {
      $string = substr($string, 0, $length);
      }
      return $string;
      }


      This function transforms HTML-specific characters into HTML literals. A browser renders any HTML run through this script as text with no markup. For example, consider this HTML string:

      <STRONG>Bold Text</STRONG>


      Normally, this HTML would render as follows:

      Bold Text


      However, when run through transform_HTML(), it renders as the original input. The reason is that the tag characters are HTML entities in the processed string. The resulting string from HTML() in plaintext looks like this:

      &lt;STRONG&gt;Bold Text&lt;/STRONG&gt;


      The essential piece of this function is the htmlentities() function call that transforms <, >, and & into their entity equivalents of &lt;, &gt;, and &amp;. Although this takes care of the most common attacks, experienced XSS hackers have another sneaky trick up their sleeve: Encoding their malicious scripts in hexadecimal or UTF-8 instead of normal ASCII text, hoping to circumvent your filters. They can send the code along as a GET variable in the URL, saying, "Hey, this is hexadecimal code, but could you run it for me anyway?" A hexadecimal example looks something like this:

      <a href="http://host/a.php?variable=%22%3e %3c%53%43%52%49%50%54%3e%44
      %6f%73%6f%6d%65%74%68%69%6e%67%6d%61%6c%69%63%69%6 f%75%73%3c%2f%53%43%52
      %49%50%54%3e">


      But when the browser renders that information, it turns out to be:

      Code View:
      <a href="http://host/a.php?variable="> <SCRIPT>Dosomethingmalicious</SCRIPT>

      To prevent this, transform_HTML() takes the additional steps of converting # and % signs into their entity, shutting down hex attacks, and converting UTF-8–encoded data.

      Finally, just in case someone tries to overload a string with a very long input, hoping to crash something, you can add an optional $length parameter to trim the string to the maximum length you specify.
      Last edited by firemax; 04.03.10, 07:58.

      Free Mobile Web Scripts by me: Free Youtube Downloader, Tweets Reader, Facebook Wall Posts Reader
      PHP Tutorials: How to Secure Your PHP Script (PHP SECURITY)
      Want to Develop/Edit your WAP/Web Site? Add me to Gtalk (gmail) 'lakshan1989' or PM me.

      Comment


        #4
        Using SafeHTML

        The problem with the previous script is that it is simple, and it does not allow for any kind of user markup. Unfortunately, there are hundreds of ways to try to sneak JavaScript past someone's filters, and short of stripping all HTML from someone's input, there's no way of stopping it.

        Currently, there's no single script that's guaranteed to be unbreakable, though there are some that are better than most.

        One whitelisting solution is the SafeHTML anti-XSS parser from PixelApes.

        SafeHTML is smart enough to recognize valid HTML, so it can hunt and strip any dangerous tags. It does its parsing with another package called HTMLSax.

        To install and use SafeHTML, do the following:

        Go to http://pixel-apes.com/safehtml/?page=safehtml and download the latest version of SafeHTML.

        Put the files in the classes directory on your server. This directory contains everything that SafeHTML and HTMLSax need to function.

        Include the SafeHTML class file (safehtml.php) in your script.

        Create a new SafeHTML object called $safehtml.

        Sanitize your data with the $safehtml->parse() method.

        Here's a complete example:

        Code View:
        PHP Code:
        <?php
        /* If you're storing the HTMLSax3.php in the /classes directory, along
           with the safehtml.php script, define XML_HTMLSAX3 as a null string. */
        define(XML_HTMLSAX3'');
        // Include the class file.
        require_once('classes/safehtml.php');
        // Define some sample bad code.
        $data "This data would raise an alert <script>alert('XSS Attack')</script>";
        // Create a safehtml object.
        $safehtml = new safehtml();
        // Parse and sanitize the data.
        $safe_data $safehtml->parse($data);
        // Display result.
        echo 'The sanitized data is <br />' $safe_data;
        ?>
        If you want to sanitize any other data in your script, you don't have to create a new object; just use the $safehtml->parse() method throughout your script.

        What Can Go Wrong?
        The biggest mistake you can make is assuming that this class completely shuts down XSS attacks. SafeHTML is a fairly complex script that checks for almost everything, but nothing is guaranteed. You still want to do the parameter validation that applies to your site. For example, this class doesn't check the length of a given variable to ensure that it fits into a database field. It doesn't check for buffer overflow problems.

        XSS hackers are creative and use a variety of approaches to try to accomplish their objectives. Just look at RSnake's XSS tutorial at XSS (Cross Site Scripting) Cheat Sheet to see how many ways there are to try to sneak code past someone's filters. The SafeHTML project has good programmers working overtime to try to stop XSS attacks, and it has a solid approach, but there's no guarantee that someone won't come up with some weird and fresh approach that could short-circuit its filters.


        --------------------------------------------------------------------------------
        Note: For an example of the powerful effects of XSS attacks, check out MySpace Worm Explanation, which shows a step-by-step approach to creating the JavaScript XSS worm that overloaded the MySpace servers.
        Last edited by firemax; 04.03.10, 07:59.

        Free Mobile Web Scripts by me: Free Youtube Downloader, Tweets Reader, Facebook Wall Posts Reader
        PHP Tutorials: How to Secure Your PHP Script (PHP SECURITY)
        Want to Develop/Edit your WAP/Web Site? Add me to Gtalk (gmail) 'lakshan1989' or PM me.

        Comment


          #5
          Protecting Data with a One-Way Hash

          This script performs a one-way transformation on data—in other words, it can make a hash signature of someone's password, but you can't ever decrypt it and go back to the original password. Why would you want to do that? The application is in storing passwords. An administrator doesn't need to know users' passwords—in fact, it's a good idea that only the user knows his or her password. The system (and the system alone) should be able to identify a correct password; this has been the Unix password security model for years. One-way password security works as follows:

          When a user or administrator creates or changes an account password, the system hashes the password and stores the result. The host system discards the plaintext password.

          When the user logs in to a system via any means, the entered password is again hashed.

          The host system throws away the plaintext password entered.

          This newly hashed password is compared against the stored hash.

          If the hashed passwords match, then the system grants access.

          The host system does this without ever knowing the original password; in fact, the original value is completely irrelevant. As a side effect, should someone break into your system and steal your password database, the intruder will have a bunch of hashed passwords without any way of reversing them to find the originals. Of course, given enough time, computer power, and poorly chosen user passwords, an attacker could probably use a dictionary attack to figure out the passwords. Therefore, don't make it easy for people to get their hands on your password database, and if someone does, have everyone change their passwords.

          ENCRYPTION VS. HASHING
          Technically speaking, this process is not encryption. It is a hash, which is different from encryption for two reasons:

          Unlike in encryption, data cannot be decrypted.

          It's possible (but extremely unlikely) that two different strings will produce the same hash. There's no guarantee that a hash is unique, so don't try to use a hash as something like a unique key in a database.

          function hash_ish($string) {
          return md5($string);
          }


          The md5() function returns a 32-character hexadecimal string, based on the RSA Data Security Inc. Message-Digest Algorithm (also known, conveniently enough, as MD5). You can then insert that 32-character string into your database, compare it against other md5'd strings, or just adore its 32-character perfection.


          Hacking the Script
          It is virtually impossible to decrypt MD5 data. That is, it's very hard. However, you still need good passwords, because it's still easy to make a database of hashes for the entire dictionary. There are online MD5 dictionaries where you can enter 06d80eb0c50b49a509b49f2424e8c805 and get a result of "dog." Thus, even though MD5s can't technically be decrypted, they're still vulnerable—and if someone gets your password database, you can be sure that they'll be consulting an MD5 dictionary. Thus, it's in your best interests when creating password-based systems that the passwords are long (a minimum of six characters and preferably eight) and contain both letters and numbers. And make sure that the password isn't in the dictionary.
          Last edited by firemax; 04.03.10, 08:01.

          Free Mobile Web Scripts by me: Free Youtube Downloader, Tweets Reader, Facebook Wall Posts Reader
          PHP Tutorials: How to Secure Your PHP Script (PHP SECURITY)
          Want to Develop/Edit your WAP/Web Site? Add me to Gtalk (gmail) 'lakshan1989' or PM me.

          Comment


            #6
            Encrypting Data with Mcrypt

            MD5 hashes work just fine if you never need to see your data in readable form. Unfortunately, that's not always an option—if you offer to store someone's credit card information in encrypted format, you need to decrypt it at some later point.

            One of the easiest solutions is the Mcrypt module, an add-in for PHP that allows high-grade encryption. The Mcrypt library offers more than 30 ciphers to use in encryption and the possibility of a passphrase that ensures that only you (or, optionally, your users) can decrypt data.

            Let's see some hands-on use. The following script contains functions that use Mcrypt to encrypt and decrypt data:

            Code View:
            PHP Code:
            <?php

            $data 
            "Stuff you want encrypted";
            $key "Secret passphrase used to encrypt your data";
            $cipher "MCRYPT_SERPENT_256";
            $mode "MCRYPT_MODE_CBC";

            function 
            encrypt($data$key$cipher$mode) {
            // Encrypt data

            return (string)
                        
            base64_encode
                            
            (
                            
            mcrypt_encrypt
                                
            (
                                
            $cipher,
                                
            substr(md5($key),0,mcrypt_get_key_size($cipher$mode)),
                                
            $data,
                                
            $mode,
                                
            substr(md5($key),0,mcrypt_get_block_size($cipher$mode))
                                )
                            );
            }

            function 
            decrypt($data$key$cipher$mode) {
            // Decrypt data
                
            return (string)
                        
            mcrypt_decrypt
                            
            (
                            
            $cipher,
                            
            substr(md5($key),0,mcrypt_get_key_size($cipher$mode)),
                            
            base64_decode($data),
                            
            $mode,
                            
            substr(md5($key),0,mcrypt_get_block_size($cipher$mode))
                            );
            }

            ?>

            The mcrypt() function requires several pieces of information:

            The data to encrypted.

            The passphrase used to encrypt and unlock your data, also known as the key.

            The cipher used to encrypt the data, which is the specific algorithm used to encrypt the data. This script uses MCRYPT_SERPENT_256, but you can choose from an array of fancy-sounding ciphers, including MCRYPT_TWOFISH192, MCRYPT_RC2, MCRYPT_DES, and MCRYPT_LOKI97.


            --------------------------------------------------------------------------------
            Note: To find out which ciphers are available on your server, check out on the phpinfo() page. If Mcrypt is available, you will see two sections: "Supported Cipher" and "Supported Modes." Use them, exactly as written, to encrypt your data.
            --------------------------------------------------------------------------------

            The mode used to encrypt the data. There are several modes you can use, including Electronic Codebook and Cipher Feedback. This script uses MCRYPT_MODE_CBC, Cipher Block Chaining.

            An initialization vector—also known as an IV, or a seed—an additional bit of binary data used to seed the encryption algorithm. That is, it's something extra thrown in to make the algorithm harder to crack.

            The length of the string needed for the key and IV, which vary by cipher and block. Use the mcrypt_get_key_size() and mcrypt_get_block_size() functions to find the appropriate length; then trim the key value to the appropriate length with a handy substr() function. (If the key is shorter than the required value, don't worry—Mcrypt pads it with zeros.)

            If someone steals both your data and your passphrase, they can just cycle through the ciphers until finding the one that works. Thus, we apply the additional security of using the md5() function on the key before we use it, so even having both data and passphrase won't get the intruder what she wants.

            An intruder would need the function, the data, and the passphrase all at once—and if that is the case, they probably have complete access to your server, and you're hosed anyway.

            There's a small data storage format problem here. Mcrypt returns its encrypted data in an ugly binary format that causes horrific errors when you try to store it in certain MySQL fields. Therefore, we use the base64encode() and base64decode() functions to transform the data into a SQL-compatible alphabetical format and retrieve rows.

            Hacking the Script
            In addition to experimenting with various encryption methods, you can add some convenience to this script. For example, rather than providing the key and mode every time, you could declare them as global constants in an included file.

            Free Mobile Web Scripts by me: Free Youtube Downloader, Tweets Reader, Facebook Wall Posts Reader
            PHP Tutorials: How to Secure Your PHP Script (PHP SECURITY)
            Want to Develop/Edit your WAP/Web Site? Add me to Gtalk (gmail) 'lakshan1989' or PM me.

            Comment


              #7
              i believe this thread deserves to be sticky
              It's better to keep your mouth shut and give the impression that you're stupid, than to open it and remove all doubt.
              ⓣⓗⓔ ⓠⓤⓘⓔⓣⓔⓡ ⓨⓞⓤ ⓑⓔ©ⓞⓜⓔ, ⓣⓗⓔ ⓜⓞⓡⓔ ⓨⓞⓤ ⓐⓡⓔ ⓐⓑⓛⓔ ⓣⓞ ⓗⓔⓐⓡ !
              ιη тнєσяу, тнє ρяα¢тι¢є ιѕ α яєѕυℓт σƒ тнє тнєσяу, вυт ιη ρяα¢тι¢є ιѕ тнє σρρσѕιтє.
              キノgんイノ刀g 4 ア乇ムc乇 ノ丂 レノズ乇 キucズノ刀g 4 √ノ尺gノ刀ノイリ!

              Comment


                #8
                PHP File Upload Security &amp; Risks

                Why File Upload Forms are a major security threat

                To allow an end user to upload files to your website, is like opening another door for a malicious user to compromise your server. Even though, in today’s modern internet web applications, it is a common requirement, because it helps in increasing your business efficiency. File uploads are allowed in social network web applications, such as Facebook and Twitter. They are also allowed in blogs, forums, e-banking sites, YouTube and also in corporate support portals, to give the opportunity to the end user to efficiently share files with corporate employees. Users are allowed to upload images, videos, avatars and many other types of files.

                The more functionality provided to the end user, the greater is the risk of having a vulnerable web application and the chance that such functionality will be abused from malicious users, to gain access to a specific website, or to compromise a server is very high.

                While testing several web applications, we noticed that a good number of well known web applications, do not have secure file upload forms. Some of these vulnerabilities were easily exploited, and we could gain access to the file system of the server hosting these web applications. In this whitepaper, we present you with 8 common ways we encountered of securing file upload forms. We also show how a malicious user, can easily bypass such security measures.

                Case 1: Simple file upload form with no validation
                A simple file upload form usually consists of a HTML form and a PHP script. The HTML form, is the form presented to the user, while the PHP script contains the code that takes care of the file upload. Below is an example of such form and PHP script:
                HTML Form:
                PHP Code:
                <form enctype="multipart/form-data" action="uploader.php" method="POST">
                <
                input type="hidden" name="MAX_FILE_SIZE" value="100000" />
                Choose a file to upload: <input name="uploadedfile" type="file" /><br />
                <
                input type="submit" value="Upload File" /> 
                PHP Code:
                PHP Code:
                <?php     
                $target_path 
                "uploads/";
                $target_path $target_path basename$_FILES['uploadedfile']['name']); 
                if(
                move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) { 
                    echo 
                "The file ".  basename$_FILES['uploadedfile']['name']).  
                    
                " has been uploaded"
                } else{
                    echo 
                "There was an error uploading the file, please try again!"
                }
                 
                ?>
                When PHP receives a POST request with encoding type multipart/form-data, it will create a temporary file with a random name in a temp directory (e.g. /var/tmp/php6yXOVs). PhP will also populate the global array $_FILES with the information about the uploaded file:
                • $_FILES[‘uploadedfile’][‘name’]: The original name of the file on the client machine
                • $_FILES[‘uploadedfile’][‘type’]: The mime type of the file
                • $_FILES[‘uploadedfile’][‘size’]: The size of the file in bytes
                • $_FILES[‘uploadedfile’][‘tmp_name’]: The temporary filename in which the uploaded file was stored on the server.

                The PHP function move_uploaded_file will move the temporary file to a location provided by the user. In this case, the destination is below the server root. Therefore the files can be accessed using a URL like: http://www.domain.tld/uploads/uploadedfile.ext. In this simple example, there are no restrictions about the type of files allowed for upload and therefore an attacker can upload a PHP or .NET file with malicious code that can lead to a server compromise.
                This might look like a naïve example, but we did encounter such code in a number of web applications.


                Case 2: Mime Type validation
                Another common mistake web developers do when securing file upload forms, is to only check for mime type returned from PHP. When a file is uploaded to the server, PHP will set the variable $_FILES[‘uploadedfile’][‘type’] to the mime-type provided by the web browser the client is using. However, a file upload form validation cannot depend on this value only. A malicious user can easily upload files using a script or some other automated application that allows sending of HTTP POST requests, which allow him to send a fake mime-type.


                Case 3: Block dangerous extensions
                In other cases, we encountered file upload forms using a blacklist approach, as a security measure. A list of dangerous extensions is compiled from the developer, and the access is denied if the extension of the file being uploaded is on the compiled list.
                One main disadvantage of using black listing of file extensions, is that it is almost impossible to compile a list that includes all possible extensions that an attacker can use. E.g. If the code is running in a hosted environment, usually such environments allow a large number of scripting languages, such as Perl, Python, Ruby etc, and the list can be endless.
                A malicious user can easily bypass such check by uploading a file called “.htaccess”, which contains a line of code similar to the below:
                AddType application/x-httpd-php .jpg
                The above line of code, instructs Apache web server to execute jpg images as if they were PHP scripts. The attacker can now upload a file with a jpg extension, which contains PHP code. As seen in the screen shot below, requesting a jpg file which includes the PHP command phpinfo() from a web browser, it is still executed from the web server:



                Case 4: Double extensions (part 1)
                This case’s security measures, as a concept are very similar to that one used in case 3. Though instead of simply checking the extension string present in the filename, the developer is extracting the file extension by looking for the ‘.’ character in the filename, and extracting the string after the dot character.
                The method used to bypass this approach is a bit more complicated, but still realistic. First, let’s have a look at how Apache handles files with multiple extensions. A quote from the Apache manual states:
                “Files can have more than one extension, and the order of the extensions is normally irrelevant. For example, if the file welcome.html.fr maps onto content type text/html and language French then the file welcome.fr.html will map onto exactly the same information. If more than one extension is given which maps onto the same type of meta-information, then the one to the right will be used, except for languages and content encodings. For example, if .gif maps to the MIME-type image/gif and .html maps to the MIME-type text/html, then the file welcome.gif.html will be associated with the MIME-type text/html.”
                Therefore a file named ‘filename.php.123’, will be interpreted as a PHP file and will be executed. This only works if the last extension (in our case .123), is not specified in the list of mime-types known to the web server. Web developers, usually are not aware of such ‘feature’ in Apache, which can be very dangerous for a number of reasons. Knowing this, an attacker can upload a file named shell.php.123 and bypass the file upload form protection. The script will compute the last extension (.123), and concludes that this extension is not in the list of dangerous extension. Having said that, it is impossible to predict all the possible random extensions a malicious user will use to be able to upload a file on your web server.

                Case 5: Double extensions (part 2)
                A better approach to securing file upload forms is the white list approach. In this case, the developer defines a list of known/accepted extensions and does not allow extensions that are not specified in the list.
                However, in some cases this approach will not work as expected. When Apache is configured to execute PHP code, there are 2 ways one can specify this: to use the AddHandler directive, or to use the AddType directive. If AddHandler directive is used, all filenames containing the ‘.php’ extension (e.g. ‘.php’, ‘.php.jpg’) will be executed as a PHP script. Therefore, if your Apache configuration file contains the following line, you may be vulnerable:
                AddHandler php5-script .php
                An attacker can upload a file named ‘filename.php.jpg’ and bypass the protection, and will be able to execute the code.

                Case 6: Checking the image header
                When images only are allowed to be uploaded, developers usually validate the image header by using the PHP function called getimagesize. When called, this function will return the size of an image. If the image validation is invalid, which means that the header is incorrect, the function will return a false. Therefore a developer typically checks if the function returns a true or false, and validate the uploaded file using this information. So, if a malicious user tries to upload a simple PHP shell embedded in a jpg file, the function will return false and he won’t be allowed to upload the file. However, even this approach can be easily bypassed. If a picture is opened in an image editor, like Gimp, one can edit the image comment, where PHP code is inserted, as shown below.



                The image will still have a valid header; therefore it bypasses the getimagesize PHP check. As seen in the screen shot below, the PHP code inserted in the image comments still gets executed when the image is requested from a normal web browser:





                Case 7: Protecting the upload folder with .htaccess
                Another popular way of securing file upload forms, is to protect the folder where the files are uploaded using .htaccess file. The idea is to restrict execution of script files in this folder. A .htaccess file typically contains the below code when used in this kind of scenario:
                AddHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi
                Options –ExecCGI
                The above is another type of blacklist approach, which in itself is not very secure. In the PHP manual, in the move_uploaded_file section, there is a warning which states ‘If the destination file already exists, it will be overwritten.
                Because uploaded files can and will overwrite the existing ones, a malicious user can easily replace the .htaccess file with his own modified version. This will allows him to execute specific scripts which can help him compromise the server.

                Case 8: Client-side validation
                Another common type of security used in file upload forms, is client-side validation of files to be uploaded. Typically, such approach is more common in ASP.NET applications, since ASP.NET offers easy to use validation controls.
                These types of validation controls, allow a developer to do regular-expression checks upon the file that is being uploaded, to check that the extension of the file being uploaded is specified in the list of allowed extensions. Below is a sample code, taken from the Microsoft’s website:
                PHP Code:
                [LEFT]
                [/
                LEFT]
                <
                asp:FileUpload ID="FileUpload1" runat="server" /><br /> 
                 <
                br />
                 <
                asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Upload File" />&nbsp;<br />
                 <
                br />
                 <
                asp:Label ID="Label1" runat="server"></asp:Label>
                 <
                asp:RegularExpressionValidator id="RegularExpressionValidator1" runat="server"
                 
                ErrorMessage="Only mp3, m3u or mpeg files are allowed!"
                 
                ValidationExpression="^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w].*))
                 +(.mp3|.MP3|.mpeg|.MPEG|.m3u|.M3U)$" 
                ControlToValidate="FileUpload1"></asp:RegularExpressionValidator>
                 <
                br />
                 <
                asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server"
                 
                ErrorMessage="This is a required field!"
                 
                ControlToValidate="FileUpload1"></asp:RequiredFieldValidator
                This ASP.NET code uses validation controls, so the end user is only allowed to upload .mp3, .mpeg or .m3u files to the web server. If the file type does not match any of the 3 specified extensions, the validation control throws an exception and the file won’t be uploaded.
                Because this type of validation is done on the client side, a malicious user can easily bypass this type of validation. It is possible to write a short client side script that will do the validation instead of the script provided by the web application. Without using a web browser, the attacker can use an application that allows sending of HTTP POST requests to be able to upload the file.

                Suggested Solution
                Below is a list of best practices that should be enforced when file uploads are allowed on websites and web applications. These practices will help you securing file upload forms used in web applications;
                • Define a .htaccess file that will only allow access to files with allowed extensions.
                • Do not place the .htaccess file in the same directory where the uploaded files will be stored. It should be placed in the parent directory.
                • A typical .htaccess which allows only gif, jpg, jpeg and png files should include the following (adapt it for your own need). This will also prevent double extension attacks.


                PHP Code:
                deny from all
                 
                <Files "^\w+\.(gif|jpe?g|png)$">
                 
                order deny,allow
                 allow from all
                 
                </Files
                • If possible, upload the files in a directory outside the server root.
                • Prevent overwriting of existing files (to prevent the .htaccess overwrite attack).
                • Create a list of accepted mime-types (map extensions from these mime types).
                • Generate a random file name and add the previously generated extension.
                • Don’t rely on client-side validation only, since it is not enough. Ideally one should have both server-side and client-side validation implemented.

                Conclusion
                As seen above, there are many ways how a malicious user can bypass file upload form security. For this reason, when implementing a file upload form in a web application, one should make sure to follow correct security guidelines and test them properly. Unfortunately, to perform the number of tests required, can take a lot of time and require a good amount of web security expertise.
                Though with Acunetix WVS, one can automatically perform file upload forms vulnerability tests without the need of web security expertise. Acunetix WVS provides the developer with extensive amount of information to be able to trace and fix the problem in the least possible time.

                More This Articale : Why File Upload Forms are a major security threat

                Summmary of mysql-apache-php.com's article


                1. Assign 775 permission to upload folder
                2. Check the file using PHP functions (if its photo upload)

                for the codes and details: PHP File Upload Security

                3. Disable Script Execution an Hide Indexes with .htaccess
                PHP Code:
                Options -Indexes
                Options 
                -ExecCGI
                AddHandler cgi
                -script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi 
                PHP Code:
                <Files ^(*.jpeg|*.jpg|*.png|*.gif)>
                order deny,allow
                deny from all
                </Files
                4. Place the upload folder outside WWW root.
                ex:
                PHP Code:
                ./uploads

                <img src="./uploads/photo.gif> 
                Read All @ : PHP File Upload Security

                Other Most Imported Articles :
                PHP Upload Security & The 1×1 jpeg Hack

                Extarnal:

                use this attachment to hide files path in your file download site.also you can use this with your autoindex program.
                Attached Files
                Last edited by firemax; 05.03.10, 11:49.

                Free Mobile Web Scripts by me: Free Youtube Downloader, Tweets Reader, Facebook Wall Posts Reader
                PHP Tutorials: How to Secure Your PHP Script (PHP SECURITY)
                Want to Develop/Edit your WAP/Web Site? Add me to Gtalk (gmail) 'lakshan1989' or PM me.

                Comment


                  #9
                  How to find PHP Shell on your server

                  In most of the hacking or defacing the most common tool used is PHP Shell. If you scan your server regularly for php shell and delete them you can avoid many hacking and defacing attempt on your server.

                  PHP Code:
                  #!/bin/bash
                  #Scanning all users directory for various php shell
                  # Below command is one line so see that its one line in your script or else it will generate error

                  echo "No PHP Shell was Found" > /root/scan.txt
                  /bin/egrep "cgitelnet|webadmin|PHPShell|tryag|r57shell|c99she ll|noexecshell|/etc/passwd|revengans|myshellexec" /home/*/public_html -R | cut -d: -f1 | uniq > /root/scan.txt

                  /bin/cat /root/scan.txt | mail -s "PHP Shell Scan" user@domain.com

                  #Replace your email address above

                  #Cron Settings
                  # 0 6 * * * PATH TO SCRIPT 
                  The above script is a very simple shell script which will scan all public_html directories of all cpanel accounts for various php shell. Then the script will mail you the locations of PHP Shell. You can set cron for this script to run once a day. If you check the code I have added a cron for it which you can use which will execute the script on 6th hour daily.

                  PHP Functions which help hackers to hack your server


                  I am listing below some PHP Functions which you should keep disabled if you dont need them as they help hackers to deface your websites or hack the server:

                  PHP Code:
                  dl
                  exec
                  shell_exec
                  system
                  passthru
                  popen
                  pclose
                  proc_open
                  proc_nice
                  proc_terminate
                  proc_get_status
                  proc_close
                  leak
                  apache_child_terminate
                  posix_kill
                  posix_mkfifo
                  posix_setpgid
                  posix_setsid
                  posix_setuid
                  escapeshellcmd
                  escapeshellarg
                  shell
                  -exec
                  fpassthru
                  crack_check
                  crack_closedict
                  crack_getlastmessage
                  crack_opendict
                  psockopen
                  php_uname
                  symlink
                  mkdir
                  ini_restore
                  posix_getpwuid
                  error_log
                  print_r
                  scandir
                  copy
                  phpinfo
                  ini_set 
                  To disable these functions you can add following line to /usr/local/lib/php.ini

                  PHP Code:
                  disable_functions "dl,exec,shell_exec,system,passthru,popen,pclose,p roc_open,proc_nice,proc_terminate,proc_get_status, proc_close,leak,
                  apache_child_terminate,posix_kill,posix_mkfifo,pos ix_setpgid,posix_setsid,posix_setuid,escapeshellcm d,escapeshellarg,shell-exec,fpassthru,crack_check,crack_closedict,crack_g etlastmessage,crack_opendict,psockopen,php_uname,s ymlink,mkdir
                  ,ini_restore,posix_getpwuid,error_log,print_r,scan dir,copy,phpinfo,ini_set" 
                  Then restart the apache server that is httpd service.

                  Please note: Doing this will break some of the php scripts on your clients. I would suggest you to block above functions first and then when you come to know which php scripts are breaking by this, at that time you can remove that particular function needed by the script. This way your disable function list will be perfect as required by your server

                  Hope this helps you all.

                  Free Mobile Web Scripts by me: Free Youtube Downloader, Tweets Reader, Facebook Wall Posts Reader
                  PHP Tutorials: How to Secure Your PHP Script (PHP SECURITY)
                  Want to Develop/Edit your WAP/Web Site? Add me to Gtalk (gmail) 'lakshan1989' or PM me.

                  Comment


                    #10
                    Well, guys, thank you all. I suggest you this tutorial:
                    Attached Files
                    mysterio.al - programming is a functional art

                    Comment


                      #11
                      great post friendz. tnx

                      Comment


                        #12
                        very helpful article double thanks to the firemax.

                        Comment


                          #13
                          Hey PHP developers! We’re a team of passionate PHP users, and we’ve launched a free PHP vulnerability scanner. It detects SQL injections, XSS, command injections, and more.

                          We’re in beta, and it would be extremely helpful to get feedback from a more professional audience. Please check it here - https://phpsecure.net/land

                          We’re looking for any tips, wishes, or constructive criticism you could offer. Thank you!

                          ---
                          Julia, CEO on PHP Secure​

                          Comment

                          Working...
                          X