JavaScriptの変数をSQL文に入れる方法とSQLインジェクションの回避

nodejs-secure-sql
  • URLをコピーしました!

SQL文の中にJavaScriptの変数を入れたい場合、何も考えずにSQLと変数を連結させたり、テンプレートリテラルSQL文を作成すると、SQLインジェクションのリスクが高くなります。
そこで今回は、JavaScript変数プレースホルダーを上手に活用して、SQLインジェクションのリスクが少ないセキュアなSQL文を作成する方法をご紹介します!

目次

SQLインジェクションとは

この手の話は定番中の定番なので、既にご存知の方は読み飛ばしちゃってください。

SQLインジェクションとは、アプリケーションのセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法のことです。

例えば、以下のようなコードがあったとします。

上記は悪い例ですので、このようなコードは絶対に書かないでください。

このコードでは、name変数にユーザーが入力した値がそのままSQL文に埋め込まれています。
もしnameが以下のような値を入力したらどうなるでしょうか?

この場合、SQL文は以下のようになります。

ここで、はコメント記号であり、それ以降の文字列は無視されます。
つまり、このSQL文は「nameが空文字かどうか、または1が1かどうか」という条件でusersテーブルから全てのレコードを取得することになります。
これは明らかにアプリケーションが想定していない動作です。

さらに悪意のあるユーザーは、データベースの内容を盗み見たり、削除したり、改ざんしたりすることも可能です。

SQLインジェクションについてもっと詳しく知りたい方は、こちらのサイトが参考になります!

著:伊藤 康太
¥3,212 (2024/04/17 10:51時点 | Amazon調べ)

プレースホルダーを使ってSQLインジェクションを回避

JavaScriptSQL文を書く際に使用するプレースホルダーとは、SQL文の中に埋め込む変数のようなものです。
プレースホルダーを使うと、SQLインジェクションなどの攻撃を防ぐことができます。

プレースホルダーの書き方

プレースホルダーの書き方は、使用するライブラリやデータベースによって異なりますが、一般的には?$1などの記号を使います。
例えば、以下のようなSQL文があります。

このSQL文では、nameの値が固定されていますが、プレースホルダーを使うと以下のように書けます。

または

この場合、?$1に対応する値を別途指定する必要があります。
JavaScriptでは、以下のようにqueryメソッド第2引数に配列で渡すことができます。

プレースホルダーを使ったSQL文

JavaScriptSQL文の中に変数を入れたい場合は、変数の値を""で囲む必要があります。
例えば、以下のようなコードです。

また、mysqlモジュールを使っている場合は、プレースホルダー?)を使って変数を埋め込むこともできます。
例えば、以下のようなコードです。

どちらの方法もSQLインジェクションのリスクを減らすことができます。

テンプレートリテラルを使ったSQL文

テンプレートリテラルの基礎

テンプレートリテラルとは、文字列をグレイヴ・アクセントで囲み、変数ドル記号と波括弧でくくることで、文字列に変数の値を埋め込むことができる機能です。
テンプレートリテラルの書き方は、以下のようになります。

  • 文字列をグレイヴ・アクセント(`)で囲む
  • 変数や式を埋め込む場合は、ドル記号($)と波括弧({})でくくります。
  • 改行やタブなどの空白文字はそのまま反映されます。

例えば、以下のようなコードがあります。

このコードでは、message変数には以下のような文字列が代入されます。

テンプレートリテラルとは、文字列を定義するときに変数を使用したり、ソース上の改行をそのまま取り込めるというものです。
SQL文の書き方にも便利ですが、注意点もあります。

SQL文で使うと危険!

上記の通り、テンプレートリテラルは大変便利に機能ですが、こちらもやはりそのままSQLの中にJavaScriptの変数を書くのは危険です。

例えば、以下のようにテンプレートリテラルSQL文を作成します。

この場合、変数nameageの値がSQL文に埋め込まれます。
しかし、この方法はSQLインジェクションという攻撃手法に対して脆弱です。

攻撃を防ぐためにも、やはりプレースホルダーを使ってSQL文を作成する必要があります。
例えば、以下のようにテンプレートリテラルプレースホルダーSQL文を作成することができます。

この場合、変数nameに不正な値が入力されても、その値は文字列リテラルとして扱われるため、想定外の命令は実行されません。

以上がテンプレートリテラルを使ったSQL文の書き方です。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次