安全なWebアプリケーションの作り方
22.5月に諦めたけど24.3月にもう一度チャレンジ
1週目はさくっと読み進めることを前提に考える。
1 Webアプリの脆弱性
脆弱性とは悪用できるバグのこと。
個人情報の閲覧やwebサイトの書き換え、ウイルス感染などなど。
脆弱性はwebアプリケーション開発者にとっては身近なもの
脆弱性があるとなぜダメなのか
経済的損失
利用者が受けた金銭の補填、webサイトの機会損失、信頼性の低下による売り上げ減少など
法的な要求
個人情報保護法(個人情報を取り扱う事業者は、データの漏洩や安全管理に必要な措置を講じなければならない)
その他ガイドラインにも、情報システムの設計時に安全性を確保し継続的に見直す必要があると記述がある
利用者の心的不安
webサイト利用者に嘘をつくことになる(安全ですよと言っているのにも関わらず、ということになる)
攻撃インフラ構築に加担してしまう
botネットワーク
bot
マルウェア(不正プログラム)に1種で、PC感染後は外部からの指令を受けてメール送信やDDoS攻撃に加担させるような挙動を取らせるのが一般的
古典的だが、現在でも新たな手口が発見されている
webサーバーを攻撃し、そのサーバにアクセスした利用者の端末に感染させ、利用者の端末がメールやDDoSに加担
この感染した端末が集まるネットワークがbotネットワーク
攻撃者の大きな収入源になっていると言われている(反社会的な勢力への加担)
なぜ脆弱性が生まれるか
バグ
SQLインジェクション、XSSなどの原因になる
チェック機能の不足によるもの
ディレクトリ・トラバーサル脆弱性など
セキュリティ上のチェックが必要という意識がチーム内で薄い場合に発生する
セキュリティバグとセキュリティ機能
セキュリティを確保するためには、バグをなくすだけでは不十分
これがセキュリティバグ
HTTPをHTTPSにして暗号化するように、積極的に安全性を強化することが大事
これがセキュリティ機能の確保
バグを無くすのも、セキュリティ機能を使って安全性を強化することも大事
2 環境構築
割愛
3 webセキュリティの基礎
HTTPとセッション管理
ブラウザからHTTPリクエストを送り、サーバがHTTPレスポンスを返す
HTTPリクエスト
リクエストメッセージ
1行目がリクエストラインと呼ばれ、サーバーに対する命令を指す。
URLやメソッド、プロトコルバージョン(HTTP/1.1とか)を送る
2行目以降がヘッダ。ポート番号とかホストとか。
レスポンスメッセージ
ステータスライン
HTTP/1.1 200 OKとかサーバーから返るメッセージ。
レスポンスヘッダ
Content-Typeとか色々なヘッダの情報。
POSTで情報を送る場合
GETとは異なり、リクエストメッセージに入力された値(メッセージボディ)が付属されている
ボディのバイト数とか色々。
パーセントエンコーディング
URL上の%xxとかそういうもの。URL上で特別な意味を持つ文字をURL上に違う形に記述すること。
Referer(リファラ)
リンク元のURLを示すヘッダ。formでの送信とかaタグの遷移などでも付属する
セキュリティの役に立つ場合もあれば、不要な場合もある
リファラを確認することでアプリが意図した遷移を経ているかどうかの確認ができる。
ただし改竄されることもあるので信頼しすぎも注意
URLに機密情報を含めた場合、リファラから追えるので脆弱性に繋がることがある。
GETとPOSTの使い分け
code:RFC7321
GETは参照(取得)のみに用いる
GETは副作用がないことが期待される
秘密情報の送信にはPOSTを用いること
副作用とは
リソースの取得以外の作用のこと
データの追加・更新・削除が起きる作用のこと。つまりこれはPOSTを使わなければならない。
なぜGETではダメか
URL上に指定されたパラメータがリファラ経由で漏洩する
URL上に指定されたパラメータがアクセスログにのこる
URLはブラウザに記述されるので、他人に覗かれて漏洩するかもしれない
パラメータ付きのURLがSNSなどで共有される可能性がある
hiddenパラメーターについて
htmlソース上に記入される
http上ではこれらのパラメーターについて、利用者が書き換えができる
hiddenを処理する部分に脆弱性があると、攻撃されてしまう
それでも使うメリット
利用者自身からは書き換えできるが、第三者からは堅牢である
利用者自身によっても書き換えられたくない情報はセッション変数に格納すると良い。
それ以外はhiddenに保存することを検討する。
ログイン前の情報など。
ステートレスなHTTP認証
いわゆるBasic認証
ステートレス
クライアントの現在の状態を覚えておく設計になっていないこと
理屈
認証が必要なページにリクエストがあると、一旦401を返す
これを受けてブラウザがIDとパスワードの入力画面を表示し、その情報をサーバーに送信する
これがAuthorizationヘッダ
一度成功すると、その後はブラウザが自動的にAuthorizationヘッダをつけてくれる
接続するたびにIDとパスワードが送出されていて、情報はどこにも保存されていない
ステートレスであると言える
クッキーとセッション管理
HTTPはステートレスだが、それでもアプリケーションでは状態を保持したい場合がある
ログインしたかどうかとか、ショッピングカートの状況とか
アプリケーションの状態を覚えておくことを、セッション管理と呼ぶ
セッション管理をHTTPで実現する目的でcookieが導入された。
cookieをセットすると
レスポンスヘッダにSet-Cookieというレスポンスが記載される
webサーバーがブラウザに対して、クッキーの値を覚えるように指示している
クッキーを覚えたブラウザは同じサイト(example.com)にリクエストを送る場合、そのクッキーの値を送信する
クッキーには期限が存在する。指定のない場合はブラウザを終了させるまで有効
セッションID
セッション情報にアクセスするための情報
session_start()などでセッション開始時にこの値を参考にして、情報を取り出す。
クッキーはアプリケーションに関するデータの保持の役割として使えるか?
厳しい。保持できる値の個数などに制限があり、また値も参照・変更ができてしまうので。
クッキーには整理番号のような形でセッションIDを持たせ、サーバから値を参照させるケースが一般的
ID:5の人→emailとpasswordは...みたいな感じ
セッションIDが持つべき2つの要件
セッションIDは推測できないようにする
セッションIDが単純なものであった場合、改竄できると他の人のデータを見れてしまう
なのでPHPでは26桁の文字列などでうまく調整されている
無理に自作せず、メジャーな開発ツールで用意されたものを使うべき
セッションIDを強制・固定化させないこと
誰かがセッションIDと合わせて本人確認し、認証を突破する
その通信を奪ってしまえば、あとは攻撃者に操作ができてしまう
なので認証を突破した後などには、新しくIDを発行してやる
セッションIDを漏洩させないこと
公衆環境などのネットワーク経路に気をつける。
クッキーの属性
Domain: ブラウザがクッキー値を送信するサーバのドメイン
指定すると同じドメインを持つサーバにクッキーを送出できる
Path: ブラウザが値を送信するURLのディレクトリ
Expires: 期限。指定のない場合はブラウザ終了まで
Secure: httpsの場合のみクッキーを送信する。
指定がない場合は、常にサーバーに送信される形になる
HttpOnly: この属性が指定されたクッキーはJSからアクセスができなくなる。
クッキーからセッションIDを抜き出す攻撃が、いわゆるクロスサイトスクリプティング(XSS)
この属性をつけておくとXSS対策となる
能動的攻撃
攻撃者がwebサーバーを攻撃すること。SQLインジェクションなど
受動的攻撃
webサイトの利用者に罠を仕掛けることで、閲覧したユーザーがアプリに対して攻撃するようになる
種類
怪しいサイト(罠サイト)を設置してマルウェアに感染させ攻撃者が操作できるようにする
正規サイトに攻撃し仕掛けを仕込み、それにユーザーが閲覧すると感染する
罠サイトを閲覧し、罠サイトから仕掛けを仕込んだHTMLがダウンロードされる。それが発動し正規サイトへ攻撃のリクエストが開始され、正規サイトからjsなどの仕掛けを含むレスポンスが返る
手間だが、ユーザーが認証など終わっていた場合、ログインした状態で攻撃ができる
CSRF, XSSなどが該当する
ブラウザ側の対策
web(開発者側)でいくら対策しても、ユーザーの使うブラウザが脆弱であれば意味がない
サンドボックスの保有
プログラムのできることを制限する環境の実現
jsが悪意を持った操作をしようとしても、ある程度であればブラウザが制限してくれる
同一オリジンポリシー
サンドボックスが持つ、クロスドメインアクセスの防止機能
jsなどのクライアントスクリプトから、サイトを跨ったアクセスを禁止する機能
サイトA(iframeでサイトBが写ってる)
サイトAのjsで、サイトBに入力した情報を取得しようとしたりするイメージ
同一かどうかはURLのホストやプロトコル、ポート番号などから判断される
CORS(Cross-Origin Resource Sharing)
jsが流行り、同一オリジンポリシーの制限を超えてサイト間でデータをやり取りしたいというニーズが強くなった
それを実現するための仕様がCORS
条件
シンプルなリクエストであること
提供元がAccess-Control-Allow-Originというタグをつけておく
それに対応させると、異なるオリジンからのレスポンスをjsで参照できるようになる
GET/HED/POSTのいずれかであること
その他、ヘッダが指定のものであること
シンプルでない場合は、プリフライトリクエストというものがブラウザで発行され、サーバーに送られる
そちらで追加されたヘッダにサーバー側が答えられる処理を持っていれば参照できる
認証情報を含むリクエストの場合
XMLHttpRequestプロパティのwithCredentialsをtrueとすることで実現ができる
要するに
複数のオリジンにまたがってクッキーなどの情報を共有したい場合、CORSを考慮して設計すれば実現できるということ
4 webアプリの機能別に見るセキュリティバグ
脆弱性はどこで発生するのか
古典的な「入力→処理→出力」という形に分けると、
HTMLの出力(XSS)
HTTPヘッダの出力(HTTPヘッダ・インジェクション)
SQLの発行(SQLインジェクション)
シェルコマンドの呼び出し(OSコマンド・インジェクション)
メールヘッダおよび本文の出力(メールヘッダ・インジェクション)など
上記からわかること
脆弱性には、処理に起因するものと出力に起因するものがある
入力に起因する脆弱性は基本的に少ない
出力に起因する脆弱性は「インジェクション」と命名される(injection:注入する)
XSSも、HTMLインジェクション / JSインジェクションと呼ばれるケースがある
インジェクション系脆弱性
webアプリではテキスト形式のインターフェースを多用する
HTML, HTTP, SQLなど
これらは決められた文法により構成される。
code:php
SELECT * FROM users WHERE id = '$id';
ただし、$id=';DELETE FROM users --'という値が渡された場合、データに被害が出る
これがSQLインジェクションの例
基本的に、データを想定している部分にデリミタなどを使って処理を終わらせ、その後の文字列構造を変化させること。
インジェクション系の脆弱性はこのケースであることが殆ど。
入力処理とセキュリティ
webアプリケーションにおける「入力」について
HTTPリクエストとして渡される、GETやcookieなどのパラメータが入力処理
入力処理 = アプリケーションロジックの処理が始まる前のデータ準備段階のこと
入力処理でやること
文字エンコーディングの妥当性検証
入り口で弾いておけば、不正な文字エンコーディングを使った攻撃を防止できる
(必要ならば)文字エンコーディングの変換
入力値の妥当性検証
アプリケーションが想定した値を入れてもらえるように調整する
なぜ入力値にバリデーションをかけるのか
特定の文字(数字だけとか)を受け付ける項目に記号などが入ると、DBのエラーに繋がる
更新処理が途中でエラーとなり、DBの不整合が発生する可能性がある
利用者が多数入力後にエラーになると、二度手間になる
メールアドレスの入力を忘れているのに、アプリケーションがメール送信処理を実行しようとしてしまうなどを防ぐ
→ユーザビリティ、信頼性が上がる。
→セキュリティ対策が漏れていても、そもそも入力できなくて実害に繋がらないケースもある。
入力処理:その他について
webアプリケーションの入り口でエンコーディング検証・入力値の検証はセーフティネットとして動作する。
表示処理に伴う問題
表示処理が原因で発生するセキュリティ問題
クロスサイト・スクリプティング
エラーメッセージからの情報漏洩
クロスサイト・スクリプティング(XSS / Cross-Site Scripting)
webアプリには外部入力に応じて表示が変化する場所が存在する
この部分のHTML生成の実装に問題があると脆弱性へと発展してしまう
XSSが起こると
サイト利用者のブラウザ上で、攻撃者の用意したスクリプトが実行されクッキーなどの値が盗まれる
なりすまし被害に遭うかも
管理者がスクリプトの被害を受けると、webアプリケーションの機能を悪用される可能性も
webサイト上に入力フォームが偽装で作られ、フィッシングにより利用者が個人情報を盗まれる
基本的な対策
HTMLで特殊な意味を持つ記号の文字メタ文字をエスケープすること。
PHPではhtmlspecialchars()などが有名。
クッキーの値の盗み出し手法の例
検索機能のあるサイトで、検索結果がパラメータで渡されてそれが画面に出る時の例
test.com?keyword=テストみたいな感じで
これをtest.com?keyword=<script>....</script>ということができてしまった場合
scriptが画面に表示され、それが実行されてしまう
そのほかの例
ワーム(単独で行動が起こるマルウェアの総称)などでの攻撃
APIが用意されているwebサイトに対して、APIに向かって攻撃
ログイン機能のないサイトの悪用例
何か色々情報を記入してformで送れるサイトがあったとする
入力画面、編集画面を兼ねている
input value="<?php echo @_POST['name']; ?>"みたいな作りになっている
別の偽装サイトで、nameというinputの値にスクリプトなどを入れて元ページのformのmethod先にpostさせる
編集画面を表示させると画面に表示させることができる
脆弱性が生まれる原因
HTMLの文法上特別な意味を持つメタもじをエスケープしていないから。
<を<と変えるなど。
<などの値を悪用する攻撃がXSS。
対策
<や&はエスケープしよう
属性値(value="1"でいう、1という値のこと)はダブルクォートで囲って、エスケープする
シングルよりもダブルクォートで囲った方がセキュリティ的に都合が良いらしい。詳しくは調べる。
cookieが読まれたくないのであれば、HttpOnly属性を付与する
XSSの発展的な攻撃手法などについて
href属性に値を入れる
<a href="<? $_GET['url']>">というものがあり、そこにjavascript:alertなどを格納できる
対策としては、httpかhttpsからしか始まるものしか入れられないようにするなど。
エラーメッセージからの漏洩
エラーを起こしている関数名、テーブル名などが露出するケースがある。
ちゃんとデバッグモードなどを有効にしておこう
その他は一旦省く
SQL呼び出しに伴う脆弱性
SQLインジェクション
クエリの呼び方に不備がある場合に発生する
DB内の情報が盗まれる、改竄、認証の回避など影響が非常に多い
対策としては、静的プレースホルダを利用してSQLを呼び出すことが一番。
攻撃手法のイメージ
select * from books where author = $idというクエリがあったとする
$idはgetパラメーターなどのクエリ。ここにSQL文を入れて漏洩させるイメージ
この中にselect id, password from users的な意味合いのものを仕込んでうまいこと出させるようにする
UNIONなどで攻撃されると一度の攻撃で多くのデータが露出する。
認証回避について
password = $pというクエリがあったとして
$p = '' OR 'a' = 'a'みたいな感じで書いておくと、aを入れるだけで入れるようになる
UPDATEを使ってのデータ改竄
OSコマンドを使ってのファイル構造呼び出しなど
mysqlの拡張機能で、ファイル構造などを呼べる機能がある。
そういうものが入っていたらsqlで操作してファイル構造なども把握できてしまう
なぜ生まれるか
リテラル(決まった値)の問題
文字列を囲むときとか、数字をSQL内に書くときのルールのようなもの
その時のルールを悪用しているものがほとんど。
静的プレースホルダによる対策
placeholder(場所取り)
Laravelなどでもよく見る、?で定義する書き方のこと。?がプレースホルダ。
phpではPDO(PHP Data Objects)などを使って、プレースホルダに変数を割り当てていく(これをバインドという)
効果的である
静的プレースホルダと動的プレースホルダ
静的
値のバインドをDB側で行う。
?の含まれた文章がDBエンジンへ送られ、コンパイルしてSQLが確定する
次にバインドの値がDBエンジンに送られ、エンジン側で値をはめた後にSQLが実行される
動的
パラメータを割り当ててからDBへ行う。
できるだけ使わない方が良い。
その他の対策
詳細なエラーメッセージを抑止する
入力値の妥当性を検証する
データベースの権限設定をする
商品を表示させるだけのアプリなら、書き込み権限は必要ないので取り外すなど。
重要な処理の際に混入する脆弱性
例えば、カード決済、口座からの送金、パスワードやメールアドレスの変更など。
その際に起こりうるのがCSRFである
CSRF
重要な処理を受け付ける際は、必ず利用者の意図したリクエストであることを確認すべきである
この確認処理が抜けていると、罠サイト閲覧→利用者のブラウザで重要な処理を実行させるという動きを実現できる
これがCSRF。
CSRFが起こると
利用者アカウントでの物品購入、退会処理などができる
アプリケーションの悪用が主であり、個人情報を盗むことなどはそこまでない。
攻撃手法のイメージ
パスワード変更画面などが例
ログインし、POSTで変更後のパスワードを記入、アクセス後に更新されるページがあるとする
攻撃用のサイトに、formなどで攻撃者が指定したパスワードをPOSTで送るような処理を書く
ログインした状態で攻撃者のサイトを覗き、submitしてしまうと攻撃者が指定したパスワードに切り替わってしまう
なお確認画面を挟んだりしても、hiddenやセッション変数を加工して対応が可能
覚えておくこと
form actionにはどのドメインのURLでも指定できる
すべてのページにCSRF対策をしなくてはならないわけではない
ショッピングサイトとかなら、カートに入れる処理などに対しての必要はない
別サイトからの拡張性を持たせたりできるから
ただし、決済などのページについてただけはCSRF対策を施してやる
正規利用者の意図したリクエストを確認できるように実装する
→正規利用者が実行したかどうか。
秘密情報(トークン)の埋め込み
パスワード再入力
物品購入の前に促すなど
リファラ(referer)のチェック
直前に閲覧したページが本当に正しいページであるかどうか。
処理実行後に利用者宛のメールアドレスに通知を飛ばすとか。
クリックジャッキング
webアプリ上でボタンを利用者にクリックさせ、利用者の意図しない投稿などをさせること
iframeとcssなどで罠サイトと正規サイトを重ね合わせ、攻撃対象サイトでクリックを誘導させる手法
攻撃することで利用者に重要な処理を実行させられるが、攻撃者はその情報は確認できない
CSRFと似ている
攻撃手法
景品応募みたいなページを作る
その応募ボタンは、cssのz-indexで上書きされたもの
その下にtwitterのウェブインテント機能で「〇〇を爆破します」みたいな投稿が書かれており、実行してしまうとか。
対策
アプリケーション側では困難なので、ブラウザ側で支援が必要。
iframeなどの制限をしてもらうとか。現在の主要ブラウザでは仕様として対応できるようになっている
csrfのように重要な処理の後に通知を出すとかで被害を抑えるとか。
セッションハイジャック
認証結果など現在の情報を記憶する手段がセッションである
クッキーにセッションIDという識別子を記憶させ、セッションIDをキーとしてサイバー側で情報を記憶する仕組み
何らかの原因でセッションIDが第三者に知られると、なりすましでアクセスが発生する
これがセッションハイジャック。影響が大きい。
セッションを奪うための手段
セッションIDの推測(生成ロジックが公開されていると起こり得る)
セッションIDの盗み出し
cookie生成時の属性不備
ネットワークでの盗聴
webアプリのXSSなど脆弱性による漏えい
PHPやブラウザなどの脆弱性による漏洩
セッションIDの強制・固定化
対策
セッション生成機構を自作せず、実績のある言語に任せる
URL埋め込みのセッションID
iモードなどではURL埋め込みのセッションIDが用いられていた
現代ではほぼほぼ必要ないので、URL埋め込みのセッションIDは作らないような実装をしよう
php.iniなどで設定ができる
リファラで漏洩することがある
セッションIDの固定化攻撃(Sessin Fixation Attack)
セッションIDを外部から強制する方法のこと
手順
セッションIDを入手する
被害者に対して、入手したセッションIDを強制させる
被害者が標的アプリにログインする
攻撃者は、被害者に強制したセッションIDを使って標的アプリにアクセスする
被害者が色々操作した情報を取得できるようになる
対策
ログインした時にセッションIDを変える
トークンを生成する
セッションとcookie両方にトークンを持たせて、一致する場合のみ認証とする
暗号論的擬似乱数生成の関数を使うと良い
code:php
>> $a = openssl_random_pseudo_bytes(24)
=> b"Ù(64ƒ\x12nÇLÏî¾éÙ9ð¢y’Û•]9N"
>> base64_encode($a) // エンコード
=> "2Sg2NIMSbsdMz+6+6dk58KJ5ktuVXTlO"
セッションアダプション
PHPなどで見られる、未知のセッションIDを受け入れるという特性
これがあると固定化攻撃がやりやすい(アダプションがなくてもできる)
リダイレクト処理にまつわる脆弱性
オープンリダイレクト
概要
ログインページのパラメータにURLを仕込んでおき、成功時にそのURLにリダイレクトさせる実装などで狙われる
このパラメータに任意のドメインにリダイレクトできる脆弱性のことを指す
フィッシングなどに使われる
利用者が信頼しているサイトから遷移するので、重要な情報を入力してしまう
手順
攻撃者が正しいログインURLの後ろにパラメータで?url=trap.comみたいなURLを付与してメールで送る
利用者は最初は正規のログイン画面が出るので、信頼してログイン後もページを閲覧してしまう。
対策
リダイレクト先のURLを固定化する
リダイレクト先のURLを番号として管理して管理する
DBとかで?redirect=1とかなら、id1の遷移URLに飛ばすとか。
リダイレクト先のドメインをチェックする
ただし正規表現で書くとすり抜けるケースが存在するので厳密の書く必要がある。
なるべく他の2つで対応するのが良い。
HTTPヘッダ・インジェクション
リダイレクトやクッキー発行など、外部のパラメータを基としてHTTPレスポンスヘッダを生成する際に発生する
レスポンスヘッダにおいて重要な文字(改行処理など)をエスケープせずに処理していると狙われる
影響は大きい
任意クッキーの生成、表示内容の改変などまで起こり得る。
対策
HTTPヘッダの出力部分を自作せず、ライブラリの機能をそのまま使う
レスポンスヘッダを生成するものがあった場合、改行コードが含まれている場合エラーとして終了させるなど。
URLパラメータでヘッダなどの情報を指定すること自体は可能。
外部からのパラメータをHTTPレスポンスヘッダとして出力させない
クッキー出力にまつわる脆弱性
webアプリケーションではcookieによるセッション管理が基本である
ただし以下の使い方によっては脆弱性が生まれる
クッキーを利用すべきでない状況でもクッキーを使っている
クッキーの出力方法に問題がある
クッキー出力時に発生する脆弱性について
HTTPヘッダ・インジェクション
クッキーのセキュア属性の不備
クッキーの不適切な利用とは
基本的な使用方法
セッションIDをcookieに保管し、データそのものにはcookieには保存しないようにする
cookieに保存すべきでない情報
それこそ、パスワードとか
なぜ保存すべきでないか
アプリの利用者によって書き換えをすることができる
書き換えられると困る情報をクッキーに保存すると脆弱性につながる
ユーザーIDや権限情報
ID1の人はこれ、みたいな分別をしていると書き換えて2の情報を見られたりする
セッション変数とクッキーの用途はほぼ同じなので、通常はセッション変数を利用すべき
よくある「ログインしたままにする」というボタンの仕組みについて
チェックを入れると、クッキーによりログイン情報が保持される
この中にはトークンが保存されており、決してIDやパスワードを入れているわけではない。
クッキーのセキュア属性不備について
Secureという属性を付与できる
これを指定したクッキーはHTTPS通信の場合のみブラウザからサーバに向かって飛ばされる
つまり、アプリケーションがHTTPSに対応していてもSecure属性がなければクッキーは平文で送られる可能性がある
盗聴が起こることも。
クッキーにはセッションIDなどを格納するケースが多いので、盗聴されると危険
基本この属性は付与させるのが良い。
HTTPとHTTPSが混在するサイトでは別途調整が必要。
メール送信の脆弱性について
メールヘッダ・インジェクション
宛先や件名などのヘッダフィールドに改行を挿入することで、新しいフィールドを追加したりする攻撃
hiddenパラメータによる宛先保持
hiddenパラメータでメールの送信先を指定しているフォームなどがある
パラメータを任意のアドレスに変更させることで、迷惑メールの送信に悪用されるパターンがある
ちゃんとアドレスはDBなどに保持させよう
ファイルアクセスにまつわる問題
ディレクトリ・トラバーサル
外部からパラメータの形でサーバ上のファイルを指定できるwebアプリケーションで発生する
指定部分のチェックが甘いと、アプリの意図しないファイルの改竄や閲覧ができる脆弱性。
OSコマンド呼び出しの問題
OSコマンドインジェクション
PHPでsystem()など、コマンドを呼べるものがあるがそれを悪用した攻撃。
ファイルアップロードにまつわる問題
大量データ送信によるDoS攻撃
対策はファイルアップロードの容量制限
アップロードするファイルがスクリプトであり、相手のサーバ内に保存させて実行させる
スクリプトをアップして、利用者がそのファイルを閲覧すると攻撃が発生するなど
ちゃんと拡張子とかでバリデーションをつけようという話
外部ファイルを読み込む機能の脆弱性
include(), require()などでファイルを読み込むアプリの脆弱性
ファイルインクルード攻撃
インクルードするファイルを外部から指定できる場合に発生する
外部からできないようにしよう
構造化データの読み込み時にまつわる問題
eval()とかを使うと起こりうる。
外部から送り込まれたスクリプトをevalで解析し、実行してしまうケースがある
これがevalインジェクション
デシリアイゼーション
そもそもシリアライズ, デシリアライズとは
アプリ内部構造を持ったデータを保存する目的でバイト列に変換すること。
CMSやフレームワークの内部でよく用いられる手法である
ただし、シリアライズする対象のプログラムが信頼できない場合、処理の際に意図しない挙動が発生する
影響としては、OSコマンドインジェクションと同じ例になる
共有資源・キャッシュに関する問題
共有資源とは、複数のプロセスやスレッドから同時に利用している変数やファイルのこと
排他制御(外部アクセスに関する制御)が不十分な場合に脆弱性となりうる
別人の情報が表される、DBの不整合、ファイルの内容の破壊など。
対策は、共有資源の利用を避けるか適切な排他制御を行うこと。
DBのロック以外にも、共有するファイルなどでも考慮する必要がある。
キャッシュからの漏洩
閲覧に認証を必要とする情報はキャッシュしてはいけない。
API実装における英弱性
jsonについて
JavaScriptのオブジェクトリテラルの形式をデータ交換形式に発展させたもの。
jsの式として解釈できる。昔はjsonの文字列をjsデータ形式として変換していたが危険なのでやらなくなった。
脆弱性と対策
パラメータにjsを書き込むなど。対策としては正しくエスケープする。
JavaScriptの問題
XSSが起こるケースがある。
webストレージ
cookieよりも高性能な保管庫としてブラウザに用意されているもの。
jsから呼び出しや書き込みができる。