Earlier quoted context omitted.
I haven’t looked at the code but it’s fairly likely the author considered this? eg the new timeout is set based on the delta of Date.now() instead of just subtracting the time from the previous timeout.
No, it pretty much just does exactly that. const subtractNextDelay = () => { if (typeof remainingDelay === "number") { remainingDelay -= MAX_REAL_DELAY; } else { remainingDelay -= BigInt(MAX_REAL_DELAY); } };
setBigTimeout
41–50 of 129 posts
Re: setBigTimeout
#42The 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 { 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 so…
In nodejs you at least get a warning along with the problematic behavior: Welcome to Node.js v22.7.0. Type ".help" for more information. > setTimeout(() => console.log('reached'), 3.456e9) Timeout { } > (node:64799) TimeoutOverflowWarning: 3456000000 does not fit into a 32-bit signed integer. Timeout duration was set to 1. (Use `node --trace-warnings ...` to show where the warning was created) reached I'm surprised t…
Re: setBigTimeout
#43What is the use-case for such a function?
Off the top of my head, a cron scheduler for a server that reads from a database and sets a timeout upon boot. Every time the server is reboot the timeouts are reinitialized (fail safe in case of downtime). If upon boot there’s a timeout > 25 days it’ll get executed immediately which is not the behavior you want.
Every five seconds check for due dates sooner than 10 seconds from now and schedule them.
The longer a delay the higher the odds the process exits without finishing the work.
Re: setBigTimeout
#44Re: setBigTimeout
#45Earlier quoted context omitted.
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.
> 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 Maybe not contrived but definitely insecure by definition. Allowing user control of rates is definitely useful & a power devs will need to grant but it should never be direct control.
No matter how many layers of abstraction you put in between, you're still eventually going to be passing a value to the setTimeout function that was computed based on something the user inputted, right?
If you're not aware of these caveats about extremely high timeout values, how do any layers of abstraction in between help you prevent this? As far as I can see, the only prevention is knowing about the caveats and specifically adding validation for them.
Re: setBigTimeout
#46If we're pedantic, this doesn't actually do what's advertised, this would be waiting X timeouts worth of event cycles rather than just the one for a true Big timeout, assuming the precision matters when you're stalling a function for 40 days.
Or maybe I'm missing your point.
Re: setBigTimeout
#47instead of chaining together shorter timeouts, why not calculate the datetime of the delay and then invoke via window.requestAnimationFrame (by checking the current date ofc).
Are you suggesting checking the date every frame vs scheduling long task every once in a long while? Can't tell if it is ironic or not, I'm sorry (damn Poe's law). But assuming not, it would be a lot more computationaly expensive to do that, timeouts are very optmized and they "give back" on the computer resources while in the meantime
Re: setBigTimeout
#48If we're pedantic, this doesn't actually do what's advertised, this would be waiting X timeouts worth of event cycles rather than just the one for a true Big timeout, assuming the precision matters when you're stalling a function for 40 days.
I haven’t looked at the code but it’s fairly likely the author considered this? eg the new timeout is set based on the delta of Date.now() instead of just subtracting the time from the previous timeout.
Re: setBigTimeout
#49Earlier quoted context omitted.
JS numbers technically have 53 bits for integers (mantissa) but all binary operators turns it into a 32-bit signed integer. Maybe this is related somehow to the setTimeout limitation. JavaScript also has the >>> unsigned bit shift operator so you can squeeze that last bit out of it if you only care about positive values: ((2*32-1)>>>0).toString(2).length === 32
I assume by binary you mean logical? A + b certainly does not treat either side as 32bit.
Re: setBigTimeout
#50Earlier quoted context omitted.
> 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 Maybe not contrived but definitely insecure by definition. Allowing user control of rates is definitely useful & a power devs will need to grant but it should never be direct control.
Can you elaborate on what indirect control would look like in your opinion? No matter how many layers of abstraction you put in between, you're still eventually going to be passing a value to the setTimeout function that was computed based on something the user inputted, right? If you're not aware of these caveats about extremely high timeout values, how do any layers of abstraction in between help you prevent this?…
Or comes from a set of known values. This stuff isn't that difficult.
This doesn't require prescient knowledge of high timeout edge cases. It's generally accepted good security practice to limit business logic execution based on user input parameters. This goes beyond input validation & bounds on user input (both also good practice but most likely to just involve a !NaN check here), but more broadly user input is data & timeout values are code. Data should be treated differently by your app than code.
To generalise the case more, another common case of a user submitting a config value that would be used in logic would be string labels for categories. You could validate against a known list of categories (good but potentially expensive) but whether you do or not it's still good hygiene to key the user submitted string against a category hashmap or enum - this cleanly avoids using user input directly in your executing business logic.