tame Intl as a shim
add a switch to allow locale-based nondeterminism
MODIFY
src/bundle/createSES.js
src/bundle/createSES.js
import tameDate from './tame-date.js';
import tameMath from './tame-math.js';
+import tameIntl from './tame-intl.js';
export function createSESWithRealmConstructor(creatorStrings, Realm) {
function makeSESRootRealm(options) {
@@ -31,6 +32,10 @@ export function createSESWithRealmConstructor(creatorStrings, Realm) {
shims.push(`(${tameMath})();`);
}
+ if (options.intlMode !== "allow") {
+ shims.push(`(${tameIntl})();`);
+ }
+
const r = Realm.makeRootRealm({shims: shims});
const b = r.evaluate(creatorStrings);
b.createSESInThisRealm(r.global, creatorStrings, r);

ADD
src/bundle/tame-intl.js
+/* global Intl */
+
+export default function tameIntl() {
+ // todo: somehow fix these. These almost certainly don't enable the reading
+ // of side-channels, but we want things to be deterministic across
+ // runtimes. Best bet is to just disallow calling these functions without
+ // an explicit locale name.
+ Intl.DateTimeFormat = () => { throw Error("disabled"); };
+ Intl.NumberFormat = () => { throw Error("disabled"); };
+ Intl.getCanonicalLocales = () => { throw Error("disabled"); };
+ Object.prototype.toLocaleString = () => {
+ throw new Error('toLocaleString suppressed');
+ };
+}

MODIFY
src/bundle/tame.js
src/bundle/tame.js
// See the License for the specific language governing permissions and
// limitations under the License.
-function tameIntl(global) {
- // todo: somehow fix these. These almost certainly don't enable the reading
- // of side-channels, but we want things to be deterministic across
- // runtimes.
- global.Intl.DateTimeFormat = () => 0;
- global.Intl.NumberFormat = () => 0;
- global.Intl.getCanonicalLocales = () => [];
- global.Object.prototype.toLocaleString = () => {
- throw new Error('toLocaleString suppressed');
- };
-}
-
function tameError(global) {
Object.defineProperty(global.Error.prototype, "stack",
{ get() { return 'stack suppressed'; } });
}
export function tamePrimordials(global, options) {
- tameIntl(global);
tameError(global);
}

ADD
test/test-intl.js
+import test from 'tape';
+import SES from '../src/index.js';
+
+test('Intl neutered by default', function(t) {
+ const s = SES.makeSESRootRealm();
+ t.throws(() => s.evaluate('Intl.DateTimeFormat()'), Error);
+ t.throws(() => s.evaluate('Intl.NumberFormat()'), Error);
+ t.throws(() => s.evaluate('Intl.getCanonicalLocales()'), Error);
+ t.throws(() => s.evaluate('({}).toLocaleString()'), Error);
+ t.end();
+});
+
+test('Math.random neutered upon request', function(t) {
+ const s = SES.makeSESRootRealm({mathRandomMode: false});
+ t.throws(() => s.evaluate('Intl.DateTimeFormat()'), Error);
+ t.throws(() => s.evaluate('Intl.NumberFormat()'), Error);
+ t.throws(() => s.evaluate('Intl.getCanonicalLocales()'), Error);
+ t.throws(() => s.evaluate('({}).toLocaleString()'), Error);
+ t.end();
+});
+
+test('Intl can be left alone', function(t) {
+ const s = SES.makeSESRootRealm({intlMode: "allow"});
+ // All we test is that these don't throw exceptions. The exact output will
+ // depend upon the locale in which we run the tests.
+ s.evaluate('Intl.DateTimeFormat().format(1234)');
+ s.evaluate('Intl.NumberFormat().format(1234)');
+ s.evaluate('Intl.getCanonicalLocales()');
+ s.evaluate('({}).toLocaleString()');
+ t.end();
+});

tame Intl as a shim

add a switch to allow locale-based nondeterminism