1

I'm wondering if it's possible to exploit a TOCTOU vulnerability without having local access to file systems?

For example, in the context of a user uploading a file to a webserver, is this timing attack feasible outside of lab settings, or is it impractical given latency, file system mitigations (if any), etc?

Scenario: given a save image function on a web server:

function saveImage(uploadedFile) {
  if (!validImage(uploadedFile.contents) {
    throw new Error('error, not a valid image!');
  }

  saveFile(uploadedFile.name, uploadedFile.contents);
}
  1. Attacker uploads "file.jpg", with JPG content
  2. saveImage function executes, passes validImage check
  3. almost simultaneously attacker uploads "file.jpg" with malicious executable contents, overwriting temp file with uploaded file contents
  4. saveFile called, writing the file successfully with malicious contents
2
  • 1
    The TOCTOU vulnerability pattern is not limited to file system access but is a more general pattern. In your specific example there is no vulnerability though since the file is not reread, at least assuming that contents is a static attribute of uploadedFile. Commented Nov 4, 2021 at 17:40
  • Great response, thanks CBHacking and Steffen
    – qUEnbcAr
    Commented Nov 5, 2021 at 20:25

1 Answer 1

2

Steffen pretty much nailed it in his comment, but to expand on that:

TOCTOU isn't in any way specific to files or file systems; it's a vulnerability that is present any time you have:

  1. Untrusted input or state
  2. That gets validated before use
  3. But can then be modified such that
  4. The modified version is used without re-validation

Your scenario meets conditions #1 and #2, but (probably) not #3 or #4. The problem is that, when you upload a new version of "file.jpg" (your third step), that just creates an entirely new web request, which will be processed separately. The object in memory that uploadedFile (or uploadedFile.contents) points to isn't going to change during the execution of the function (or if it does, throw your server away and get one that's remotely sane). If the server supports parallel execution and/or preemptive multitasking, a new instance of the saveImage function might start before the first one finishes, but the new instance's uploadedFile will refer to the second upload, not the first one, and it will start again from the beginning (attempting to validate the second upload), while the first instance continues processing the initial upload. The first instance will complete successfully; the second will throw the error.


What would it take for this to be vulnerable to TOCTOU anyway? A minimum of two changes:

  • The server would need to overwrite the memory buffer (or temporary file) used by the first upload when the second upload happens.
  • The modified temporary file would need to be re-read (typically this happens if you close the file handle between steps, without caching the file contents within the function), or if it's a buffer, the uploadedFile variable (or at least its contents member) would need to be re-read from memory that got overwritten in place (instead of e.g. a new allocation being created, in which case the old pointer would probably be cached).

Generally, the thread processing request X doesn't even have access (except in the strict sense of "shares an address space with") the parameters and local variables of the thread processing request Y, and vice versa. Deliberately overwriting the buffer of an incomplete request is unheard of. A server that did that wouldn't just be insecure, it wouldn't even work (after all, you have no way to control whether multiple browsers make requests to the same server at the same time, and indeed it's normal for that to happen; this is why real servers have a request queue and/or thread pool, and network listener sockets allow multiple waiting connections).

Temp files could have this problem, but it would need to both re-use the file name (usually temp files get random, unique names), and the saveImage function would need to either allow another thread to modify the file while the handle is open and then re-read the file, or it would need to close the handle and re-open it. By default, on Linux the original file contents would still be there until the file is closed and reopened, and on Windows the other thread wouldn't be allowed to overwrite or delete the file at all until the thread running saveImage closed it.


As a practical matter, even if it was vulnerable in theory, this would be tricky to exploit in practice from the same computer - network I/O is usually much slower than local processing - but you could do it if the validation step was very slow or the server was busy and stopped for a while after validation to do something else.

Also, just to be clear: "malicious executable contents" don't necessarily achieve anything. I can upload malware.exe (renamed to puppies.jpg) all day long if I want to; the server isn't going to execute it! Even if somebody downloads it again, they probably won't try to execute it, because they'll think it's an image (opens in another process that can display images), not an executable (used to create a new process that treats the file as machine instructions).

You must log in to answer this question.

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