5

https://developer.mozilla.org/en-US/docs/Web/API/File/lastModified describes the .lastModified property of a File object in JavaScript (usually created when a user selects a file via a HTML <input type="file"> element; in-browser JavaScript served from a web page of course does not have limitless access to the user's file system!)

The docs contain the following cryptic security remark:

To offer protection against timing attacks and fingerprinting, the precision of someFile.lastModified might get rounded depending on browser settings. In Firefox, the privacy.reduceTimerPrecision preference is enabled by default and defaults to 20us in Firefox 59; in 60 it will be 2ms.

At a real stretch I can see how, hypothetically, file modification dates could be used for fingerprinting: if you can get a user select the same file in an <input type="file"> dialog on multiple sites, and you store the accurate-to-the-microsecond file modification date, then you can cross-reference them and notice that, voila, it's the same user (although this seems like a wildly far-fetched scenario!). But I'm at a total loss to imagine what "timing attacks" this rounding could protect against.

What are the attacks that this feature is actually supposed to prevent?

Mark Amery
  • 1,777
  • 2
  • 13
  • 19
  • File times have a granularity of 1 second in many OSs, 1ms at best; not precise enough. – dandavis Apr 17 '18 at 04:48
  • @dandavis: You can create a fake file via JS, and its last modified date has a millisecond precision by default, since it uses `Date.now` to set its value. – Benoit Esnard Apr 17 '18 at 05:49
  • @BenoitEsnard: how would that date be the same across sites so as to allow fingerprinting? I can create Date() objects at will, the key to OP's question is persistence, and for that you need a File from the OS – dandavis Apr 17 '18 at 05:51
  • @dandavis:it's possible to calculate the offset between the site date and the user date. That offset will be constant, so it can be used to fingerprint the user. – Benoit Esnard Apr 17 '18 at 07:01
  • @BenoitEsnard: actually, the `new Date()` output offset, in relation to a 3rd party clock, can fluctuate, which is why `performance.now()` was introduced... – dandavis Apr 17 '18 at 07:11

2 Answers2

2

I don't think there is a timing attack specifically against File.lastModified. I think the reduced precision of the lastModified field is an effect of a mitigation for all kinds of timing attacks.

Spectre/Meltdown were exploitable from JavaScript, by timing certain statements. For this, you would need high-precision timing. To solve this issue, Mozilla reduced the precision of the timer with privacy.reduceTimerPrecision. This must affect all timers: if the someFile.lastModified is more precise than new Date() or some other timer, you could build a precise timer by changing a file and then looking at the lastModified.

Sjoerd
  • 28,707
  • 12
  • 74
  • 102
  • *"you could build a precise timer by changing a file and then looking at the `lastModified`."* - could you really? How are you going to change a file from JavaScript? The usual way of getting a `File` object - from an `` element - doesn't permit modifying the selected file. Perhaps your idea here is still correct, but there's a missing step in your chain of logic (perhaps some way of generating `File` objects *not* through an `` that lets the attacker create them at will with the current instant as their `.lastModified`?) without which it doesn't quite make sense. – Mark Amery Apr 16 '18 at 15:02
  • if you "upload" a file, and change the file, the File() properties get updated automatically; i use this to create watchFile-like monitors on webapps, generally to consume logs or monitor long-running conversions. – dandavis Apr 17 '18 at 04:47
0

You're right: it's a protection against fingerprinting.


This wouldn't need any user interaction, since you can create dummy files via JavaScript:

const file = new File([], 'foo.bar');
console.log(file.lastModified);

If you don't specify the last modified date, the default value will be Date.now().

Since Date.now had to be throttled to prevent fingerprinting attacks (see bug #1217238), the docs needs to reflect that behavior to developers.

Benoit Esnard
  • 13,942
  • 7
  • 65
  • 65
  • a dynamic "file" would not have the same time on different sites, nor could one site's time be compared to another's, so it's useless for fingerprinting regardless of the precision (or lack thereof) – dandavis Apr 17 '18 at 06:00