Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 22, 2021 09:25 am GMT

Never trust an upload's filename

It's generally accepted that we should never simply trust a user's input. Otherwise, we're vulnerable to malicious input (CE-5). For a file upload from a user, its common to check their file size or type, especially when restricting them by those two attributes. But one that might get overlooked is the filename.

Checking the filename is especially important when it displayed on a web page to prevent HTML or XSS injection. Thats just on the frontend. On the backend, there are the other usual injections to worry about. Like SQL injection, when storing the name in a database. Or path injection, if storing in a path based on the name.

It might be tempting to dismiss this possibility as something that would never happen. After all, we must make the files first before we can upload them and there are file-naming rules. We can't simply make one with just any name they want! However, the rules wont prevent malicious filenames!

OS file naming rules won't prevent injection

Operating systems have rules about what can be in a filename. But, different operating systems can have different rules. So, a filename prohibited in one operating system may be allowed in another.

For example, <img onerror="alert('XSS')" src="nowhere">.txt. The file can't be created in Windows because it doesn't allow < and > (see Naming a file). However, Linux does allow them. For example, we could use touch to create the file:

touch '<img onerror="alert('"'XSS'"')" src="nowhere">.txt'

Actually, we don't even need to make the files

HTTP clients usually send file uploads using a multi-part POST request. We can use Wireshark to see what the request looks like. Here's one from cURL:

POST /attachments HTTP/1.1Host: 127.0.0.1:3000User-Agent: curl/7.76.1Accept: */*Content-Length: 250Content-Type: multipart/form-data; boundary=------------------------6c44be865e1d13e6-------------------------------6c44be865e1d13e6Content-Disposition: form-data; name="attachment"; filename="Lorem_Ipsum.txt"Content-Type: text/plainLorem ipsum dolor sit amet, consectetur cras amet. -------------------------------6c44be865e1d13e6--

Notice the filename field is at the end of the Content-Disposition header. We can use this as a template to make our own requests. Simply. copy and paste into a file, change the filename and update the Content-Length. Then use Ncat to send the request. For example, to send the request in request.http to http://localhost:3000:

ncat localhost 3000 < request.http

Using HTTPS isn't enough either

The example above sent a forged request to an insecure server (i.e one that isn't using SSL/TLS). But changing over to HTTPS still won't be enough to prevent malicious filenames - Ncat also works with HTTPS connections:

 ncat -C --ssl localhost 3000 < request.http

Even if it didn't, it we could go back to using a web browser to upload files over HTTPS.

Pentesting tools makes this easier

Using Wireshark and Ncat was how I first learnt to do this. It turns out pentesting tools like mitmproxy make this easier - it can intercept and modify the requests in-flight.

MITM Proxy intercepting requests

Burp Suite's proxy has similar features.

BurpSuite intercepting requests

Prevent injection via filenames

There is just no way to guarantee a server never receiving an upload with a bad filename. The server must guard against it - usually by sanitising or encoding and escaping where it is used (OWASP CE-4). Doing so will help to prevent injection attacks via filenames.


Original Link: https://dev.to/kahdev/never-trust-an-upload-s-filename-3fhj

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To