はじめに
自分が作成したwebサイトについて、SQLインジェクションが対策されているのか指摘があったので、調べてみることにしました。
SQLインジェクションとは
WebサイトやWebアプリケーションの脆弱性を利用し、不正なSQL文をWebサイトなどからデータベースへ送ることで個人情報の窃盗やデータ改ざんなどを行うサイバー攻撃手法。
【引用】SQLインジェクションとは?手口や被害リスク・5つの対策までわかりやすく解説
仕組み
「user」というテーブルから「id」を基にデータを抽出
SELECT * FROM user WHERE id = '$ID'
「$ID」に「taro’ or ‘1’=‘1」が注入された場合
SELECT * FROM user WHERE id = 'taro' or '1'='1'
id='taro'が成立した場合はtaroの情報が出力されるが、
成立しない場合は、'1'='1'で全ての場合において成立してしまうので、「user」の全てのデータが出力されてしまう。
対策
1. プレースホルダの利用
SQL文に置く変動箇所を示す記号のこと
この例では「?」のこと
SELECT * FROM user WHERE id = ?
変動箇所に入力された文字がSQL文の一部でなく、文字列として処理されます。それによって、不正SQL文の実行を防ぐことができます。
2. エスケープ処理
エスケープ処理とは、ユーザーから入力された特定の文字や記号を安全な形に変換する処理です。例えば、SQL文において特別な意味を持つシングルクォート「’」をダブルクォート「”」に変更することなどがあります。
エスケープ処理を行うことで、SQLインジェクションを受けても、攻撃コードの中の特定の文字列や記号を削除したり置き換えたりするので、攻撃を無効化することができます。
3. Webアプリケーションを常に最新のバージョンに保つ
OSやアプリケーションのバージョンアップには、発見された脆弱性を修正したものが含まれることが多いので、常に最新のバージョンにしておくことで攻撃を受けるリスクを軽減できます
4. WAFの導入で本格的なセキュリティ対策
WAFとは、Web Application Firewall(ウェブアプリケーションファイアウォール)の略称で、Webサイトを含めたWebアプリケーションの脆弱性を狙ったサイバー攻撃を防御する、セキュリティ対策ツールのひとつです。
実践
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form method="post" action="/login">
<p>名前</p>
<input type="text" name="id">
<p>パスワード</p>
<input type="text" name="pass">
<input type="submit">
</form>
</body>
</html>
データベース
テーブル名:user
カラム | 値 |
---|---|
id | taro |
pass | password |
対策していない場合
app.post("/login", (req, res) => {
connection.query(
`SELECT * FROM user WHERE id='${req.body.id}' AND pass='${req.body.pass}'`,
(error, results) => {
if (results[0] != undefined) {
login_check(req, res, results);
} else {
res.redirect("/");
}
}
);
});
function login_check(req, res, results) {
for (choice of results) {
if (choice.id === req.body.id) {
res.redirect(`/resp?id=${choice.id}`);
break;
}
}
}
プレースホルダーによる対策をした場合
app.post("/login", (req, res) => {
connection.query(
'SELECT * FROM user WHERE id=? AND pass=?',
[req.body.id,req.body.pass],
(error, results) => {
if (results[0] != undefined) {
login_check(req, res, results);
} else {
res.redirect("/");
}
}
);
});
function login_check(req, res, results) {
for (choice of results) {
if (choice.id === req.body.id) {
res.redirect(`/resp?id=${choice.id}`);
break;
}
}
}
参考にしたサイト
おわりに
SQLインジェクションは割と簡単に対策できることが分かりました。
今回はSQLインジェクションだけを対策しましたが、他にもさまざまなセキュリティ対策があると思うので、機会があれば調べてみようと思います。