はじめに
ウェブセキュリティはウェブ開発者だけでなく、一般のウェブユーザーも理解しておくべき非常に重要なテーマです。この記事ではWEBページが具体的にどのような攻撃手法に晒されているのかと、それぞれの対策についてわかりやすく説明します。
XSS(クロスサイトスクリプティング)
XSS攻撃とは、攻撃者がウェブページの掲示板などに悪意のあるスクリプトを挿入する手法です。
具体的な攻撃方法
例えば、掲示板のコメント欄に以下のようなJavaScriptのコードを入力した場合、次にそのページを開いた人は強制的に「あなたのPCが異常を起こしています」という文字列のポップアップメッセージを見せられることになります。
<script>
alert('あなたのPCが異常を起こしています'); // ブラウザの画面に「XSS」というメッセージの小窓を表示させる
</script>
このJavaScriptコードが掲示板にサニタイズ(無害化)されずにそのまま保存されることで、他のユーザーがその掲示板のページを開いたときに、掲示板に残ったJavaScriptなどのコードを解析されてしまい、攻撃者以外のブラウザでもこのJavaScriptコードは実行がされてしまいます。その結果、alertメソッドが実行されてアラートボックスが出現します。
クロスサイトスクリプティング(XSS)の最も危険な被害
XSS攻撃で一番怖いのは、「なりすまし」です。つまり、悪い人があなたになりすますことができてしまいます。前述のメッセージを表示させる方法は非常に簡易的な方法ですが、JavaScriptを悪用すればユーザーのセッション情報(ログイン情報)やクッキー(閲覧履歴)に侵入して、最悪の場合情報を盗み取ることができます、そうなれば、悪い人があなたになりすましてネットバンクのお金を動かしたり、個人の大事な情報を閲覧されたりする可能性が出てきます
サニタイズとは?
不正なデータや危険なコードが実行されるのを防ぐために、入力データを「清潔」にする処理のことを指します。ウェブサイトで上記のような変なコードを入力されると危険なことがあるため、危険な記号を別の安全な記号に変えて、問題が起こらないように掃除することをサニタイズといいます。
クロスサイトスクリプティングの対策とは
ユーザーからの入力をそのまま表示させないためにサニタイズ処理を行い、特殊文字に変換するなどのエスケープ処理を実行し、JavaScriptのコードを作らせないことが対策になります
具体的なクロスサイトスクリプティングの対策とは
一般的にはサーバーサイドとクライアントサイド、両方での対策をすることでそれぞれの手法が補完し合う形で、より堅牢なセキュリティ対策を構築することができます。
サーバーサイド(例:PHP)
サーバーサイドでの処理は、クライアント(ブラウザ)から送られてきたデータをデータベースに保存する前や、それを再度クライアントに送り返す前に行います。この段階でデータを適切にエスケープ(サニタイズ)したり、バリデーション(チェック)を行うことで、XSS攻撃を防ぐことができます。
PHPでよく使用されるエスケープ(サニタイズ)の関数には htmlspecialchars() や htmlentities() があります。
$clean_data = htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
クライアントサイド(JavaScript)
HTMLタグに直接対策を施す方法もあります。これは特にJavaScriptを使って動的にコンテンツを生成する場合に有用です。JavaScriptでDOMを操作する際に、.innerText のようなプロパティを使うと、HTMLタグはエスケープされた状態で挿入されます。これによって、スクリプトの埋め込みを防ぐことができます。
document.getElementById("someElement").innerText = user_input;
SQLインジェクション
SQLインジェクションとは?
SQLインジェクションは、攻撃者がデータベースに対するSQLクエリに悪意のあるコードを挿入する手法です。
具体的な攻撃方法
例えば、ログインフォームでユーザー名に以下のような文字列を入力します
Copy code
' OR '1'='1
これがフィルターされずにSQLクエリにそのまま入ると、認証を無視してログインできてしまいます。
具体的な攻撃方法
攻撃者は、Wi-Fiのスニッフィング(データパケットの傍受)やXSSを使用して、ユーザーからセッションIDを盗むことがあります。
なぜログインされてしまうのか
たとえば、一般的なログインのSQLクエリが以下のようになっているとします。
SELECT * FROM users WHERE username = '入力されたユーザー名' AND password = '入力されたパスワード';
このとき、ユーザー名の部分に ' OR '1'='1 と入力されると、SQLクエリは次のようになります。
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '入力されたパスワード';
'1'='1' は常に真(true)なので、このクエリは「ユーザー名が空、または1=1(常に真)」という条件にマッチするすべてのレコードを返します。これが成功すると、攻撃者は認証をスキップしてログインできてしまいます。
つまり「' OR '1'='1」という特殊なコードをユーザー名として入力すると、このコードは「1=1」という部分が常に正しい(真)であるため、このコードを使うと、「正しいユーザー名かどうか」のチェックをすり抜けて、ログインしてしまうことができます。
SQLインジェクションへの対策
SQLインジェクションの対策は基本的にサーバー側で行います。クライアント側(例:JavaScript)での対策は一般に不十分であり、セキュリティが確保されていない場合が多いです。
なぜなら、クライアント側のコードはユーザー(または攻撃者)が操作できてしまうからです。攻撃者が悪意を持ってクライアント側のコードを書き換えたり、無効にしたりすることができます。そのため、サーバー側で次のような対策を講じることが重要です。
-
プリペアドステートメントを使用する(パラメータ化クエリ)
これは一番推奨される方法です。この方法では、SQLクエリの中で変数の場所を先に決めておき、後からその変数に値を代入します。このようにすることで、悪意のあるコードが挿入されるのを防ぎます。 -
入力検証する(バリデーション)
ユーザーからの入力に対して、何が許可されていて何が許可されていないかのルールを明確にして、それに基づいてチェックします。 -
エスケープ処理
ユーザーからの入力をデータベースに挿入する前に、特殊な文字をエスケープ(無効化)します。
セッションハイジャック
簡単に言えば、誰かがあなたの「オンラインの身分証明書」を盗む手法の一つです。これをやられると、攻撃者はあなたとしてオンラインサービスにログインできてしまう可能性があります。
具体的には、あなたがウェブサイトにログインすると、そのウェブサイトは「あ、この人は確かに○○さんだ」と認識するための特別なコード(セッションIDと呼ばれる)を作ってくれます。このセッションIDは通常、あなたのウェブブラウザ(ChromeやFirefoxなど)に保存されます。
攻撃者が何らかの方法でこのセッションIDを手に入れると、ウェブサイトは攻撃者をあなたと誤認してしまいます。このようにして、攻撃者はあなたになりすまして様々な悪事を働くことができてしまうのです。
セッションハイジャックの具体的な攻撃方法
セッションハイジャック(またはセッションハイジャッキング)にはいくつかの一般的な攻撃方法があります。
-
パケットスニッフィング(傍受)
攻撃者は、公共のWi-Fiなどを利用して通過するデータを「傍受」します。このデータの中には、セッションIDが含まれている場合があり、それをつかんで攻撃者はそのIDでログインします。 -
XSS(クロスサイトスクリプティング)
前述で説明した通り、攻撃者はウェブページに特定のコードを挿入して、そのページを訪れたユーザーからセッションIDを盗みます。これは、ユーザーが何も気づかずにセッションIDが盗まれるケースが多いです。 -
物理的な手段
攻撃者は、ユーザーのデバイス自体を盗んでセッションIDを取得することもあります。これは最も直接的な攻撃方法です。 -
ソーシャルエンジニアリング
攻撃者は、ユーザー自身にトリックを使ってセッションIDを明かさせる場合もあります。例えば、偽の「ログアウトしました、再度ログインしてください」というメッセージを表示してユーザーにログイン情報を入力させるなどです。
セッションハイジャックへの対策
-
HTTPSの使用
ウェブサイト全体でHTTPSを使用することで、データの暗号化を行い、第三者によるデータの傍受を防ぐことができます。HTTPSとはHTTPにセキュリティ層(主にSSL/TLS)を追加したもので、HTTPの場合「平文」で送受信されるため、第三者に傍受されるリスクがありましたが、HTTPSにすることでデータは暗号化されて送受信されるため、第三者に傍受されても内容は容易には読み取れなくなります -
セッションタイムアウト
一定時間アクティビティがない場合、自動的にユーザーをログアウトさせる設定を行います。これにより、攻撃者がセッションIDを手に入れても、限られた時間しかそのIDを使えなくなります。アクティビティとはユーザーがウェブサイトで商品を検索したり、フォームに情報を入力したり、ボタンをクリックしたりするなどの一連の行動のことです -
セッションIDの頻繁な変更
ユーザーが重要な操作(例えば、パスワード変更や個人情報の編集など)を行った場合、セッションIDを新しく生成するようにします。 -
IPアドレスとセッションIDの紐付け
ユーザーがログインしたIPアドレスとセッションIDを紐付け、IPアドレスが急に変わった場合はセッションを無効にするといった対策が考えられます。IPアドレスとはPCやスマホなどの端末が設置されているインターネット上の住所のようなものです -
二要素認証(2FA)
パスワード以外にもう一つの認証手段(例:SMSコード、認証アプリなど)を用いることで、セッションIDが盗まれたとしても、攻撃者は容易にはログインできなくなります。 -
ユーザー教育
ユーザー自身にセキュリティ意識を持ってもらうことも重要です。公共のWi-Fiを使用する際のリスク、フィッシングメールに対する警戒など、ユーザー自身ができる対策もあります。
CSRF(クロスサイトリクエストフォージェリ)
CSRFは、ある人がログインした状態で別の悪意のあるウェブサイトにアクセスすると、その悪意のあるサイトが彼の代わりに本来のサイトに対して不正な操作を行うという攻撃です
例えば、あなたがお気に入りのSNSにログインしています。そのままの状態で別のウェブサイト(これが悪意のあるサイトです)に行くと、そのサイトは裏であなたがログインしているSNSに対して「友達を削除する」といった操作を行います。
あなたは何もしなくても、あなたの友達がSNSから削除されてしまうわけです。これがCSRF攻撃の一例です。
CSRFの具体的な攻撃方法
攻撃者は以下のような方法でユーザーがログインした状態である他のサイトに対して、ユーザー自身が意図しない操作を行わせます
-
悪意のあるサイトや電子メールにリンクを配置
攻撃者は、ユーザーがクリックするとCSRF攻撃が実行されるサイトのリンクを用意しておくことで、それを開いてしまったユーザーを悪意のあるサイトへ誘導します -
JavaScriptを用いて自動的にリクエストを送る
悪意のあるサイトには、訪問者が何もしなくても攻撃が実行されるJavaScriptコードが埋め込まれている場合もあります。 -
偽装フォーム
攻撃者は、目的のウェブサイトにそっくりな偽のウェブページを作成し、ユーザーに情報を入力させることで攻撃を行う場合もあります。例えばアマゾンや楽天の偽サイトが存在したことは有名です。
CSRFへの対策
-
トークンを使用してリクエストを認証する
トークンとは、セキュリティや認証の文脈でよく用いられる一時的な「証明書」のようなものです。たとえば、ログイン後にサーバーからトークンが発行され、それを用いてユーザーが認証される場合があります。これによって、パスワードなどの重要情報を何度も送信する必要がなくなります。 -
リファラーチェック
HTTPリクエストヘッダのリファラーを確認し、不正な源からのリクエストを拒否する。リファラーは「このページに来る前に、ユーザーはどのページにいたか」を示しています。 -
プリペアドステートメント
SQLインジェクション対策として、SQLクエリを実行する前にデータをエスケープする。データをエスケープ(Escape)するとは、特定の文字をコードに変換することで、その文字がもともと持っている意味や機能を無効にする処理のことを指します。 -
データのバリデーション
ユーザーからの入力データに対して、サーバー側でも厳密なバリデーションを行います。バリデーションとはデータが特定の条件やルールに確実に合致するように検証する高度な処理のことを指します。例えば、文字数や不正な記号が入っていないかなど -
セッション管理
セッションIDを頻繁に変更したり、不正なセッションに対するロックアウト機能を設ける。 -
HTTPSの強制
通信をHTTPSで暗号化し、データの傍受を防ぐ。
まとめ
ウェブセキュリティは日々進化していますが、基本的な攻撃手法とその対策は知っておくべき重要な知識です。安全なウェブの利用と開発のために、これらの知識をしっかりと理解することがエンジニア必須のステータスと言えます