Giter Site home page Giter Site logo

Identify and constrain timers about snaps HOT 13 CLOSED

metamask avatar metamask commented on June 14, 2024
Identify and constrain timers

from snaps.

Comments (13)

rekmarks avatar rekmarks commented on June 14, 2024

We already constrain setTimeout and setInterval in the iframe execution environment, but we have not looked into e.g. Date.

from snaps.

kenhkan avatar kenhkan commented on June 14, 2024

A note from refinement session: We need to constrain Date as well.

from snaps.

ritave avatar ritave commented on June 14, 2024

With help of @naugtur we've identified:

  1. Date()
  2. new Date()
  3. Date.now()
  4. performance
  5. DOMHighResTimeStamp
  6. process.hrtime()
  7. setTimeout and setInterval if they are not constrained by the browser / the load is low.
    1. They are not constrained by the browser in general case, only when nested.
  8. alarms
  9. TC39 Temporal

Inside snaps we allow:

  1. Date and similiar
  2. setInterval
  3. setTimeout

To protect against Spectre, Firefox rounds the precision to 1 ms increments.

Just rounding is not enough since you can create an increasing counter loop and detect the change in the millisecond. A random noise should be added

from snaps.

ritave avatar ritave commented on June 14, 2024

There are more subtle ways to create timers. When doing this task, please read Fantastic Timers and Where to Find Them: High-Resolution Microarchitectural Attacks in JavaScript paper to check for anything more

from snaps.

naugtur avatar naugtur commented on June 14, 2024

Note that the paper goes very deep into searching for time and some of it may not be practical. Like things that take predictable time synchronously - that's not useful for timing attacks because nothing can be done while the time is being measured.

As for random noise adding when rounding, the rounding function would need one item of state to ensure the time doesn't fluctuate back and forth, because it could be used to defeat the rounding.
The state doesn't need to be preserved across shutdowns or anything, just be there as the time measurements keep being called by a snap.

function createRounder({ factor }) {
  let current = 0;
  return (time) => {
    const newRounded = Math.round( (time/factor) + tinyRandomNoise );
    if(newRounded>current){
      current = newRounded;
    }
    return current;
  }
}

TODO: figure out the span of values for generating tinyRandomNoise

from snaps.

FrederikBolding avatar FrederikBolding commented on June 14, 2024

I might be missing something but would it be simpler to just add a bit of noise instead of rounding at all?

e.g.

  const getNoise = () => crypto.getRandomValues(new Uint32Array(1))[0] % 5;

  let currentTime = 0;
  const now = () => {
    const actual = Date.now();
    const new = actual + getNoise();
    if (new > currentTime) {
      currentTime = new;
    }
    return currentTime;
  };

from snaps.

FrederikBolding avatar FrederikBolding commented on June 14, 2024

Also, in this thread we have been mainly discussing Date so far. Do we need to add some noise to reduce precision on setTimeout and setInterval as well? We have them constrained to not overlap handles between snaps right now, but they still have normal precision.

from snaps.

GuillaumeRx avatar GuillaumeRx commented on June 14, 2024

I might be missing something but would it be simpler to just add a bit of noise instead of rounding at all?

e.g.

  const getNoise = () => crypto.getRandomValues(new Uint32Array(1))[0] % 5;

  let currentTime = 0;
  const now = () => {
    const actual = Date.now();
    const new = actual + getNoise();
    if (new > currentTime) {
      currentTime = new;
    }
    return currentTime;
  };

Rounding is not really usefull for Date since the timestamps are already at the ms precision. I guess rounding to the ms as Firefox does is usefull for more precise timers like peformance.now(). Date should only be fuzzy timed to prevent high resolution timer recovery IMO.

EDIT: We could also round the date to only have a second of precision but I don't know if it's useful.

from snaps.

GuillaumeRx avatar GuillaumeRx commented on June 14, 2024

Also, in this thread we have been mainly discussing Date so far. Do we need to add some noise to reduce precision on setTimeout and setInterval as well? We have them constrained to not overlap handles between snaps right now, but they still have normal precision.

Yes, that was part of the work but likely more easier than adding the fuzziness in Date.

from snaps.

GuillaumeRx avatar GuillaumeRx commented on June 14, 2024

Adding some fuzziness to Date is also harder than expected. Due to the implementation of Date (being able to call it in several ways like new Date() and Date()) lead me follow the route of re-writing part of the Date constructor which I didn't had any good way of achieving at the time I handed off the task.

from snaps.

naugtur avatar naugtur commented on June 14, 2024

@FrederikBolding
Rounding removes more information about the values and removes the precision so the developer would not believe they're getting precise values. With more of the information gone, Math.random might suffice to generate the noise and is cheaper. But overall I agree your proposal seems fine and is clearly better than just rounding.

As for setTimeout and setInterval - they have some noise built into them by nature (they run on the next event loop pass after the time for which they were scheduled). I'm not sure if there's a benefit to disturbing them. I would forbid using a timeout value of zero for good measure. We don't want that kind of behavior. Especially for setInterval.
We might want setInterval to throw if less than 10 is passed in as timeout.
Not sure what to do with setTimeout, because it's sometimes used to make something happen right away but asynchronously, so throwing would break the ecosystem potentially. Silent Math.max(10, timeout) is also debatable, but would not break any non-silly code.

from snaps.

FrederikBolding avatar FrederikBolding commented on June 14, 2024

@naugtur

I think throwing on setInterval or setTimeout depending on passed args could both be ecosystem breakers. I would much rather set a slightly higher minimum that we automatically enforce (e.g. Math.max(10, timeout)). Do we think a minimum of 10ms is fine?

If we don't do any rounding what should be the maximum value for noise? Also 10ms? 5? something else? In general it seems simpler to me to just add some random noise, but persist it, instead of rounding.

from snaps.

FrederikBolding avatar FrederikBolding commented on June 14, 2024

Potential solution: #1118

from snaps.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.