DOMPurifyを使って、kintone で安全にDOMをエスケープしよう!
はじめに
kintone は、カスタマイズによってレコードの表示方法を変更できるため非常に便利です。
レコードに入力されたマークアップテキストやマークダウンテキストを解析して表示できます。
しかし、セキュリティ面を意識しないと、悪意を持ったユーザーからサイバー攻撃を受ける可能性があります。
今回は kintone アプリで想定されるサイバー攻撃の例と、
DOMPurify
を使った対策を紹介します。
DOMPurify は Cybozu CDN にてサポートされているので利用してください。
DOMPurifyのメリット
単純に正規表現で置き換えたりしようとすると回避されて XSS を埋め込まれる可能性があります。
innerHTML
や jQuery の html()
などで出力する前に DOMPurify.sanitize()
しておくことで、より安全に HTML タグを許容できます。
kintone セキュアコーディングガイドライン でも、出力するすべての要素に対してエスケープ処理を施すことを推奨しています。
やむを得ず innerHTML を使う場合は、DOMPurify のような対策が有効です。
サイバー攻撃の例
ここでは、セキュリティ脆弱性を含んだアプリとそのアプリへのサイバー攻撃の例を紹介します。
セキュリティ脆弱性を含んだアプリ
サンプルとして、マークダウンフィールドの内容をコンバートして表示するアプリを用意しました。
フォーム設定
フィールド名 | フィールドタイプ | フィールドコード |
---|---|---|
マークダウン |
文字列(複数行) |
マークダウン |
スペース |
preview |
フォーム画面
JavaScriptカスタマイズ
sample.js として次のプログラムをアプリに適用します。
|
|
JavaScript ライブラリの
jQuery
および
Marked.js
を利用しています。
お試しの場合は、
Cybozu CDN から利用してください。
動作
詳細画面を開くと、コンバートされたマークダウンフィールドの内容が preview スペースに表示されます。
サイバー攻撃
上記アプリで、悪意のあるユーザーにより文字列(複数行)フィールドに次の内容が登録されたとします。
|
|
レコードの削除権限を持った別のユーザーが、このレコードの詳細画面を開くと、アプリ内のレコードが全件削除されてしまいました。
このようにセキュリティ脆弱性を含むアプリでは、悪意のあるユーザー自身がレコードの削除権限を持っていないとしても、間接的にレコードを全件削除できます。
同様に、閲覧権限のないレコードを盗み出すことなどもできてしまいます。
注意事項
- 当アプリはサイバー攻撃の一例として意図的にカスタマイズしたものです。
セキュリティリスクがあるため、DOMPurify のようなセキュリティ対策なしに使うことはお控えください。 - 検証環境でのみお試しください。 万一データが損失した場合、サイボウズは責任を負いません。
対策
上記の対策として DOMPurify を使います。
DOMPurify.sanitize()
を用いると、コード内の危険性のある箇所(<script>
タグ等)を除去してくれます。
DOMPurifyの利用例
HTML を埋め込んでいる箇所に対して DOMPurify.sanitize()
します。
|
|
alert("アラート");
が除去されていることが確認できます。
さきほどの sample.js に DOMPurify.sanitize()
を実装した場合はこちらになります。
|
|
動作確認
先ほどはすべてのレコードが削除されてしまいしたが、DOMPurify.sanitize()
することで、
マークダウンの表示をしつつ全件削除の攻撃を防ぐようになりました。
最後に
セキュリティを意識せずに、ユーザーが入力したコードを表示するのは非常に危険です。
今回は「サイバー攻撃」という想定で書きましたが、意図しない「うっかり」でも同様の危険を含みます。
このような場合に備えてあらかじめ DOMPurify でエスケープすることで、より安全に DOM を扱うことができます。
主要ブラウザーでは、innerHTML を用いて DOM を追加した場合には <script>
タグの中身を実行しません。
しかし念のため、出力前に DOMPurify.sanitize()
しておくことをおすすめします。
この Tips は、2018 年 6 月版 kintone で動作を確認しています。