- 投稿日:2019-03-24T17:55:30+09:00
安全なWebサイトのつくりかた ざっくりまとめpart1
情報推進機構「安全なWebサイトのつくりかた」を読んだけど
情報量が多すぎて頭がフリーズしたので、現時点で最低限理解できる内容までを記録しておきます。
誰にでもわかるというより、僕にでもわかる文章で書いていますのでご了承ください。Webアプリケーションのセキュリティ実装
例として、11種類のセキュリティ脆弱性が挙げられています。
「何がまずいのか?」「どんなアプリで注意が必要なのか?」を
噛み砕いてからまとめていきます。
SQLインジェクション
Part1(本記事)
https://qiita.com/E-46/items/93199f38bdacd6b6076aOS コマンド・インジェクション
Part2
https://qiita.com/E-46/items/aa43b6a01de8ab2055911. 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
- 投稿日:2019-03-24T02:15:55+09:00
技術書 読んだ順番を振り返ってみた
必要に迫られてSQLを勉強し始めて以来、購入した技術書も気づけば10冊を超えていました。本棚を晒すようで若干恥ずかしさもあるのですが、自身の振り返りも兼ねて記事にしてみました。
プログラミング初心者が、ちょっとしたデータベース構築と入力画面の作成ができるようになるまでに読んだ本の一覧として、参考になれば幸いです。読んだ順番
- SQL Server 2016の教科書
- SQLパズル 第2版
- SQLアンチパターン
- プログラマのためのSQL 第4版
- 独習C# 新版
- もっとプログラマ脳を鍛える数学パズル
- やってはいけないデザイン
- リーダブルコード
- 実戦で役立つC#プログラミングのイディオム/定石&パターン
- Effective C# 6.0/7.0
- プリンシプル オブ プログラミング
この順番で読んだほうが良かったかも順
- プリンシプル オブ プログラミング
- リーダブルコード
- プログラマのためのSQL 第4版
- SQLアンチパターン
- SQLパズル 第2版
- SQL Server 2016の教科書
- 独習C# 新版
- 実戦で役立つC#プログラミングのイディオム/定石&パターン
- Effective C# 6.0/7.0
- もっとプログラマ脳を鍛える数学パズル
- やってはいけないデザイン
発売順を考慮していないため、実際にできたかは別として、その分野の原理原則的なことを記している書籍を先に読んでおいたほうが、後続の本の理解もしやすかっただろうと思いました(とはいえ、その時の気分や勢いがあるからこそ一気に読めるというのもあるので難しいですね)。