Git Product home page Git Product logo

hr-time's Introduction

hr-time's People

Contributors

annevk avatar chrisn avatar divmain avatar ericduran avatar github-actions[bot] avatar igneel64 avatar igrigorik avatar jyasskin avatar marcoscaceres avatar ms2ger avatar noamr avatar npm1 avatar plehegar avatar rakuco avatar saschanaz avatar sidvishnoi avatar siusin avatar toddreifsteck avatar yoavweiss avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hr-time's Issues

Security consequences of measuring time of operations on cross-origin data

When it comes to timing information, the key property we are looking for is the ability of script to measure the time that operations take. This is both the useful property that this API is looking to provide, and the dangerous one that attackers wish to exploit by learning about timing differences caused by data that they can't otherwise see.

For instance, see http://www.contextis.com/documents/2/Browser_Timing_Attacks.pdf

The security considerations doesn't really cover this at all.

Note: What is most concerning is that 5μs isn't the floor on the accuracy of measurements, because basic statistics allows for much smaller differences to be recovered. That's an important thing to explain.

There are two ways we can mitigate this sort of attack:

  1. Stop writing code with timing that is dependent on the inputs it receives. Basically, write the entire browser to be constant time. That's essentially ridiculous. It's analogous to saying that you will mask the length of messages in a protocol by sending at a constant rate.
  2. Isolate script from the clock. This is also somewhat ludicrous, but it might be more achievable. It would make it hard for script to measure the time that operations take. Note that this is imperfect and it introduces latency proportional to the gains that it provides. But it can increase the number of samples required for statistical methods of measurement.

Clarify ServiceWorker time origin

(as discussed at TPAC...)

@slightlyoff I believe current language should be sufficient for ServiceWorker, correct?

That said, I think we may need to refine workerStart:

The workerStart attribute MUST return a DOMHighResTimeStamp representing the difference between the time origin of the SharedWorkerGlobalScope associated with the SharedWorker and the time origin of the current document. - source

Since there is no "current document" (there can be multiple) for ServiceWorker, above doesn't really work. Perhaps add a clause for "if there is no current document, or there are multiple, then report time from worker start"?

Security Review

Philippe mentioned that there is interest in having HR-Time 2 undergo another security review before sending it to next phase in process. We should do that!

workerStart and "current document" ?

From
https://lists.w3.org/Archives/Public/public-web-perf/2015May/0032.html

The one issue I have is that workerStart is defined as follows:

The workerStart attribute MUST return a DOMHighResTimeStamp
representing the difference between the time origin of
WorkerGlobalScope and the time origin of the current document.

I assume it means "the WorkerGlobalScope of the AbstractWorker the
getter is invoked on", right?

But I'm not at all sure what "current document" is supposed to mean
here. That part is clearly wrong when getting the .workerStart of a
worker started from another worker (so the code that gets .workerStart
is running in a worker), but even when a worker was started from a
window it's ambiguous: is the "current document" the document that
started the worker or the document the script doing the get is running
in or something else?

[Maintenance, reminder] Cycle environment variables that were encrypted with Travis

Travis CI sent a message this week alerting of a bug in the way they used to encrypt environment variables. Owners of this repo should have received it.

Depending on the way encryption was done in this repo using the Travis CLI, those values might have leaked.

This is a reminder for maintainers of this repository to make sure they discard old values, and re-encrypt new ones with the latest version of travis, now that the bug has been fixed.

Please close this issue if action has already been taken. Feel free to ping me or sysreq if you need help.

Security and privacy considerations for DOMHighResTimeStamp resolution

Note: the intent of this issue is to provide a reference and track the ongoing research, discussions, proposals, and implementation techniques employed by various browsers on how they expose or provide access to high resolution time.


Paraphrasing Section 7.1: Clock resolution...

Access to accurate timing information, both for measurement and scheduling purposes, is a common requirement for many applications... This specification defines an API that provides sub-millisecond time resolution, which is more accurate than the previously available millisecond resolution exposed by DOMTimeStamp.

... Access to the same accurate timing information can sometimes be also used for malicious purposes by an attacker to guess and infer data that they can't see or access otherwise.

To ensure that the new API does not significantly improve the accuracy or speed of such attacks, the recommended minimum resolution of the DOMHighResTimeStamp type should be inaccurate enough to prevent attacks... In order to mitigate such attacks user agents may deploy any technique they deem necessary. These techniques may include: Resolution reduction, added jitter, abuse detection and/or API call throttling.

This problem space space remains an unsolved and an evolving one. There is no existing industry consensus or a definitive set of recommendations that applies to all browsers, which is reflected in the range of different implementations and platform-specific techniques used by various browsers.


Relevant prior art and discussions:

  1. Reducing resolution (SPECTRE and microarchitecture timing attacks): #56
  2. PING review feedback: #20
    • Gating timestamps behind existing permission prompts: #64
    • Related discussion on evaluated and proposed strategies: #56 (comment)

Find better sources to quote than Wikipedia

For both "unix-time" and "clock drift", we're citing Wikipedia, which seems shaky.

We should find better places for those definitions.
For "time", there's a definition in ECMA-262 which we could point to or borrow.
For "clock drift", we may need to define our own

Update worker reference

From #45 (comment):

The references to the W3C unmaintained fork of workers rather than the WHATWG HTML Standard will end up confusing implementers. I personally wouldn't accept that.

Define the performance attribute for workers

Separate issue from #9 since this may actually require discussion.

FWIW, it's already exposed in workers in at least Blink and Gecko.

In Blink it's a bit weird, with a separate [NoInterfaceObject] interface WorkerPerformance that looks a lot, but not exactly, like the Performance interface.

Following Gecko would probably make more sense, they just use [Exposed=(Window,Worker)] or [Exposed=Window] as makes sense.

CC @bzbarsky

timeOrigin prose doesn't make sense

The IDL says:

readonly attribute DOMHighResTimeStamp timeOrigin;

and the prose says:

The timeOrigin attribute MUST return a DOMHighResTimeStamp representing the high resolution time of the time origin timestamp of the global object.

where "time origin timestamp" is defined as:

  • If time origin is undefined, return undefined.
  • Otherwise, the sum of the high resolution Unix time at which the global monotonic clock is zero and the time value of the global monotonic clock at which the time origin is zero.

OK, so if time origin is undefined... what does the .timeOrigin attribute return? undefined is not a valid DOMHighResTimeStamp value.

`timeOrigin` is not clamped

According to the spec, timeOrigin is not clamped.
While it's not clear if that can be abused, having performance.now() be and timeOrigin be in different resolutions seems confusing, and there's no clear use case for it. I suggest we clamp timeOrigin as well.

Suggestions: ticking during sleep, comparison across contexts, time origin + now semantics, and skew definition

Hi all,

My research group at Princeton has been collaborating with Mozilla on a project that involves precise monotonic cross-context timing. We've encountered a recurring browser- and platform-specific implementation issue, where a context's High Resolution Time monotonic clock does not tick during sleep: mdn/content#4713. Contributors to the standard previously discussed a version of this issue in Chrome and reached consensus that the clock should tick during sleep: #65.

I would like to suggest several related revisions to the High Resolution Time standard for the Web Performance Working Group's consideration.

First, the language that closed #65 (PR #69) does not expressly address what should happen during sleep.

    <p class="note">In certain scenarios (e.g. when a tab is backgrounded), the
    user agent may choose to throttle timers and periodic callbacks run in that
    context or even freeze them entirely. Any such throttling should not affect
    the resolution or accuracy of the time returned by the monotonic clock.</p>

Addressing the scenario would be valuable for implementers of the API, since operating systems typically offer separate monotonic clocks APIs that do and don't include sleep. Addressing the scenario would also be valuable for users of the API, who could better understand the expected behavior and document inconsistent behavior. Here's an example revision.

    <p class="note">In certain scenarios (e.g., when a tab is backgrounded, 
    the thread or process for a tab is sleeping, or the system has entered a 
    suspended state), the user agent may choose to throttle timers and 
    periodic callbacks run in a context or even freeze them entirely. Any 
    such throttling or freezing should not affect the resolution or accuracy 
    of the time returned by the monotonic clock.</p>

Second, I would suggest upgrading the informative note on this issue to a normative requirement. If the monotonic clock in a context depends on past sleep for that context, then the following use case cannot be reliably supported in real-world conditions.

      <p>This specification defines a few different capabilities: it provides
        timestamps based on a stable, monotonic clock, comparable across
        contexts, with potential sub-millisecond resolution.</p>

      ...

      <p>Comparing timestamps between contexts is essential e.g. when
        synchronizing work between a {{Worker}} and the main thread or when
        instrumenting such work in order to create a unified view of the event
        timeline.</p>

If a High Resolution Time timestamp can vary by a context's sleep history, then timestamps are not comparable across contexts in real-world scenarios (where thread, process, and system sleep are frequent and unpredictable). Similarly, the example provided in Section 1.2 (Example 2) is not reliable in real-world scenarios. A stronger version of this normative requirement would be to migrate the per-context monotonic clocks entirely to the shared monotonic clock (i.e., the same clock ticking in all contexts, just with a per-context time origin). That might not have been realistic with OS capabilities ~6 years ago, but it might be realistic now. Some relevant context that I found helpful: #22 and #29.

Third, I would suggest adding semantics for performance.timeOrigin + performance.now() and how that compares to Date.now() in the explanation of monotonic clocks (Section 6). There are normative requirements that DOMHighResTimeStamp count in milliseconds, that the reference point for the shared monotonic clock is ordinary ECMAScript time, and that a context's time origin be set with the shared monotonic clock. The only way I see to satisfy these normative requirements is if performance.timeOrigin + performance.now() and Date.now() both represent the current time, and should only differ because of either 1) user or automated adjustments to the system clock after the shared monotonic clock starts ticking, or 2) differences in underlying clock implementation (e.g., there might be different hardware clocks with slightly different frequencies). There are definitely use cases for those performance.timeOrigin + performance.now() semantics, where the goal is to timestamp events in a way that approximates real-world time, is monotonic, ideally is comparable across contexts (the prior item), and is not subject to user or operating system clock adjustments, assuming that the system clock was approximately correct when the shared monotonic timer started ticking. I recognize there have been prior discussions about how High Resolution Time relates to Date.now(), with a resolution that the two APIs shouldn't have their values compared (e.g., #27). To be clear, I'm not suggesting a quantitative guarantee that the values provided by the two APIs will be similar, but rather, a semantic definition of how the two APIs relate and the specific conditions that can cause divergence over time.

Fourth, I would suggest defining what the term "skew" means in the document, and perhaps using a different term instead. The notion, if I understand correctly from discussion in prior issues, is that NTP and similar automatic adjustments for clock errors should not change (skew) the monotonic clocks. Unfortunately, skew also typically means a difference between two clocks (which NTP tries to mitigate). So... depending on the meaning of "skew," the normative requirement that monotonic clocks not have "system clock skew" either means they must not change when the system clock changes, or they must change when the system clock changes. I would also suggest clarifying that monotonic adjustments to a monotonic clock are permissible (e.g., monotonic NTP corrections for oscillator frequency or adjtime corrections, see CLOCK_MONOTONIC vs. CLOCK_MONOTONIC_RAW in clock_gettime); the current text could be interpreted to prohibit any adjustments.

WebCodecs Time Stamps

Hello!

We're trying to work out (w3c/webcodecs#52, w3c/webcodecs#122) what kind of timestamps to use for frames in WebCodecs. In general we need ~microsecond resolution, measured from either time 0 at the start of the media, or in calendar time (typically relative to the Unix epoch).

Usually media times are measured as an integer fraction of seconds (a timestamp and a timebase), but there doesn't seem to be a convenient Rational type in JS, so it's not very ergonomic.

The <video> element has currentTime in seconds (as a double). RTC uses DOMHighResTimeStamp for some things. Internally Chrome uses int64 microseconds.

It seems like DOMHighResTimeStamp is the most reasonable choice for us, but it also seems to have been defined relative to a specific epoch. Is there any concern with WebCodecs using it with no explicit epoch?

Translating high resolution timestamps between globals

Note (igrigorik), original title: "translateTime does not work for nested workers"

Through MessageChannel a document can directly communicate with a worker that it otherwise knows nothing about. translateTime doesn't really work with that existing capability model.

Use section/headings for attributes and methods

This is an Editorial request to make the easier to use: it would be nice to put the methods and attributes into their own sections, then they will appear in the ToC. That makes the spec nicer to use as a developer, and you get a nice overview of the API at a glance.

Should time origin be defined in terms of a monotonic clock?

The way things are defined right now, it's not clear whether "time origin" is recorded via wall clock or a monotonic clock.

If it's via wall clock, then you can end up in a situation like this in a web page:

var now = performance.now();
var blob = new Blob(["postMessage(performance.now())"]);
var w = new Worker(URL.createObjectURL(blob));
w.onmessage = function (e) {
  alert(performance.translateTime(e.data, w) - now); // alerts a negative number
}

which seems suboptimal. Seems to me like the same monotonic clock used for performance.now() in general should be used for recording all time origins.

Provide hook for getting a high resolution time between time origin and a "time"

The DOM Standard currently creates a DOMHighResTimeStamp representing the high resolution time from the time origin to the time of the occurrence that the event is signaling.

"[T]he time of the occurrence that the event is signaling" is really the only thing that the DOM Standard should define here (or callers). The remainder should be a reference to a concept in this document that does the correct thing. I.e., something that "current high resolution time" also builds upon.

Time origin of event timestamps across iframes

In the case that event listener functions are defined in another window from which the event is created, the time origin of high resolution event timestamps has implementation differences:

  • Current behavior in Chrome, Firefox, Edge: The event timeStamp received in all listeners, regardless of which window the functions were defined in, uses the time origin of the window that the event was created in. Listeners in parent and child windows will receive the same value for timeStamp.

  • Current behavior in Safari (desktop and iOS): The event timeStamp uses the time origin of the window that the listener function is defined in. Listeners in parent and child windows will receive a different value for timeStamp.

I'm not sure which implementation is the "correct" one.

The Boomerang RUM library is often loaded in an iframe and we add event listeners to the parent window to calculate things like time to first interaction, interaction delay, etc. It is hard for us to detect which time origin is being used.

I setup a repro page here: https://querymetrics.com/event-timestamp.html

Gate Timestamps behind existing permission prompts

Following up from #20

The privacy risks associated with these high res timestamps are documented in the draft, as well as some of the issues (e.x. #56), and a long list of research papers (happy to provide citations, but they're already linked to elsewhere in the repo).

The usefulness of the timestamps are also well documented in #56, and it seems like there are cases where these would be very useful to web users.

However, these cases seem to be the rare case, and not what users will encounter on the vast majority of pages. And the most compelling examples of the usefulness of these timestamps are gated behind permission prompts (fullscreen API for games, USB inputs and WebVR for VR uses, etc).

I suggest only making these timestamps available when the user has approved one of the following permissions (using the permissions in Chrome currently):

  • Fullscreen
  • MIDI
  • USB Devices

Could also add to the above list, if there are other permissions that'd be relevant. But it seems like this would be a way of blocking the privacy violating uses of these timestamps (at least in the common case) while also making them available in the cases where they're likely to be useful.

Timing attacks

We’ve recently published a report describing a new Javascript-based network attack. Our attack lets a malicious website learn a surprising amount of personal information about an innocent user, and is largely based upon repeated calls to performance.now() as a measurement method. We have a proof-of-concept demo for this attack which I can share off-list with relevant stakeholders. A draft report is also available online here:
http://arxiv.org/abs/1502.07373 http://arxiv.org/abs/1502.07373

From our testing it is very apparent that somewhat reducing the resolution of performance.now() will make the attack much more difficult. We noticed that various browser vendors implement the call with different precisions, with Firefox for Linux and MacOS going down to the single nanosecond. Our attack as described becomes very difficult to launch once the resolution of performance.now() is upper-bounded to 5 thousandths of a millisecond.

I would like to suggest that you change the spec to recommend this countermeasure. In your opinion, does this modification incur too much of a usability loss (to games, music, VR, etc)?

can performance.now() timers be frozen for background tabs, etc?

Currently users in chrome are seeing relatively large divergence from Date.now() and timeOrigin+performance.now(). We believe this is likely due to chrome allowing the performance.now() to counters to be frozen for some periods, like when a tab is in the background. See:

https://bugs.chromium.org/p/chromium/issues/detail?id=948384

While the spec mentions clock skew and system adjustments, its not clear to me if the browser is allowed to freeze counters for long periods. This can lead to two tabs for the same site having drastically different times that can no longer be compared.

If we cannot compare across tabs with performance.now(), must sites use Date.now() if they want this kind of comparison? This would seem unfortunate to me.

Discussion of privacy issue mitigations for possible transferal of timestamps across contexts

#22 discusses a privacy issue of globalOffset being used for fingerprinting.
#25 is a another proposed way to transfer DomHighResolutionTimestamps between contexts

My question:

  • How much more of a privacy issue is exposing global/local offset compared to code that creates its own Worker and then sends a time stamp across a few workers to figure out local offsets?

I guess.. my thinking is.. if the globalOffset time is based upon clock time in some way, there is no leak that is more significant than what is already leaked by correlating Date() to performance.now() in various contexts that can already be reached.

This leads me back to @bzbarsky and @sicking suggesting that perhaps everything should be based upon time... That makes it less finger printable because you'll have entire time zones with the same offSets. (@sicking seemd to be leaning that that way in #22 before we veered to performance.transferable() aka #25.)

ReSpec errors

Currently, https://w3c.github.io/hr-time/ contains 1 warning and 2 errors.

Warning is: "Linter (local-refs-exist): Broken local reference found in document. Please fix the links mentioned. See developer console. Occured at: 1, 2."

Errors are both: "Couldn't expand inline reference. The id "" is not in the document. at: 1."

But if I copy the html file and open it locally I see no warning or error.

Time Origin in Workers - official moment of creation or not?

The spec specifically mentions that the time origin for Workers:

The time origin is the time value from which time is measured:

This doesn't appear to match implementations. For example:

<script>
let blob = new Blob([`console.log(performance.now())`]);
let url = URL.createObjectURL(blob);
console.log(performance.now());
setTimeout(() => { worker = new Worker(url); }, 1000);
</script>

Based on the spec, I would expect very low numbers for both logs. The one on the page because it is very close to the page's load. The one in the worker because it is very close to the worker's load.

Implementations are consistent but differ from the spec:

  • Chrome (v55)
    page: 13.495
    worker: 1047.71

  • Firefox (v51)
    page: 17.135
    worker: 1032.125

I am unable to test on Edge. If someone could include their numbers that would be fantastic!

Comments on "Define 'relative high resolution time'"

Looking at the diff of #95 there's a couple things I don't really understand:

  1. "relative high resolution time" says it takes a DOMHighResTimeStamp but this isn't used and a variable isn't named for it. Should that be removed?
  2. "current high resolution time" talks about a "context object" but that is only available (as "this" these days) when defining IDL members.

Why is Performance an EventTarget?

Why is Performance an EventTarget?

interface Performance : EventTarget {
    ...
};

I didn't see any events that would be dispatched on Performance, so registering listeners would seem unnecessary. Is this in preparation for the future or are events dispatched in a related spec?

WebIDL serializer has been deprecated in favor of toJSON operation

Hi!

We recently deprecated WebIDL serializers. You can now directly specify toJSON operations instead, which you previously weren't allowed to do.

To deal with common cases, we added a new [Default] extended attribute which triggers the default toJSON operation that behaves similarly to how serializers={attributes} or serializers={attributes, inherit} used to. That is, it serializes all attributes that are of a JSON type into a vanilla JSON object.

It seems only the following interface in this spec is impacted by this change:

It's a good candidate for the default toJSON operation, so the below should be all you need:

[Exposed=(Window,Worker)]
interface Performance : EventTarget {
    DOMHighResTimeStamp now();
    readonly attribute DOMHighResTimeStamp timeOrigin;
    [Default] object toJSON();
};

I'm sorry for the inconvenience this causes, but our hope is that this ultimately makes things a lot simpler and clearer for everybody.

Please feel free to reach out if you have any questions.

Thanks!

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.