サーバアプリケーションがMySQLなどデータベースを利用する場合ブラウザからのリクエスト文字列を工夫することで意図しないSQL文が組み立てられて情報の改ざんや漏洩することあります。それをSQLインジェクションと呼ぶものと認識しております。
SQLインジェクションの基本的な対策方法として、ブラウザからのリクエストなど、ユーザが入力したデータをエスケープ処理するというものがあると思います。
私は、SQLインジェクションに詳しくないのでエスケープ処理をちゃんと行っっていれば基本的に安心できるのではないか?と考えているのですがエスケープ処理を正しく行っていた場合にもユーザ(クラッカー)に想定しないSQL文を実行されてしまうことはあるのでしょうか?
このような質問をした理由としましては、SQL文を作成するにあたり、テンプレートエンジンを利用するのはどうか?と考えたためです。
なぜSQL文の作成にテンプレートエンジンを利用しようと思ったのかと言いますと、基本的なSQL関連のモジュールには?
マークを利用して値をエスケープしてフォーマットするような仕組みが備わっているものが多いと思いますが(参考:sqlstring)この単純な?
マークによる値代入が不便に感じたからです。
例えば、ユーザデータから年齢を指定して条件を絞って検索したい場合に
SELECT * FROM user WHERE age = ?
といったステートメントを記述し?
にブラウザのリクエストで受け取った年齢を挿入するという手順を踏むと思われますが、ブラウザからのリクエストに年齢データが含まれてない場合には全ての年齢のユーザを対象に検索をかけたいという場合にage = ?
を取り除かなければなりません。
このような問題を対策する場合
let age_sql = '1' if( age ) age_sql = 'age = ?' let sql = `SELECT * FROM user WHERE ${age}`
のように文字列を組み合わせて作成する必要が生まれます。(もちろんSELECT * FROM user WHERE ${age ? 'age = ?' : '1'}
で可能ですがfor文やif文を使いたい場合にはどうしてもコードが散らかってしまうかと思われます)
このような複雑なコードを書くならば、テンプレートエンジンを使ってスッキリ書いた方が良いのではないのか?と思った次第です。
lodashのtemplateを利用を想定したテンプレート文字列
SELECT * FROM user WHERE <% if( age ) { %> age = <%- age %> <% } %>
余計に複雑になってないか?とも感じますが、テンプレートエンジンを利用することでコード内に直接SQL文を書くことを避けることができますし、for文などを利用したい場合には確実にこちらの方がシンプルになるのではないかと考えています。
SQL文の作成にテンプレートエンジンを利用するといった話はあまり聞いたことがありませんが、もしこの実装方法で開発を進めていく場合、今まではDB関連のモジュールに標準で備わっていた?
を利用してエスケープ処理を任せていたが、そのような処理を独自に開発することになります。
テンプレートエンジンを利用するため独自に開発というと語弊がありますがもともとテンプレートエンジンはSQL専用のモジュールではないし?
のエスケープ処理がどのように行われているか詳しく理解せずに独自のやり方で実装すると思わぬ脆弱性を生んでしまうかもしれません。
そこで、SQLインジェクション対策は基本的にエスケープ処理をしっかり行っていれば良いのかみなさんにお聞きいたしました。
squelのようなライブラリの利用も検討したのですが、JSとSQLを記述するプログラマで役割をもし分けていたというようなことを考えるとあまり望ましくないのではないか?と思いました。
SQLインジェクション対策は基本的にエスケープ処理を行うだけで良いのでしょうか?
また、SQLの作成にテンプレートエンジンを使うことに対しても否定的な意見がありましたら是非ご指摘いただけるとありがたいです。
よろしくお願いいたします。

回答4件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/03/03 04:26
2017/03/03 04:32