2

For example, if a client submits a file to a server, and the server opens the file in read-mode with Python:

with open(uploaded_file, "r") as f:
    # Do something

Could the act of opening a file be abused with a cleverly-crafted file from the client? Does it depend on the language used by the server?

7
  • Possible duplicate of web application extracts uploaded tar files, is it vulnerable?
    – Tom K.
    Commented Feb 11, 2018 at 10:52
  • You used word 'read-mode' which is important in this context. You may think it like an text editor program in your desktop opening .txt file. If you meant something else, please give more details. Commented Feb 11, 2018 at 11:11
  • 4
    Just opening the file for reading does not harm. Of course, if you then try to interpret the data you've read from the file (i.e. the # Do something part) you might introduce security problems but this depends on your actual code. Commented Feb 11, 2018 at 11:31
  • @SteffenUllrich Indeed, and since the file is opened in text mode, the act of simply reading from the file causes Python to interpret the data.
    – Fax
    Commented Mar 18, 2021 at 12:13
  • 1
    @SteffenUllrich Not exactly. Reading from a file in text mode causes Python to decode the text in the file (in this case using the system's preferred encoding). Although somewhat unlikely, the decoder may have a vulnerability.
    – Fax
    Commented Mar 18, 2021 at 12:29

3 Answers 3

4

No.

If the filename is controlled by the user, then you might open yourself up to vulnerabilities (e.g. an attacker might try to read config files with the database password). But just opening a file handle for an uploaded file can't do much.

Perhaps if the underlying mechanism would try to read the whole file for buffering purposes, it might fill up RAM and crash the process, but Python doesn't do that: to read the whole file, you would first have to call f.read() -- but that is just what you do with it, and not opening the file. Only opening the file is harmless.

2

Operating systems generally have a limited number of files they can open at once (specifically, a limited number of file descriptors or fds in Unix-like systems, or HANDLEs in Windows). If you allow people to open an arbitrary number of those without closing them, then it might be possible to deplete that limit, which would prevent the OS from opening more files and probably cause it to misbehave or even crash. It would be hard to exploit it for anything more than denial of service, though. Also, programs may have quotas (lower than the system limit) of how many files they can open, so a single misbehaving program couldn't do too much, and all of a process' files are released when the process exits so normally it's easy enough to restore function (indeed, most programs would crash themselves before long).

Still, if you're letting people tell your server to open a file, it would be a good idea to have a limit on how many can be open at once, and close the file (automatically, if the user doesn't instruct it to happen first) after as short a time as possible.

Another risk could be opening up network connections, depending on what OS you're running on and what path types it accepts. For example, if the system accepts Windows networking style paths (\\server\share\path\to\file) or SMB (the Windows networking protocol, implemented on Unix-likes in the Samba toolkit) paths (smb://server/share/path), or other ways to access any kind of network file system that isn't yet mounted (or "mapped" to use the old Windows term) to the local file system, that could cause your server to open a network connection to an attacker's box and possibly try to authenticate. This might reveal info about the server, and could provide a vector for attackers to try to compromise the server via malicious responses.

So, you should also restrict file names to things you can be really sure aren't remote paths. In general, you should probably avoid letting paths be specified at all; just allow file names only. Those are the only two risks I can think of, though. Otherwise, it's pretty safe.

2

Not the act of opening, but the act of reading (in text mode).

The open() function falls back on several defaults when you don't specify the parameters. This is what the code snippet you provided does:

  • Opens the file in text mode (no "b" in mode flags).
  • Calls locale.getpreferredencoding(False) to determine which decoder to use (no encoding specified).
  • Configures the decoder to throw exceptions when it encounters an error (no errors specified).

Now, say you want to actually # Do something like read from the file, e.g. with f.readline(). This is what happens:

  1. Binary data is read from the file.
  2. The decoder interprets the bytes in order to turn them into a Python string.
    • If it encounters an invalid byte sequence, it raises a ValueError.
  3. Newline sequences are substituted.

Even if you remember to handle the ValueError, there is still some risk. Decoders can have rather complicated logic, so it is very possible for them to have vulnerabilities that are triggered by a cleverly crafted sequence of bytes. For example, at one point a problem in the decoder used by the language Go made it possible to send it into an infinite loop.

This only happens because the file is opened in text mode. If you open it in binary mode ("rb") instead, you can safely read the raw bytes from it.

1
  • Thanks for explicitly pointing out that the issue can be avoided by opening the file in binary mode. Commented Mar 18, 2021 at 14:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .