- ステータスライン
例: HTTP/1.1 200 OK
- ヘッダ
- Date
- Server (Apache/2.2.14 Ubuntuとか)
- Content-Length (ボディのバイト数)
- Content-Type (MIMEタイプ text/plain, image/gifなど)
- etc
- ボディ
MIMEタイプ
MIMEタイプ | 意味 |
---|---|
text/plain | テキスト |
text/html | HTML文章 |
text/css | CSS |
image/gif | gif画像 |
image/png | png画像 |
image/jpeg | jpg画像 |
application/pdf | |
application/xml | XML |
- 1xx : 処理が継続している
- 2xx : 正常終了
- 3xx : リダイレクト
- 4xx : クライアントエラー
- 5xx : サーバーエラー
処理の流れは左から右。 (ブラウザ (HTTPリクエスト) --> 入力値検証 -->色々な処理 --> 表の通り)
入力 | 処理 | 出力 | 流れ | 発生する脆弱性の種類 | 脆弱性の発生箇所 | |
---|---|---|---|---|---|---|
入力値検証 | 処理 | 表示/HTTP | --> | ブラウザ | 「クロスサイトスクリプティング」 | 出力時 |
入力値検証 | 処理 | DB/SQL | <--> | RDB | 「SQLインジェクション」 | 出力時 |
入力値検証 | 処理 | 外部コマンド | <--> | シェル | 「OSコマンド・インジェクション」 | 出力時 |
入力値検証 | 処理 | メール | <--> | メール | 「メールヘッダ・インジェクション」 | 出力時 |
入力値検証 | 処理 | ファイル | <--> | ファイル | ディレクトリ・トラバーセル | 入力時 |
入力値検証 | 重要な処理 | クロスサイト・リクエストフォージェリ | 入力時 | |||
入力値検証 | 認証 | セッションフィクセーション | 入力時 | |||
入力値検証 | 認可 | 認可不備 | 入力時 |
- HTMLの出力(XSS)
- HTTPヘッダの出力(HTTPヘッダ・インジェクション)
- SQLの呼び出し・発行(SQLインジェクション)
- シェルコマンドの呼び出し(OSコマンド・インジェクション)
- メールヘッダおよび本文の出力(メールヘッダ・インジェクション)
hiddennパラメータのメリット
ユーザが書き換え可能という問題はあるものの、
情報漏洩・第3者からの書き換えに対して強い
- クッキー発行の際の属性に不備がる
- ネットワーク的にセッションIDが盗聴される
- XSSなどアプリの脆弱性により漏洩
- PHPやブラウザなどのプラットフォームの脆弱性で漏洩
- セッションIDをURLに保持している場合はRefererヘッダから漏洩する
- クッキーが保持できる値の個数や文字列長には制限がある
- クッキーの値は利用者が参照・変更できるため、秘密情報保持には向かない
属性 | 意味 |
---|---|
Domain | ブラウザがクッキー値を送信するサーバのドメイン |
Path | ブラウザがクッキー値を送信するURLのディレクトリ |
Expires | クッキー値の有効期限。指定しない場合はブラウザの終了まで |
Secure | SSLの場合のみクッキーを送信 |
HttpOnly | この属性が指定されたクッキーはJavaScriptからアクセスできない |
HttpOnly属性は、JSからのアクセスを防げるため、
XSSなどの攻撃からセッションIDなどをある程度守ることができる。 悪影響は殆どない。
旧ブラウザなどでは".co.jp"ドメインのクッキーが作れてしまうという問題で、
ユーザに悪意のある該当のクッキーを付与し、それでログインをさせる。
その後、そのクッキーでログインするという感じ。
IE8では地域型ドメインに対するクッキーモンスター問題がある。
地域ドメインとは、city.yokohama.lg.jpみたいなの。危ない。
formのaction要素を使用した攻撃手法 別Gistに記載
JavascriptやJavaアプレット、Flash Player, ActiveXなどのサイトを閲覧しても、
それらのアプリケーションのプログラムによる参照・書き換え範囲が決まっていること。
例: 埋め込まれたiframe内にJavascriptの記述があり、
そこから埋め込み元のページに対して悪事を働こうとプログラムを起動する。 しかしサンドボックスのおかげで書き換えられない。 など
サンドボックスで書いた、
Javascriptによるサイトをまたがったアクセスを禁止するセキュリティ上の制限。
iframe内のドキュメントや、Ajaxの実現に使用されるXMLHttpRequestでアクセスできるURLにも
同一生成元ポリシーの制約がある。
- URLのホスト(FQDN: fully Qualified Domain Name)が一致している
- スキーム(プロトコル)が一致している
- ポート番号が一致している
HTTPリクエスト --> 処理(アプリケーションロジック) --> 出力
- 文字エンコーディングの妥当性検証
- 文字エンコーディングの変換
- パラメータ文字列の妥当性検証
Javaは文字エンコーディングの自動変換を主に使用する言語である。
自動変換のデメリット「文字化けが発生しても利用者が気づかずに処理を継続してしまう」
C言語・Unix, Windows APIなどでは、nullバイトを文字列の末端とみなす取り決めがあり、
それと他の脆弱性を使って攻撃する手法。
NullのついたURLで攻撃してくる。
http://hogehoge.jp/hoge%00<script>alert("hoge")</script>
入力値で不正な入力を全てチェックしておけば、セキュリティの対策が終わる わけではない
入力値検証はアプリケーションの使用が基準のため。
基準はあくまでアプリケーション要件
入力値検証の対象は全てのパラメータ。
hidden, radio, select要素なども。
クッキーにセッションID以外の値を入れているときはクッキーの値も検証する。
その他、RefererなどHTTPヘッダをアプリケーションが利用している場合も検証対象。
Javaでの正規表現チェックはStringクラスのmatchesメソッドが便利
matchesは全体一致検索を行うので\A \zで挟む必要はない
Javaの正規表現は文字列として指定するため、バックスラッシュで重ねる必要がある
ex. s.matches("\P{Cc}{0,100}")
入力値の検証で正規表現を使うとき、
後ろで"u"修飾子をつけてUTF-8エンコーディングのマッチをしたほうがいい
(言語や正規表現のクラスによる)
「行」の先頭・末端にマッチする^, $ では
$が改行にマッチしてしまうため、
%0a(ラインフィード)をつけると改行文字がチェックをすり抜ける。
そのため、「データ」の先頭末端を扱う\A, \Zで行うべき
(言語や正規表現のクラスによる)
正規表現関数はクラス開発者の裁量によって挙動が変わるため、
\dで全角数字にマッチする場合もある。
そこで明示的に[a-zA-Z0-9_]のように宣言しておくと良い
リクエストメッセージにつく場合がある。
Refererヘッダは、リンク元のURLを示すヘッダで、form送信のほか、a要素のリンク、
img要素による画像参照などで付く。
アプリケーションが意図した推移をしているかが確認できるが、 ユーザが書き換え可能なため、URLが機密情報を含んでいる場合(セッションIDなど)
脆弱性としてなりすましなどに悪用される場合がある
https://gist.github.com/motoyasu-saburi/10e3d8ee5d3629a31faa5d836ee9c876