Basic Programming: File Uploads using Python-Requests

So uploading files is something I figured I should cover first, before discussing the “streaming files” stuff later.

In the requests library, there is a pretty simple way to manage uploading files. I’ll cover some examples here, which are probably the ways I end up doing it most often.

In all of these examples, we will assume we are talking to an endpoint that accepts fileupload with the variable “upload”, like a PHP script using the following: $_FILES["upload"]. We will also assume the upload is happening using a HTTP POST request for this article.

Firstly, lets take an example of uploading a file named “file.txt” from disc, and just sending it as-is. No sending extra headers, no renaming the file, just uploading that file.

#!/usr/bin/env python
import requests

url = "http://localhost:9000/lol.php"
files = {'upload': open('file.txt', 'rb')}
r = requests.post(url=url, files=files)

Now, say we want to upload the same file, but tell the server it has a different name, in this case, “new.txt”. This is simple, we just put the name in there – the object passed in the dict can be a tuple containing a bunch of values.

#!/usr/bin/env python
import requests

url = "http://localhost:9000/lol.php"
files = {'upload': ('new.txt', open('file.txt', 'rb'))}
r = requests.post(url=url, files=files)

In our third example, we will be uploading the same file (file.txt), but setting our own MIME Type. This can be very useful in bypassing checks in upload scripts that blacklist based on the MIME type sent.

#!/usr/bin/env python
import requests

url = "http://localhost:9000/lol.php"
files = {'upload': (open('file.txt','rb'), 'text/plain')}
r = requests.post(url=url, files=files)

In our next example, we will be uploading a file again, but this time both renaming it, and setting a custom MIME type.

#!/usr/bin/env python
import requests

url = "http://localhost:9000/lol.php"
files = {'upload': ('new.txt', open('file.txt','rb'), 'text/plain')}
r = requests.post(url=url, files=files)

Now, in our final example, instead of reading a file from the disc, we will be uploading a file where the contents being sent are a string. This could be something we dynamically have generated on the fly (eg: a PHP backdoor). We will be both providing a name – and the MIME type.

#!/usr/bin/env python
import requests

url = "http://localhost:9000/lol.php"
string_to_upload = "hello world!"
files = {'upload': ('new.txt', string_to_upload, 'text/plain')}
r = requests.post(url=url, files=files)

Hopefully these examples, while not exhaustive, will provide you with the basis to understand how to do file uploads using the POST method. You should note – you can easily add other POST parameters using the data argument, or GET parameters using the params argument to the request, as shown in earlier episodes.

We will be referring back to this article later in case studies of simple file upload holes in web applications.

%d bloggers like this: