Computer Security :: Lessons :: Upload Vectors
Upload Vector Attacks
An upload vector is an area of a web app that allows uploads. Upload vectors can be vulnerable to attack if individuals are able to upload any file type. In 2014, security researcher Oren Hafif presented this example of a reflected file download that is a type of upload vector attack. You can also read an article by Open Source Hacker about different types of upload vector attacks.
Ideally, user-uploaded files should be stored on a different server from your website. This isn't possible for web apps created in Advanced Studies classes, however, because you only have access to the YHSCS server. In cases where only one server is available you should create a proxy script to only allow read-only access to user-uploaded files. The script below from the Paragon Initiative is an example that you can use.
<?php /** * This is an example of an image proxy script. It assumes an .htaccess or nginx rewrite e.g. * files/.* -> /proxy_script.php?path=$1 */ if (empty($_GET['path'])) { header('HTTP/1.1 404 Not Found'); exit; } // We're going to iterate over $dirs $dirs = explode('/', $_GET['path']); // We start with $path set to the basepath $path = $_SERVER['DOCUMENT_ROOT']; // For the FileInfo functions: $fi = new finfo(FILEINFO_MIME, '/usr/share/file/magic'); // Bad filenames that should trigger an alert and terminate the script $bad_files = [ '..', '.git', '.htaccess', '.svn' ]; // Let's iterate through directories while (!empty($dirs)) { // PHP has a bad history of handling NUL bytes. Just strip them. $piece = str_replace("\0", '', array_shift($dirs)); if (empty($piece)) { continue; } if (in_array($piece, $bad_files)) { // Blacklist violations header('HTTP/1.1 404 Not Found'); exit; } // A directory traversal attempt that somehow bypasswed the blacklist if (is_dir($path . '/' . $piece)) { $realpath = realpath($path . '/' . $piece); if (strpos($realpath, $path) !== 0) { header('HTTP/1.1 404 Not Found'); exit; } } $path .= '/' . $piece; } // If the file exists and is within document root (i.e. not a successful LFI) $realpath = realpath($path); if (file_exists($realpath) && strpos($realpath, $_SERVER['DOCUMENT_ROOT']) === 0) { $type = finfo_file($fi, $file); header("Content-Type: ".$type); readfile($realpath); exit; } // Are you still here? header('HTTP/1.1 404 Not Found'); ?>