44
React.js に XSS 対策を 求めるのは間違っている だろうか #edomaesec 2015 5/30 LT

React.js に XSS 対策を求めるのは間違っているだろうか

  • Upload
    ryo-kato

  • View
    5.224

  • Download
    45

Embed Size (px)

Citation preview

Page 1: React.js に XSS 対策を求めるのは間違っているだろうか

React.js に XSS 対策を 求めるのは間違っている

だろうか

#edomaesec 2015 5/30 LT

Page 2: React.js に XSS 対策を求めるのは間違っているだろうか
Page 3: React.js に XSS 対策を求めるのは間違っているだろうか

@clariroid

Page 4: React.js に XSS 対策を求めるのは間違っているだろうか

くらりど

Page 5: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

Page 6: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

Page 7: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

青い紐

Page 8: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

• UI を構築する JavaScript ライブラリ

Page 9: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

• UI を構築する JavaScript ライブラリ

• Virtual DOM

Page 10: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

• UI を構築する JavaScript ライブラリ

• Virtual DOM

• Component Composable

Page 11: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

• UI を構築する JavaScript ライブラリ

• Virtual DOM

• Component Composable

• Server-side Rendering

• etc ...

Page 12: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

• UI を構築する JavaScript ライブラリ

• (省略)

Page 13: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

• UI を構築する JavaScript ライブラリ

• XML like な JavaScript – JSX で記述

Page 14: React.js に XSS 対策を求めるのは間違っているだろうか

React.js – JSX

var str = "Hello, React!";

React.render(

<span>{str}</span>,

document.body

);

Page 15: React.js に XSS 対策を求めるのは間違っているだろうか

React.js – JSX

var str = "Hello, React!";

React.render(

<span>{str}</span>, // js 式は { } で括る

document.body

);

Page 16: React.js に XSS 対策を求めるのは間違っているだろうか

React.js – JSX

• JSX Transformer

• JSX を生の JavaScript に変換

Page 17: React.js に XSS 対策を求めるのは間違っているだろうか

React.js – JSX

var str = "Hello, React!";

React.render(

React.createElement("span", null, str),

document.body

);

Page 18: React.js に XSS 対策を求めるのは間違っているだろうか

React.js – JSX

• 結果として生成される HTML

Page 19: React.js に XSS 対策を求めるのは間違っているだろうか

React.js – JSX

<body>

<span data-reactid=".0">

Hello, React!

</span>

</body>

Page 20: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

• エスケープは自動でしてくれる

• が、React.js が XSS 対策にどこまで責任を負うかは議論となっている

• Issue #3473 “How Much XSS Vulnerability Protection is React Responsible For?”

Page 21: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

• ユーザが入力した文字列から生成した 新しい DOM node を挿入したい

• Ex.) Markdown から変換された文字列

Page 22: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

```Markdown

** edomaesec! **

```HTML

<em>edomaesec!</em>

Page 23: React.js に XSS 対策を求めるのは間違っているだろうか

React.js

• 直に innerHTML を叩くと怒られる

• React 版 innerHTML

• dangerouslySetInnerHTML API の利用

Page 24: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

Page 25: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

• 公式の Tutorial でも Backdoor な API として 使っている

• こんな風に使う

Page 26: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

var str = "<em>edomaesec!</em>";

var obj = { __html: str };

React.render(

<span dangerouslySetInnerHTML={obj}/>,

document.body

);

Page 27: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

var str = "<em>edomaesec!</em>";

var obj = { __html: str };

React.render(

<span dangerouslySetInnerHTML={obj}/>,

document.body

);

Page 28: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

• 公式の docs より抜粋・翻訳

-- 不安を感じる言葉で意図的に名付けました。 -- プロパティ値はサニタイズされたデータを示す -- ために使われることでしょう。

Page 29: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

• どれほど dangerously なのか分からない

• ソースコードを追ってみた

• react.js v0.13.3 ( 全19602行 )

• デバッガ使いましょう

Page 30: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

var str = "<em>edomaesec!</em>";

var obj = { __html: str };

React.render(

<span dangerouslySetInnerHTML={obj}/>,

document.body

);

Page 31: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

var str = "<em>edomaesec!</em>";

var obj = { __html: str };

React.render(

React.createElement(

"span", {dangerouslySetInnerHTML: obj}

), document.body

);

Page 32: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

• L: 9928 ReactElement

{ key: “span”,

_store: {

props: {

dangerouslySetInnerHTML: { __html: str }

}

}

}

Page 33: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

• ( DOM更新のトランザクションを開くコードが永遠と続くので中略)

Page 34: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

• L: 7641 mountComponent

return

_createOpenTagMarkupAndPutListeners

+ _createContentMarkup

+ closeTag

Page 35: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

• L: 7641 mountComponent

return

_createOpenTagMarkupAndPutListeners

+ _createContentMarkup

+ </span>

Page 36: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

• L: 7664 _createOpenTagMarkupAndPut…

return

<span date-reactid=".0">

+ _createContentMarkup

+ </span>

Page 37: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

• L: 7641

return

<span date-reactid=".0">

+ _createContentMarkup

+ </span>

Page 38: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

• L: 7711 _createContentMarkup

var innerHTML

= props.dangerouslySetInnerHTML;

return "" + innerHTML.__html;

• __html の内容について何も確認なし

Page 39: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

• L: 7641

return

<span date-reactid=".0">

+ <em>edomaesec!</em>

+ </span>

Page 40: React.js に XSS 対策を求めるのは間違っているだろうか

dangerouslySetInnerHTML

• L: 18971 setInnerHTML

node.innerHTML = html;

// html 先程 return された文字列

Page 41: React.js に XSS 対策を求めるのは間違っているだろうか

Demo

• str = "<input autofocus onfocus=alert(1)>" を代入してみる

Page 42: React.js に XSS 対策を求めるのは間違っているだろうか

まとめ

• React.js の dangerouslySetInnerHTML API は 通常の innerHTML 挿入と等価である

• 使わないようにリスク回避で設計したい

• dangerouslySetInnerHTML を利用する際は エスケープ(場合によってはサニタイズ)した文字列を代入させる

Page 43: React.js に XSS 対策を求めるのは間違っているだろうか

まとめ

サニタイズって簡単に言うけれども…

• RickDOM の使用

• marked.js の sanitize parameter を true にする ( Markdown のみ)

• HTML5 sandboxed iframe で wrap しておく ( js の実行を抑制 )

Page 44: React.js に XSS 対策を求めるのは間違っているだろうか

参考資料

• Dangerously Set innerHTML | React – e10s https://facebook.github.io/react/tips/dangerously-set-inner-html.html

• Yosuke Hasegawa『文字列から HTML を組み立てる話』@Shibuya.XSS techtalk #5 http://utf-8.jp/public/20140807/shibuyaxss.pdf