Edited at

安全なWebサイトのつくりかた ざっくりまとめpart1

情報推進機構「安全なWebサイトのつくりかた」を読んだけど

情報量が多すぎて頭がフリーズしたので、現時点で最低限理解できる内容までを記録しておきます。

誰にでもわかるというより、僕にでもわかる文章で書いていますのでご了承ください。


Webアプリケーションのセキュリティ実装

例として、11種類のセキュリティ脆弱性が挙げられています。

「何がまずいのか?」「どんなアプリで注意が必要なのか?」を

噛み砕いてからまとめていきます。


  1. SQLインジェクション

    Part1(本記事)

    https://qiita.com/E-46/items/93199f38bdacd6b6076a


  2. OS コマンド・インジェクション

    Part2

    https://qiita.com/E-46/items/aa43b6a01de8ab205591



1. SQLインジェクション


どんな脆弱性なのか

インジェクションとは「注入、投入する」の意味。

SQL文を含むリクエストが入力フォームから渡されたとき、ユーザーがデータベースの情報を操作できてしまう問題です。

データベースを利用するなら注意すべき脆弱性、とのことですが

それはつまりほとんどすべてのWebアプリケーションが当てはまるのでは?

被害届出の数が他の脆弱性に比べて多い、もっとも代表的な脆弱性と考えられます。


  • 非公開データを閲覧される

  • データベースの情報が改ざん・消去される

  • 認証回避による不正ログイン

  • 不正なOSコマンド実行

などの問題を生じうる脆弱性です。


どんな問題につながるのか


  • 非公開のはずの個人情報を閲覧される

  • データ改ざんによりパスワードが勝手に変更される

  • 管理者権限を持った状態でログインされる

  • データを削除されてシステム全体が停止させられる

  • 不正なOSコマンドを実行されることで他サイトへの攻撃の踏み台にされる


注意すべきWebサイトの特徴

データベースを利用するWebアプリケーションを設置しているWebサイト。

個人情報を扱う場合は特に注意すべし。


対策

SQL文がパラメータとして送られてきても問題ないように設計する


2019/03/25 @error_401様のコメントを元に追記

参考 

https://blog.ohgaki.net/are-you-using-prepared-query-only#i-2

対策の優先順位は

1. プリペアードクエリ(プレースホルダをあらかじめ設定したクエリ)を使う

2. それがダメな場合に文字列処理・エスケープ処理をする

の順になる。

そもそも1のプリペアードクエリを使うならば、最終的に実行されるSQL文で変化するのは

渡されたパラメータが入るプレースホルダの部分だけになる。

つまりどんな処理を行うのか?を決めておけば、あやしい文字列がパラメータとして渡されてもそもそも安全だよね、という話。



SQL文はプレースホルダで実装する

参考

@Morinikiz様 安全なSQLの呼び出し方

https://qiita.com/Morinikiz/items/dfdb33f25df4df0f672c

「SQL文をプレースホルダで実装する」の例を示す。

SELECT * FROM employee WHERE name=?

の部分をプレースホルダといい、

この に実際の値を割り当てることをバインドという。

つまり、仮の値として設定しておいた部分に入力させる形式で実装することで

意図しないSQLの処理が走ることを防ぐ。


危険な文字列をエスケープさせる


2019/03/25 @arai-wa様のコメントを元に追記

エスケープ: 特殊文字が特殊文字ではなく普通の文字として扱われるようにすること。


参考

SQL注入攻撃 - IPA

https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/502.html

文字列のエスケープ処理 - DBOnline

https://www.dbonline.jp/sqlite/type/index4.html

SQLインジェクションのまとめ - No Programming, No Life

http://npnl.hatenablog.jp/entry/20080412/1207965105

危険な文字列というと語弊があるが、「SQL文の処理に関わる文字列」のことと解釈した。

例として以下のようなSQL文が走る処理を考える。

SELECT user_id FROM account_table WHERE user_id='ユーザID'

入力された"ユーザID"が"user_id"のレコードを、accountテーブルから取得させる。

ここで"ユーザID"に以下のような値が入力された場合を想定する。

';DELETE FROM account_table--

実行されるSQLはこのような形になる。

SELECT user_id FROM account_table WHERE user_id='';DELETE FROM acount_table--'

セミコロンで区切られているため、データベースに2つの命令が飛ぶことになる。

SELECT user_id FROM account_table WHERE user_id=''

DELETE FROM acount_table--'

2行目にaccount_table をまるごと削除するSQL文が完成してしまった。

(SQLでは--の後ろはコメントとして解釈される)

これを防ぐため、SQL文に含まれるパラメータ(入力された値)に対して

特殊な文字を置換・削除するためのエスケープ処理を行う。

特殊文字(「'」など)ではなくリテラルとして扱われるようにするためのエスケープ処理を行う。


2019/03/25 @arai-wa様のコメントを元に修正


この処理をサニタイジングと呼ぶ。


2019/03/25 @error_401様のコメントを元に追記

「サニタイズ」「サニタイジング」という言葉の厳密な定義が自分自身でまだ理解しきれておらず、現状で使うのは誤った情報の拡散につながること、誤解を招きかねないことから、一部表現を削除いたしました。


高木浩光@自宅の日記 - 続・「サニタイズ言うなキャンペーン」とは より引用

http://takagi-hiromitsu.jp/diary/20060115.html

「サニタイズ」という用語が、各人の都合でどんな意味にも解釈され るという、「汚れた言葉」になっており、専門用語として使い物にならなくなっ ているのだ。もはや、「サニタイズする」は「セキュリティ対策する」と同義 でしかない。



';DELETE FROM account_table--

このパラメータで問題なのは、'(シングルクオート)がSQL文の一部として解釈されてしまう点である。

これを防ぐため、パラメータを以下のように置換する処理を行う。

'';DELETE FROM account_table--

SQLでは、'(シングルクオート)が2連続で記述された場合

この'(シングルクオート)は特殊な文字ではなく単なる文字列であると解釈される。

こうすることで、最終的には以下のようなSQL文が発行される。

わかりやすくするため、パラメータは()で囲んでみた。

SELECT user_id FROM account_table WHERE user_id='('';DELETE FROM acount_table--)'

この場合、

「user_id が';DELETE FROM acount_table-- のレコードを探す」

という処理として解釈されるため

DELETE FROM acount_table が実行されることはなくなる。


SQL文をパラメータとして直接受け取らないようにする

論外。というか、どういう状況だろう・・・?


エラーメッセージをブラウザ画面に表示しない

エラーメッセージにSQL文などの情報が含まれている場合、

「どのようなエラーが発生したか?」を手がかりに攻撃される恐れがある。

データベース関係のエラーメッセージはユーザーに見せないこと。

セキュリティ、難しいですけど勉強しがいのある分野ですね。

2019/03/25

@error_401様のコメントを元に、「対策」「危険な文字はエスケープさせる」に一部追記いたしました。

@arai-wa様のコメント・編集リクエストを元に、「危険な文字はエスケープさせる」に一部追記いたしました。

2019/03/27

@prograti様のコメントより、OWASPが作成したSQLインジェクション対策チートシートを

参考URLとして追記いたします。


OWASPとは

The Open Web Application Security Projectは、ウェブアプリケーションセキュリティをとりまく課題を解決することを目的とする、国際的なオープンなコミュニティです。


SQL Injection Prevention Cheat Sheet

https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.md