←back to thread

setBigTimeout

(evanhahn.com)
210 points cfj | 2 comments | | HN request time: 1.013s | source
Show context
n2d4 ◴[] No.41880898[source]
The default behaviour of setTimeout seems problematic. Could be used for an exploit, because code like this might not work as expected:

    const attackerControlled = ...;
    if (attackerControlled < 60_000) {
      throw new Error("Must wait at least 1min!");
    }

    setTimeout(() => {
      console.log("Surely at least 1min has passed!");
    }, attackerControlled);

The attacker could set the value to a comically large number and the callback would execute immediately. This also seems to be true for NaN. The better solution (imo) would be to throw an error, but I assume we can't due to backwards compatibility.
replies(6): >>41881042 #>>41881074 #>>41881774 #>>41882110 #>>41884470 #>>41884957 #
arghwhat ◴[] No.41881042[source]
A scenario where an attacker can control a timeout where having the callback run sooner than one minute later would lead to security failures, but having it set to run days later is perfectly fine and so no upper bound check is required seems… quite a constructed edge case.

The problem here is having an attacker control a security sensitive timer in the first place.

replies(2): >>41881665 #>>41888952 #
a_cardboard_box ◴[] No.41881665[source]
The exploit could be a DoS attack. I don't think it's that contrived to have a service that runs an expensive operation at a fixed rate, controlled by the user, limited to 1 operation per minute.
replies(2): >>41882211 #>>41883672 #
arghwhat ◴[] No.41883672[source]
A minimum timing of an individual task is not a useful rate limit. I could schedule a bunch of tasks to happen far into the future but all at once for example.

Rate limits are implemented with e.g., token buckets which fill to a limit at a fixed rate. Timed tasks would then on run try to take a token, and if none is present wait for one. This would then be dutifully enforced regardless of the current state of scheduled tasks.

Only consideration for the timer itself would be to always add random jitter to avoid having peak loads coalesce.

replies(1): >>41885533 #
1. lemagedurage ◴[] No.41885533[source]
I don't think it's that far fetched that a developer implements a rate limiter with setTimeout, where a task can only be executed if a timeout is not already running. The behaviour in the article is definitely a footgun in this scenario.
replies(1): >>41886626 #
2. ◴[] No.41886626[source]