Proposal-temporal: new Instant() or Instant.now()?

Created on 25 Jul 2018  路  16Comments  路  Source: tc39/proposal-temporal

Hi, @pipobscure , it seems now family is removed without explanation.

Would this proposal cover now in the future?
Otherwise user could only fallback to Date.now() or new Date().

behavior spec-text

Most helpful comment

Hi @littledan , thanks for bringing my attention to this issue. It is indeed crucial that this proposal exclude any direct access to the current time.

An important high level invariant of JavaScript, with a small and fixed number of grandfathered exceptions(*), is "no I/O powers or hidden mutable state among the primordials". As a result, JavaScript the language is analogous to the user-mode instructions portion of a processor. All abilities to cause or sense effects to/from the world outside those JavaScript objects are only via host-provided objects, which are only initially obtained by looking them up in the global scope or global object, by names other than the JavaScript standard globals. Such lookup is thus analogous to system-mode instructions or systems calls. Intercepting these lookups thus provides an analogous trapping mechanism for virtualizing the outside world without impeding general purpose computation.

At https://youtu.be/pig-sIS8_Wc?t=1h25m , 1 hour, 25 min into my Stopping Exfiltration talk (a recorded re-presentation of the talk I gave at the May 2018 tc39 meeting), I specifically call out the unconditional safety of date arithmetic, parsers, and renderers, vs the unsafety of, for example, Date.now.

Our ability to pleasantly secure JavaScript comes largely from the strict separation between those APIs presenting computational conveniences vs those providing access to the outside world. Thus, we must not repeat the Date.now mistake. Secure EcmaScript indeed censors Date.now by default, while leaving intact its abilities to represent, parse, and render dates.

https://rawgit.com/Agoric/SES/master/demo/?dateNow=enabled is our challenge page, showing how its presence unsurprisingly enables one to read timing channels, while in its absence together with the absence of various host services that transformational libraries don't need, we can run transformational libraries in a mode that ensures they cannot sense the passage or duration of time, and so cannot read side channels built on timing channels.

(*) The grandfathered exceptions are

  • Date.now() and Date(), and new Date() providing access to the current time. SES instead has Date.now() return NaN and the others return results consistent with that. The moment library, run under SES, works fine except for those parts that directly rely on access to the current time.
  • Math.random(). If this were a cryptographically strong pseudo-random number generator, not observably different from a source of genuine entropy, then it would not provide a global communications channel.
  • Access to the current time zone. Actually, I'm unclear on this. As I carry my computer between time zones, is this supposed to dynamically update? In any case, it is hard to imagine that this provides a practical way to read side channels. Our challenge page does not censor this, so please feel free to use it to try to read the side channel provided by the challenge.

Attn @jfparadis @warner @fudco @tribble

All 16 comments

now() was removed, because it's simply sugar for Instant.fromMilliseconds(Date.now()).

I think we just want to leave the options open for an additional/later proposal that could give us higher precision creation given that temporal objects can do nanosecond resolution.

That seems like a stretch to achieve as part of this proposal. If we add .now() now, then I fear the follow-up proposal asking for higher precision instantiation would meet with the but we already have .now() hurdle.

So sacrificing higher precision in a followup for simple syntactic sugar didn't seem worth while to me.

Reasonable, thanks for the explanation!

Cc @erights

Hi @littledan , thanks for bringing my attention to this issue. It is indeed crucial that this proposal exclude any direct access to the current time.

An important high level invariant of JavaScript, with a small and fixed number of grandfathered exceptions(*), is "no I/O powers or hidden mutable state among the primordials". As a result, JavaScript the language is analogous to the user-mode instructions portion of a processor. All abilities to cause or sense effects to/from the world outside those JavaScript objects are only via host-provided objects, which are only initially obtained by looking them up in the global scope or global object, by names other than the JavaScript standard globals. Such lookup is thus analogous to system-mode instructions or systems calls. Intercepting these lookups thus provides an analogous trapping mechanism for virtualizing the outside world without impeding general purpose computation.

At https://youtu.be/pig-sIS8_Wc?t=1h25m , 1 hour, 25 min into my Stopping Exfiltration talk (a recorded re-presentation of the talk I gave at the May 2018 tc39 meeting), I specifically call out the unconditional safety of date arithmetic, parsers, and renderers, vs the unsafety of, for example, Date.now.

Our ability to pleasantly secure JavaScript comes largely from the strict separation between those APIs presenting computational conveniences vs those providing access to the outside world. Thus, we must not repeat the Date.now mistake. Secure EcmaScript indeed censors Date.now by default, while leaving intact its abilities to represent, parse, and render dates.

https://rawgit.com/Agoric/SES/master/demo/?dateNow=enabled is our challenge page, showing how its presence unsurprisingly enables one to read timing channels, while in its absence together with the absence of various host services that transformational libraries don't need, we can run transformational libraries in a mode that ensures they cannot sense the passage or duration of time, and so cannot read side channels built on timing channels.

(*) The grandfathered exceptions are

  • Date.now() and Date(), and new Date() providing access to the current time. SES instead has Date.now() return NaN and the others return results consistent with that. The moment library, run under SES, works fine except for those parts that directly rely on access to the current time.
  • Math.random(). If this were a cryptographically strong pseudo-random number generator, not observably different from a source of genuine entropy, then it would not provide a global communications channel.
  • Access to the current time zone. Actually, I'm unclear on this. As I carry my computer between time zones, is this supposed to dynamically update? In any case, it is hard to imagine that this provides a practical way to read side channels. Our challenge page does not censor this, so please feel free to use it to try to read the side channel provided by the challenge.

Attn @jfparadis @warner @fudco @tribble

As I carry my computer between time zones, is this supposed to dynamically update?

In Chrome, there is such a dynamic update.

@erights THANK YOU that is a brilliant rationale. Finally I understand why this would be a bad thing.


Also we currently allow "SYSTEM" to allow for the current local timezone. Which (in accordance with your arguments) we may want to remove as well, especially in the context of automatic updates.

Yes, although it is less urgent, it would be good to separate access to the current timezone as well, especially one that dynamically updates. That way, access to the allegedly current timezone could be trapped and virtualized, just like all other I/O to the external world.

I think it would be helpful if this virtualizing system were phrased as a staged proposal if champions will be asked to follow it. Currently, it is not clear what conventions to follow.

Can we take this as sort-of agreed? (I'm about to start updating things in advance of the TC39 meeting to reflect the current state)

@pipobscure , I think it's a yes. now will be handled separately out of this proposal. I'll close this issue.

Thanks!

I'm not sure if this is 100% agreed. At the last TC39 meeting, some committee members, including @waldemarhorwat and @domenic, encouraged the proposal to include a now method. Let's continue investigating this question in Stage 2.

I'll mention that @ljharb has an approach that may provide an alternative to the System object, for providing safely injectable sources of authority, including time sources (and weak refs, stack traces, current loader, etc). This is worth exploring, though the System object approach remains cleaner.

It'd be great to see a championed proposal for the System object itself, with an idea to ask the committee for consensus on segregating authority into that object. I don't know if we have committee consensus is one way or another on whether we should go down that route.

We have concluded that there will be a separate "sub-module" exporting something like here() and now().

  • here() would return the System-Timezone
  • now() would return an Instant representing the current time.

So new ZonedDateTime(here(), now()) would be the easy entrance into the current date/time.

Note: because this is a "sub-module" (as in separated out in a way) it can easily be removed/screened in very security conscious environments.

I object to that direction. Like other languages, it should be convenient to create an Instant/ZonedDateTime/etc. in the current time/time zone, with Instant.now()/ZonedDateTime.now()/etc.

I understand that is less convenient for some libraries which want to virtualize time. There is a separate useful discussion to be had as to how to weigh those libraries ease of writing code with the committee's other priorities, such as the language ergonomics goal I am mentioning here. See https://github.com/tc39/proposal-weakrefs/issues/22#issuecomment-485000498.

I also understand the desire for centralized mocking of time. I don't think segregating into modules is helpful for this goal, and I think it might be actively harmful, if people think that by mocking this module, they can mock time effectively. I'd rather see, either as part of this proposal or as a follow-on, investigation into a comprehensive time-mocking library, which would affect the results of both temporal, or of Date, or of host functionality such as those mentioned in https://github.com/sinonjs/lolex#lolex-. In the meantime, I think time-mocking functionality should continue to be done in the usual way, using JavaScript's usual facilities for mocking and virtualization, and libraries (such as Lolex) which build on those.

W have added this as Temporal.getAbsolute()

Was this page helpful?
0 / 5 - 0 ratings

Related issues

felixfbecker picture felixfbecker  路  6Comments

justingrant picture justingrant  路  5Comments

sffc picture sffc  路  3Comments

AlicanC picture AlicanC  路  4Comments

ptomato picture ptomato  路  5Comments