脆弱性

webサイトの脆弱性

More than 3 years have passed since last update.


XSS(クロスサイトスクリプティング)

クロスサイトスクリプティングはユーザーからの入力をそのままエコーバック(オウム返し)するようなアプリケーションに対する、悪意のあるスクリプトを送信する攻撃。


原理

$userInput = ユーザーから入力された値;

echo $userInput;

上記のようなアプリケーションで、下記のような入力を受け取るとJavascriptのアラートが表示されてしまう。

<script>alert('悪意ある文章')</script>


対策

これはHTML出力時にHTMLエスケープをしてやることで対策が可能。

echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');


CSRF(クロスサイトリクエストフォージェリ)

クロスサイトリクエストフォージェリ(Cross site request forgeries、略記:CSRF、またはXSRF)は、www における攻撃手法のひとつである。具体的な被害としては、掲示板に意図しない書き込みをさせられたり、オンラインショップで買い物をさせられたりするなどが挙げられる。


原理


  1. 攻撃者がwww上に攻撃用のwebサイトを作成する

  2. ユーザーがそのサイトを開く

  3. ユーザーは攻撃者が用意した任意のHTTPリクエストを送信させられる

  4. 攻撃者が意図した操作が行われる

下記が攻撃用のサイト例

<!DOCTYPE html>

<html lang="ja">
<head>
<title>攻撃用のページ</title>
</head>
<body onload="document.attackform.submit();">
<form name="attackform" method="post" action="http://example.com/bbs/register.cgi">
<input type="hidden" name="title" value="攻撃者が指定した題名">
<input type="hidden" name="article" value="攻撃者が指定した本文">
<input type="submit" value="送信">
</form>
</body>
</html>

javascriptでonloadが書いてある部分がミソで、ページが表示されると同時にフォームの内容が送信される。このwebサイトを1×1ピクセルのiframe内に表示させたものが以下のサイト。


<!DOCTYPE html>
<html lang="ja">
<head>
<title>誘導用のページ</title>
</head>
<body>
<p>ようこそいらっしゃいました。</p>
<iframe width="1" height="1" src="attack.html"></iframe>
</body>
</html>

スクリーンショット 2015-02-10 1.05.58.png

ユーザーは1×1ピクセルなど見えないので、実際に何か送信したことに気づきにくい。iframeの代わりにimgタグがつかわれることもある。

<html>

<body>
<img src="http://example.com/bbs/register.cgi?title=攻撃者が指定した題名&article=攻撃者が指定した本文">
</body>
</html>

こちらは前述のPOST送信と違ってGET送信になるため、文字数などが限られるが、ひとつのサイト上に複数仕込む事が可能。


対策

ユーザーが入力フォームから情報を入力して、送信していることを保証できれば、この問題は解決する。そのために入力フォームを表示させるときに下記のようなコードを仕込んでおく。

 <input type="hidden" name="sessionid" value="セッション追跡用cookieの値"> 

この値をユーザーに保持させておいて、送信ボタン押下と同時にサーバーに送り返し、サーバーに保持してあるセッションと突き合わせることで認証が可能となる。


SQLインジェクション

アプリケーションのセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法。


原理

SELECT * FROM user WHERE name = '(入力値)'

ここで入力値にt' OR 't' = 't';と入力したとする。

すると、

SELECT * FROM user WHERE name = t' OR 't' = 't';

となり後半の条件がすべてのレコードにおいて真のため、全データが抽出される。


対策

入力値のメタ文字'''(単一引用符2つ)にエスケープしてあげることで意図したnamet' = 't'を探すことができる。

SELECT * FROM user WHERE name = t' OR 't'' = ''t'';