※期待してた機能実装の途中でトラブルが発生したため、一旦前半として#day6のoutputを行います。
このチャレンジについて
目的: セキュリティエンジニアとしての技術力向上
手段: シェルスクリプト作成を通じて学習
実施する事: 自動化,監視,ツール開発基礎学習など
今回の目的:HTTPヘッダー分析ツールの作成
#day4の死活監視では、Webサイトが「生きているか」をステータスコードで確認しました。今回はもう一歩踏み込み、サーバーが返すHTTPヘッダーの中身を分析します。Webアプリケーションの脆弱性診断を実現できるように、適切なセキュリティヘッダーが設定されているかを確認するツールです。
ひとまず【前半】の記事では、「クリックジャッキング」という攻撃を防ぐX-Frame-Optionsヘッダーの有無を判断するツールとして作成します。そして次回の【後半】の記事で、他の多数のセキュリティヘッダーもまとめて確認できる、より本格的なツールへと改良していく予定です。
目次
- 実行イメージ
- 実行環境
- コード全文(前半)
- コードの詳細な解説
- 実行結果
- まとめと次回予告
実行イメージ
今回の【前半】で作成するスクリプトは、引数で渡されたURLに対し、X-Frame-Options
ヘッダーが存在するかどうかを判定し、結果を一行で表示します。
# スクリプトを実行すると...
$ ./header_checker.sh https://www.google.com
# このように結果が出力される
The X-Frame-Options header was found.
実行環境
この記事で紹介するスクリプトは、これまでと同様に以下の環境で作成・実行したものを想定しています。
- 接続元(ローカルPC): Windows 10
- ターミナルソフト: Tera Term
- 接続先(サーバー): AWS EC2 (Amazon Linux 2)
コード全文(前半)
header_checker.sh
#!/bin/bash
# 1. 最初の引数が空かどうかを確認
if [ -z "$1" ]; then
echo "Usage: $0 <URL>"
exit 1
fi
# 2. コマンドを実行し、ヘッダーを検索
# - URLには"$1"を使用
# - grep -i で大文字小文字を区別しない
# - &> /dev/null でパイプラインからの出力を抑制
curl -sIL "$1" | grep -i "X-Frame-Options" &> /dev/null
# 3. パイプラインの終了ステータスを確認
if [ $? -eq 0 ]; then
echo "The X-Frame-Options header was found."
else
echo "The X-Frame-Options header was not found."
fi
コードの詳細な解説
このスクリプトは、特定のヘッダーの有無を確認するというシンプルな目的を、いくつかの基本的な要素で実現しています。
-
引数チェック (
if [ -z "$1" ]
)
スクリプト実行時に引数(URL)が指定されているかを確認します。-z
は変数が空かどうかを判定する演算子です。もし空であれば、使い方を表示してスクリプトを終了します。 -
ヘッダーの検索と出力抑制 (
curl ... | grep ... &> /dev/null
)
この一行が中核部分です。curl
でヘッダーを取得し、その結果をパイプ|
でgrep
に渡してX-Frame-Options
という文字列を検索します。-i
オプションで大文字・小文字を区別しないようにしているのがポイントです。
&> /dev/null
は、grep
が見つけた行そのものは画面に表示せず、結果を捨てるための記述です。今回はgrep
が成功したか(0
)失敗したか(1
)という終了ステータスだけが欲しいため、このような形にしています。 -
結果判定 (
if [ $? -eq 0 ]
)
直前に実行されたコマンド(この場合はgrep
)の終了ステータスは、特殊な変数$?
に格納されます。grep
は文字列を見つけたら成功(0
)、見つけられなければ失敗(1
)を返すため、この$?
の値を-eq 0
(0と等しいか)で判定することで、ヘッダーの有無を判断しています。
実行結果
このスクリプトに実行権限を与え、実際にGoogleのURLを渡して実行した結果がこちらです。
$ ./header_checker.sh https://www.google.com
The X-Frame-Options header was found.
正しくヘッダーの存在を検知できていることが確認できます。
まとめ・次回
#day6の前半では、単一のHTTPヘッダーの有無をチェックするツールの基礎固めることができました。curl
とgrep
の終了ステータスをif
文で判定するという流れは、様々なチェックに応用できるなと、ここ数日の流れからも感じています。
【後半】では、実用的なツールとするために複数のヘッダーを一度にチェックし、レポートとして出力する機能を実装します。