1 of 60

プロトタイプが汚染されたヨ〜😭

これからどうなっちゃうの!?

2 of 60

プロトタイプが汚染されたヨ〜😭

これからどうなっちゃうの!?

はじまるよ〜〜〜〜〜!!!!

3 of 60

自己紹介

  • canalun (@i_am_canalun)
  • elementチーム@テックタッチ

4 of 60

趣味でやっていること

  • DOMDOMタイムス�(zennでやってるよ)
  • TAPL.ts�(TAPLの輪読会)
  • Chromium Contributor

5 of 60

プロトタイプやグローバルの汚染が怖い

当たり前だけど、汚染は怖い

  • コードの振る舞いが完全に予知不可能になる
  • 安全性にも影響を与えてしまう�(極端な例を考えて見るなら、Array.filterをやると勝手にfetchされるとか)

6 of 60

プロトタイプやグローバルの汚染が怖い

当たり前だけど、汚染は怖い

  • コードの振る舞いが完全に予知不可能になる
  • 安全性にも影響を与えてしまう�(極端な例を考えて見るなら、Array.filterをやると勝手にfetchされるとか)

クライアントサイド(3rd party script)も

サーバーサイドも

7 of 60

サードパーティスクリプトって広告以外にもいろいろある

  • 分析ツール
  • SNS連携のボタンだのなんだの
  • チャットボットとかガイダンスを出すとかカスタマーサポート的なツール
  • 決済系のツール

8 of 60

汚染してくるコードは意外とある

グローバル汚染

Zone.js

(Angular

非同期処理

ライブラリ)

9 of 60

汚染してくるコードは意外とある

グローバル汚染

Zone.js

(Angular

非同期処理

ライブラリ)

手がこんでるねえ😇

10 of 60

汚染してくるコードは意外とある

プロトタイプ汚染

有名なSaaSの

OSSライブラリ

11 of 60

汚染してくるコードは意外とある

汚染というか

チェーン差し込み?

どっかのサイト

12 of 60

不要なpolyfill、polyfillのバグ

  • 対応しているはずのブラウザなのにpolyfill(自家製含む)を入れているアプリも多くある(感覚値)
  • かつ、polyfillが正しく動く保証はやはりない
    • 例えばcore-jsのバグで、descriptorのwritableがデフォルトではない値でpolyfillされてlodashが落ちた(修正済み)

13 of 60

不要なpolyfill、polyfillのバグ

  • 対応しているはずのブラウザなのにpolyfill(自家製含む)を入れているアプリも多くある(感覚値)
  • かつ、polyfillが正しく動く保証はやはりない
    • 例えばcore-jsのバグで、descriptorのwritableがデフォルトではない値でpolyfillされてlodashが落ちた(修正済み)

14 of 60

現状の対策: どうにかしてrealmを作る

  • worker
  • webならiframe

15 of 60

iframeの例

16 of 60

それができないこともある

  • worker
    • 基本は非同期が前提になる
    • workerでは使えないAPIがある
  • iframe
    • ページ自体にCSP: sandbox

17 of 60

汚染まわりをECMAScriptはどう思っているんだろう

18 of 60

汚染まわりをECMAScriptはどう思っているんだろう

19 of 60

汚染まわりをECMAScriptはどう思っているんだろう

  • proposalの内容はstage 4になるまで�変わり続けるよ!
  • ここに書いてあるのは�2024年1月下旬時点で調査した内容!

20 of 60

Object.freeze()というものがあるよ

21 of 60

Object.freeze()をやる前

22 of 60

Object.freeze()をやると!!

23 of 60

Object.freeze()をやると!!

上書きできなくなってる!!

いい感じ!

24 of 60

Object.freeze()をやると!!

上書きできなくなってる!!

いい感じ!

25 of 60

でも既に汚れてたらどうする?

既に汚れているものをObject.freeze()

してもしょうがない

26 of 60

👶「もっとすごいのないの〜?」

27 of 60

Secure ECMAScript, Jessie...

28 of 60

Frozen Realmと呼ばれていたやつ

29 of 60

どういう状況なのか?

Kris Kowal

QやCJSを

作ったすごい人

SESまわりで

活躍している

30 of 60

どういう状況なのか?

Secure ECMAScriptは

  • ShadowRealm
  • Compartment
  • Hardened JavaScript

に分解されたよ

31 of 60

どういう状況なのか?

見てみよう

Secure ECMAScriptは

  • ShadowRealm
  • Compartment
  • Hardened JavaScript

に分解されたよ

32 of 60

ShadowRealm

1度目の検索は

絶対に遊戯王のカードにたどり着いてしまう

恐ろしいproposal

33 of 60

ShadowRealmは相当前からある

34 of 60

ShadowRealmができること

  • realmを独立させてそこでコードを実行できる
    • realm = globalThis + built-in objects

(built-in objects = ArrayとかObjectとか。正確にはspecを、ざっくりとはMDNを参照)

  • ライブラリ同士の干渉がなくなる

35 of 60

ShadowRealmのインターフェース

36 of 60

👶「これで全部解決や!!!」

37 of 60

👶「これで全部解決や!!!」

38 of 60

ShadowRealmでは

web APIがほぼ使えない……!

  • ECMAScript的built-inは使える
  • webのAPIのうち何が使えるかは協議中
    • WinterCGのMinimum Common Web Platform API
    • stage 3へ行くための要請

39 of 60

たしかにDOMとか論外だよね

realmの隔離が目的であって、

グローバルに強く結びついたDOMだとかを

ShadowRealmから操作するのは論外

👶「なにか他のものがほしいね」

40 of 60

Compartmentはどうか?

いろいろ制御した

仮想環境を作れる

  • タイムゾーン
  • モジュール

41 of 60

Compartmentはどうか?

いろいろ制御した

仮想環境を作れる

  • タイムゾーン
  • モジュール

と思っていた時代が私にもありました

42 of 60

Compartmentのスコープはモジュールローディングに限定された

43 of 60

Compartmentの現在の内容(stage 1)

  • モジュールを第一級オブジェクトにして、もっと操作可能にしようという提案
  • Module/ModuleSourceなるbuilt-inを導入する
  • モジュールグラフ解析、HMR、非JSモジュール利用の容易化、異なる実行環境の再現ができる
    • 実行環境ごとにモジュール解決の仕組みは違う

44 of 60

冷静に、CompartmentもけっきょくShadowRealmと同じ話になるのでは?

API使えるのかな……

Compartmentもある種globalThisを隔離する

👉 ShadowRealmと同じように省かれるかも?

45 of 60

ではHardened JavaScriptは?

46 of 60

Hardened JavaScriptの概要

  • mutableなbuilt-inの排除
    • built-inを凍結する(frozen built-ins)
  • ambient authorityの排除
    • 各オブジェクトがどんな関数を使っていいのかを制御できる(OCap)

47 of 60

これけっこう安全では?

  • built-inを凍結して
  • 各オブジェクトがどんな関数を使っていいのかを制御できる

👉とにかく安全!

48 of 60

でも冷静に……

Object.freeze()と同じで、

既に汚染されていたら凍らせても、、、ねえ?

それに、Hardened JavaScript上で動くライブラリと動かないライブラリが併存したらどうなるの??

49 of 60

けっきょく……隔離も凍結もむずくない?

  • 隔離する系(ShadowRealm, Compartment)
    • その理念からしてweb APIが使えない
  • 凍結する系(Object.freeze, Hardened JS)
    • 既に汚染されていたら無力なんじゃないか
    • 他のライブラリは汚染「したい」かも

50 of 60

取り出す系はないのか?

51 of 60

proposal-get-intrinsic

52 of 60

proposal-get-intrinsic

53 of 60

proposal-get-intrinsic

👶「任意のタイミングで汚染されていないオリジナルのプロトタイプがとれる!これだ!」

54 of 60

proposal-get-intrinsic

👶「任意のタイミングで汚染されていないオリジナルのプロトタイプがとれる!これだ!」

と思っていた時代が私にもありました

55 of 60

proposalをよく読んでみると

56 of 60

proposalをよく読んでみると

呼び出された時点でのprototypeを

キャッシュして

後続のみんなで取り回す仕組みらしい

だからfirst-run code、

つまり一番最初のコードで呼び出される

想定らしい

57 of 60

proposalをよく読んでみると

呼び出された時点でのprototypeを

キャッシュして

後続のみんなで取り回す仕組みらしい

だからfirst-run code、

つまり一番最初のコードで呼び出される

想定らしい

汚染されてたら、

汚染されたものが取り回されるってワケ

58 of 60

👀「それなにがメリットなんですか?」

59 of 60

まとめ

  • 明るい未来はない
  • CompartmentでAPIが使える可能性に賭ける?
    • でも、stage 1。いつ実現するんだろう?
  • 現時点では、webならiframeでがんばるしかない
    • CSP: sandboxだったら終わるけど
  • オリジナルのprototypeを取り出せる提案をしてみたい。たぶん理由があるんだろうけど

60 of 60

参考にさせて頂いたソース