#はじめに#
プログラミングを学習しているとセキュリティについては必ず考えなければなりません。
今回は
・なぜセキュリティを考えなければならないのか
・主な攻撃手法とその対策
という点についてまとめていきたいと思います。
#なぜセキュリティを考えなければならないのか#
プログラミングを勉強しているとセキュリティ対策はしっかりしましょう!という話をよく聞くと思います。結構考えるのも面倒ですし実装するのも面倒なので、えー・・・と思う方もおられるかもしれません。
しかし、世の中には悪いことを考える人がたくさんいます。SNSでなりすまして詐欺を働いたり、データベースから情報を抜き取って悪用したり、といった感じです。自分しか使わないようなアプリならそれほど気にする必要はないかもしれませんが、多くの人が使うアプリであれば、そしてそれが個人情報やクレジットカード情報などを扱うようなものであれば十分注意する必要があります。
#主な攻撃手法とその対策#
それでは主な攻撃手法とその対策について見ていきましょう。
##XSS(クロスサイトスクリプティング)##
XSS(クロスサイトスクリプティング)とはユーザーからの入力があるSNSや掲示板などでHTMLタグを生成し、悪意のあるスクリプトを実行させる攻撃手法のことです。
例えばSNSで今日の一言などを入力する際、<h1>ひとこと</h1>などとすると見出しタグとして認識されてしまいます。それでは、これが他のページへ遷移させるようなスクリプトであればどうでしょうか。見ていたページと全く同じサイトが表示されて、そこで個人情報の入力を求められたとしたらどうでしょうか。これがXSSという手法です。
####対策####
対策にはいくつかありますが、その一つはエスケープ処理です。htmlspecialchars関数を用いることでユーザーから入力のあった値を出力する際、<や>などの特殊文字を通常の文字列に変換することが出来ます。まあ厳密には文字列というかHTMLエンティティというものなんですが、深く考えなくても良い気はします。
こうすることでHTMLタグやscriptタグが実行されることなく単なる文字列として出力されるというワケです。ユーザーからの入力文字を出力する場所には全てエスケープ処理をしておきましょう!
##SQLインジェクション##
SQLインジェクションとは、入力箇所にSQL文を直接書くことでSQLを実行してしまうという手法です。例えば、DELETE文などを入力されてしまうとどうでしょうか。データベースのデータが消されてしまう可能性があります。他にも、ECサイトの金額を書き換えられてしまったり管理者権限が乗っ取られたり別のユーザーでログインしたりといった脆弱性が挙げられます。
####対策####
SQLインジェクション対策には、SQL文に直接入力値を入れるのではなく、プリペアードステートメントを用いて値をバインドさせるのが有効です。
$stmt = $dbh->prepare('INSERT INTO users SET name=?, age=?, height=?');
$stmt->bindValue(1,'太郎',PDO::PARAM_STR);
$stmt->bindValue(2,'18',PDO::PARAM_INT);
$stmt->bindValue(3,'175',PDO::PARAM_INT);
$stmt->execute();
このようにバインドさせることによってSQLインジェクションを防ぐことが出来ます。
##CSRF(クロスサイトリクエストフォージェリ)##
CSRF(クロスサイトリクエストフォージェリ)とは、ログインを維持した状態でリンクを踏ませて悪意を持った罠ページにユーザーを誘導し、ユーザーが意図していないリクエストをさせる攻撃手法のことです。これにより、本来ログインしたユーザーしか発信できないリクエスト(SNS投稿など)が実行されてしまいます。
####対策####
対策にはトークンというものを生成します。POST通信をするフォームに対してあらかじめ推測できないランダムな文字列を埋め込んでおきます。さらに、生成されたトークンをセッションに保存しておき、POST送信が行われた際にフォームのトークンと照合します。トークンが埋め込まれていなかったり、セッションに保存されている文字列と異なる場合は不正なリクエストとして処理を停止します。
#まとめ#
このように多くの人に使われるアプリケーションでは、常に悪意に晒されていると考えた方が良いでしょう。
初学者であってもこういったセキュリティ対策は必須になってきており、今から癖をつけておく必要があります。覚えておいて損はないでしょう。