node.jsでMySQLの疑問符プレースホルダによるSQLインジェクション対策
提供: Node.js/JavaScript入門
スポンサーリンク
node.jsでMySQLサーバに接続し、SQLを実行するときにSQLインジェクション対策を忘れてはいけません。SQLインジェクション対策として、ここでは、疑問符プレースホルダを使用します。
読み方
- SQLインジェクション
- えすきゅーえる いんじぇくしょん
- 疑問符プレースホルダ
- ぎもんふ ぷれーすほるだ
概要
以下は、任意の番号を受け取って、その番号と一致するidのuserのデータを引っ張るときのSQLの例です。
SELECT * FROM USER WHERE id=番号
番号をSQL文と単純に連結するには、適切にエスケープしなければなりません。
var sql = 'select * from user where id=' + number;
エスケープをプログラマが意識せずに扱うには、疑問符プレースホルダが簡単です。 疑問符というのは、記号 ? のことです。
SELECT * FROM USER WHERE id=?
このSQLを実行するときに、? に部分に値をバインドして、SQLを実行します。自動的にSQLは、エスケープされます。
コードを部分的に抜粋すると、以下のようなコードになります。 query()の第2引数に、渡したい値を指定します。
var sql = 'select * from user where id=?'; var id = 1; var e = my_client.query(sql, [id], function (err, rows, fields) {
前提となるデータベースのテーブル
CREATE DATABASE test; USE test; CREATE TABLE test.USER (id INT, name VARCHAR(20)); INSERT INTO USER VALUES(1,'a'); INSERT INTO USER VALUES(2,'b');
ソースコード
/* * mysql_query1.js * Copyright (C) 2014 kaoru <kaoru@bsd> */ var db_host = '127.0.0.1'; var db_user = 'root'; var db_pw = ''; var db_name = 'test'; var mysql = require('mysql'); var mysql_options = { host: db_host, user: db_user, password: db_pw, database: db_name }; var my_client = mysql.createConnection(mysql_options); my_client.connect(); var sql = 'select * from user where id=?'; var id = 1; var e = my_client.query(sql, [id], function (err, rows, fields) { if (err) { console.log('can not connect'); console.log(err); return; } console.log('-- 1 --'); for (var i in rows) { console.log(rows[i].name); } }); id = 2; my_client.query(sql, [id], function (err, rows, fields) { if (err) { console.log('can not connect'); console.log(err); return; } console.log('-- 2 --'); for (var i in rows) { console.log(rows[i].name); } }); my_client.end();
実行例
$ node sql_query1.js -- 1 -- a -- 2 -- b
SQLインジェクションっぽい値を入れる
このSQLの番号、というところに 0 or 1=1 を入れて、
SELECT * FROM USER WHERE id=番号
以下のSQL文を組みたてることができると
SELECT * FROM USER WHERE id=0 OR 1=1;
以下のような結果になります。
MariaDB [test]> SELECT * FROM USER WHERE id=0 OR 1=1; +------+------+ | id | name | +------+------+ | 1 | a | | 2 | b | +------+------+ 2 ROWS IN SET (0.00 sec)
たとえば、上のコードを id を以下のようにします。
var sql = 'select * from user where id=?'; var id = '0 or 1=1'; var e = my_client.query(sql, [id], function (err, rows, fields) {
実際に、query()が作成したSQLを確認してみると
sql: 'select * from user where id=\'0 or 1=1\,
となります。結果、テーブルのデータ的には、何もマッチしなくなります。
以下、query()の戻り値の抜粋です。
{ domain: null, _events: { error: [Function], packet: [Function], end: [Function], timeout: [Function], 'start-tls': [Function] }, _maxListeners: 10, _callback: [Function], _callSite: [Error], _ended: false, _timeout: undefined, _idleNext: null, _idlePrev: null, _idleStart: null, _idleTimeout: undefined, _repeat: null, sql: 'select * from user where id=\'0 or 1=1\'',
このように、疑問符プレースホルダを使用すると、自動的に値がエスケープされます。
関連項目
- node.jsでMySQLに接続する
- node.jsでMySQLの疑問符プレースホルダによるSQLインジェクション対策
ツイート
スポンサーリンク