OWASP Night 2019-03-11 / OWASP Japan
2019-03-11 OWASP NightNode.js セキュリティOWASP Kansai チャプターリーダーはせがわようすけ
View Slide
長谷川陽介 (はせがわようすけ)(株)セキュアスカイ・テクノロジー 取締役CTO[email protected]http://utf-8/jp/千葉大学 非常勤講師OWASP Kansai チャプターリーダーOWASP Japan ボードメンバーCODE BLUEカンファレンス レビューボードメンバー
OWASP Night / 2019-03-11 #owaspjapantOWASP Kansai Chapter自分たちの直面するWebセキュリティの問題を自分たちの手で解決したい!日本で2番目の OWASP Local Chapter2014年3月から 京都・大阪・神戸・奈良 でLocal Chapter Meeting (勉強会) を開催Webセキュリティの悩み事を気楽に相談し情報共有できる場 スキル、役職、業種、国籍、性別、年齢に関係なし
OWASP Night / 2019-03-11 #owaspjapant今日のテーマ「Node.jsなWebアプリのセキュリティ」
OWASP Night / 2019-03-11 #owaspjapantNode.jsなWebアプリのセキュリティ普通のWebアプリと同様の対策 SQLi対策、XSS対策、CSRF対策、SSRF対策…Node.js特有の問題点への対策 同期処理によるブロック prototype汚染Node.jsのコーディング、運用上の配慮 eslint使おう npm outdated / npm auditでモジュールの更新管理
OWASP Night / 2019-03-11 #owaspjapantNode.jsなWebアプリのセキュリティ普通のWebアプリと同様の対策 SQLi対策、XSS対策、CSRF対策…Node.js特有の問題点への対策 同期処理によるブロック prototype汚染Node.jsのコーディング、運用上の配慮 eslint使おう npm outdated / npm auditでモジュールの更新管理今日はここの話
OWASP Night / 2019-03-11 #owaspjapant同期処理によるブロック
OWASP Night / 2019-03-11 #owaspjapant同期処理によるブロックNode.jsは非同期型のイベント駆動 イベントループにてイベントの発生を継続的に監視 I/Oなどは非同期に実行されるイベントループが停止するとアプリケーション全体が止まる イベントループを止めないよう各処理は速やかに処理を終えるか非同期に実行する必要がある出力よろしく!入力きた?コールバック関数出力終わった?きたよ!libuv / OSまだだよ!Node.js イベントループまかせろ!
OWASP Night / 2019-03-11 #owaspjapant同期処理によるブロックイベントループが止まるとアプリケーション全体が止まる CPUのみで行う処理などは同期的に実行され他のイベントが実行されない 膨大な計算処理、時間のかかる正規表現、巨大な配列の処理、JSON.parseなど攻撃者が意図的にそのような状況を作り出すことができるとDoSを発生させられる出力よろしく!入力きた?コールバック関数出力終わった?きたよ!libuv / OSまだだよ!Node.js イベントループまかせろ!
OWASP Night / 2019-03-11 #owaspjapant同期処理によるブロック - ReDoS正規表現によるDoS (ReDoS)正規表現のパターンによっては内部的に膨大な照合処理が行われる意図的にこの状態を攻撃者が作り出すことでパフォーマンスが低下するconst re = /([a-z]+)+$/;re.test('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!'); //秒単位で処理時間がかかるhttps://gist.github.com/watson/7682ee718b9cf4aa2a5a605a3fb4a552 より
OWASP Night / 2019-03-11 #owaspjapant同期処理によるブロック - ReDoS対策量指定子の回数を制限する「+」や 「*」 ではなく 「{0,20}」 などsafe-regexモジュールなどを用いて事前にパターンの検査を行う正規表現を使わなくていい箇所では使わないString.prototype.includes や String.prototype.startWith などを使用
OWASP Night / 2019-03-11 #owaspjapant同期処理によるブロック - JSON.parseJSON.parseは同期的に処理され、パース中は他のイベント処理は実行されない巨大な文字列のJSON.parseはアプリケーション全体をブロックさせる可能性があるconst text = req.body.param;const obj = JSON.parse(text); // パースが完了するまで処理がブロック
OWASP Night / 2019-03-11 #owaspjapant同期処理によるブロック - JSON.parse対策JSON.parseの前にテキストのサイズを確認asyncなJSONパーサーの導入 使ったことがないので何とも言えず… 他のライブラリで内部的にJSON.parseが呼び出されている場合には対応できないconst text = req.body.param;// サイズが4k以下の時だけJSON.parseするif (typeof text === 'string' && text.length < 4096) {const obj = JSON.parse(text);}
OWASP Night / 2019-03-11 #owaspjapant同期処理によるブロック - JSON.stringifyJSON.stringifyでも同じことはあり得る 巨大な配列を含むJSONをシリアライズするときにブロック等参考:https://techblog.yahoo.co.jp/advent-calendar-2018/goodbye-mym/#uopoo配列を含むJSONをstringifyするときは事前に配列の長さを確認function foo (obj) {let text = {};// 配列の長さが1k以下の時だけJSON.stringifyするif (obj.items instaneof Array && obj.items.length < 1024) {text = JSON.stringify(obj);}...}
OWASP Night / 2019-03-11 #owaspjapantprototype汚染
OWASP Night / 2019-03-11 #owaspjapantprototype汚染__proto__経由でObject.prototypeが汚染されてしまう問題 prototype.js時代のprototype汚染とは異なる あれは意図的にObject.prototypeに便利メソッドを追加しているが迷惑だという問題攻撃者が__proto__プロパティを宣言することでグローバルのObject.prototypeeを汚染する 存在しないはずのプロパティが全オブジェクトに存在してしまう
OWASP Night / 2019-03-11 #owaspjapantprototype汚染オブジェクトリテラルの__proto__がObject.prototypeを指しているため、攻撃者が__proto__に書き込みできる場合、グローバルのObject.prototypeが汚染される valueOf()やtoString()などの既存プロパティも書き換えられ、最悪の場合は任意コード実行となるfunction isObject(obj) {return obj !== null && typeof obj === 'object';}function merge(a, b) {for (const key in b) {if (isObject(a[key]) && isObject(b[key])) {merge(a[key], b[key]);} else {a[key] = b[key];}}return a;}function clone(obj) {return merge({}, obj);}app.post('/', (req, res) => {const obj = clone(req.body);const r = {};const status = r.status ? r.status: 'NG';res.send(status)});% curl -H 'Content-Type:application/json' -d '{"__proto__":{"status":"polluted"}}' http://example.jp/https://jovi0608.hatenablog.com/entry/2018/10/19/083725 より攻撃者の作成したJSONをそのままコピーしているため __proto__ もコピーされる攻撃者が送信するJSON。レスポンスは "polluted" になるObject.prototypeが汚染されているので、無関係なオブジェクト r の status プロパティが意図しない値となる
OWASP Night / 2019-03-11 #owaspjapantprototype汚染 - 対策外部からのJSONには__proto__のように動作に影響をあたえるキーが含まれている可能性がある 外部からのJSONのキーを列挙してそのまま使用しない キー名が想定されているものか確認する 最低限、キーを列挙する際には __proto__ を除外するfunction merge(a, b) {for (const key in b) {if (key === "__proto__") continue;if (isObject(a[key]) && isObject(b[key])) {merge(a[key], b[key]);} else {a[key] = b[key];}}return a;}
OWASP Night / 2019-03-11 #owaspjapantprototype汚染 - 他の対策方法 オブジェクトリテラル「{}」ではなくObject.create(null)を使う prototypeがnullのオブジェクトが生成される ただしprototypeチェインがたどれなくなるので、hasOwnPropertyなどが直接は呼び出せなくなる Object.freezeを用いてObject本体およびObject.prototypeを凍結する 副作用で動かなくなるモジュールが発生する可能性がある JSON Schemaなどを用いて入力をより厳密に検証する 入力されるJSONのキー名や型などを厳密に検証する ObjectではなくMapを使う 外部からのデータはObjectではなくMapに格納して使用する MapからObjectへコピーする際には__proto__をコピーしないよう注意が必要参考: https://techblog.securesky-tech.com/entry/2018/10/31/
OWASP Night / 2019-03-11 #owaspjapant質問?[email protected]@hasegawayosukehttp://utf-8.jp/