FILE UPLOADS

the methods described here are the exploitation of file upload forms and functionalities

PAYLOADS

#image magic bytes
JPEG/JPG
 * Hexadecimal: FF D8 FF
 * ASCII: ÿØÿ
          ÿØÿà
PNG
 * Hexadecimal: 89 50 4E 47 0D 0A 1A 0A
 * ASCII: .PNG.... 
GIF
 * Hexadecimal
    - 47 49 46 38 39 61 (GIF89a)
    - 47 49 46 38 37 61 (GIF87a)
 * ASCII: GIF8
 
SVG
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="200" height="200">
   <!-- Metadata -->
   <title>HTB SVG Example</title>
   <desc>An example SVG file with a rectangle and a script alert.</desc>

   <!-- Rectangle Element -->
   <rect x="50" y="50" width="100" height="100" fill="green" stroke="black" stroke-width="2"/>

   <!-- Script Element (potential security risk) -->
   <script type="text/javascript">
     alert('Window Origin: ' + window.origin);
   </script>
 </svg>

MITIGATION

EXTENSION VALIDATION

  • use whitelisting to allow specific extension extensions and blacklisting to restrict dangerous extensions. this way, the blacklist list will prevent uploading malicious scripts if the whitelist is ever bypassed. this MUST be applied to both the back-end and front-end file validation.

$fileName = basename($_FILES["uploadFile"]["name"]);

// blacklist test
if (preg_match('/^.+\.ph(p|ps|ar|tml)/', $fileName)) {
    echo "Only images are allowed";
    die();
}

// whitelist test
if (!preg_match('/^.*\.(jpg|jpeg|png|gif)$/', $fileName)) {
    echo "Only images are allowed";
    die();
}

CONTENT VALIDATION

in addition to extension validation, file content MUST also be validated and ensure that the file extension matches the file's content.

$fileName = basename($_FILES["uploadFile"]["name"]);
$contentType = $_FILES['uploadFile']['type'];
$MIMEtype = mime_content_type($_FILES['uploadFile']['tmp_name']);

// whitelist test
if (!preg_match('/^.*\.png$/', $fileName)) {
    echo "Only PNG images are allowed";
    die();
}

// content test
foreach (array($contentType, $MIMEtype) as $type) {
    if (!in_array($type, array('image/png'))) {
        echo "Only PNG images are allowed";
        die();
    }
}

AVOID UPLOAD DISCLOSURE

restrict disclosing the uploads directory or providing direct access to the uploaded file. It is always recommended to hide the uploads directory from the end-users and only allow them to download the uploaded files through a download page. utilize a download.php script that fetches a requested file to be downloaded from the uploads directory. this can significantly reduce the chances of accessing a maliciously uploaded script to execute code. if a download page is utilized, ensure the download.php only grants access to files owned by the users to prevent IDOR/LFI vulnerabilities. this can be achieved by utilizing the Content-Disposition and nosniff headers and using an accurate Contrent-Type header. lastly, implement a filename randomization mechanism for the uploaded files and only store "sanitized" original names in a database. this prevents users from knowing the uploads directory nor the uploaded file name.

CONFIGURATION SECURITY

disable specific functions that may be used to execute system commands through the web application. for instance, use the disable_functions configuration in php.ini. lastly, always handle errors at the web application level and print out simple errors that explain the error without disclosing any sensitive or specific details, like the file name, uploads directory, or the raw errors.

  • Limit file size

  • Update any used libraries

  • Scan uploaded files for malware or malicious strings

  • Utilize a Web Application Firewall (WAF) as a secondary layer of protection

Last updated