こんにちは。セキュリティの世界で「盾」を握り続けている者です。
今日は、開発現場で避けては通れない「SQLインジェクション」についてお話しします。難しそうな名前ですが、要は「プログラムを騙して、想定外の命令を実行させるズル」のことです。
特にSpring Frameworkを使っている皆さん、JdbcTemplateを便利に使っているつもりが、実は「家の鍵をわざと開けて寝ている」ような状態になっていないか、一緒に確認していきましょう。
—
1. なぜ「文字列連結」は泥棒を招くのか?
まず、身近な例で考えてみましょう。あなたは受付係です。来客者が名前を書く紙に「山田太郎」と書けば、あなたは「山田さんですね、どうぞ」と通しますよね。
しかし、もし悪意のある人が「山田太郎です。そのあと、裏口の鍵も開けておいてね」と書いたらどうでしょう? あなたがその言葉をそのまま信じて実行してしまったら、泥棒は堂々と裏口から侵入してきます。
これがプログラムで言う「文字列連結によるSQL構築」です。
// 【絶対にやってはいけない例】
String name = request.getParameter(“name”); // ユーザーが入力した値
// 危険!「’ OR ‘1’=’1」なんて入力されたら、全てのデータが漏洩します
String sql = “SELECT FROM users WHERE name = ‘” + name + “‘”;
jdbcTemplate.query(sql, …);
このコードでは、ユーザーの入力内容をそのまま「命令文」の一部として混ぜてしまっています。攻撃者はこの隙を突き、データベースの中身を根こそぎ盗み出すクエリを注入してくるのです。
—
2. 解決策:バインド変数という「専用の隔離スペース」
では、どうすればいいのでしょうか? 答えは「バインド変数」を使うことです。
これは、受付の例で言うなら「名前を書く欄には、名前以外の命令を書かせない」というルールを徹底することです。入力値はあくまで「ただの文字(データ)」として扱い、決して「命令(プログラムの一部)」としては解釈させない。これが防御の鉄則です。
NamedParameterJdbcTemplate で安全に守る
Springでは、NamedParameterJdbcTemplateを使うのが現代の標準的な守り方です。これを使うと、クエリの構造とデータを完全に切り離すことができます。
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
// 安全なコードの書き方
public void findUser(String name) {
// 1. 命令部分は固定しておく(:name はプレースホルダー)
String sql = “SELECT FROM users WHERE name = :name”;
// 2. ユーザーの入力は「データ」としてMapに詰める
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue(“name”, name); // これが安全な受け渡し
// 3. 実行!
// データベースは「:name」の中身を命令として解釈せず、ただの文字列として検索します
namedParameterJdbcTemplate.query(sql, params, …);
}
この書き方なら、たとえ攻撃者が' OR '1'='1のような悪意ある文字列を入力しても、データベースはそれを「そういう名前のユーザーがいるかどうか」を探すためだけに使い、決して「命令」として実行することはありません。泥棒が何を叫ぼうが、受付のシステム自体には影響を与えないのです。
—
3. 私からのアドバイス:セキュリティは「疑う」ことから始まる
現場で長くシステムを見ていると、時々「これくらいなら大丈夫だろう」という油断が大きな事故に繋がる場面を何度も見てきました。
- 入力値は全て「毒」だと思え: ユーザーから来るデータは、どんなに誠実そうに見えても、まずは疑ってかかるのが一流のエンジニアです。
- テンプレートエンジンを信じすぎない: Springがいくら優秀でも、使い方を間違えれば無力です。
JdbcTemplateを使う際は、必ずプレースホルダー(?や:name)を使う癖をつけましょう。
セキュリティは、一度設定して終わりではありません。泥棒が常に新しい手口を考えるように、私たちも常に「どうすれば守れるか」を考え続ける必要があります。
最初は面倒に感じるかもしれません。でも、この「ひと手間」が、あなたの大切なシステムと、その先にいるユーザーの信頼を守る最強の鍵になります。
さあ、今日から「文字列連結」のコードを見かけたら、すぐにリファクタリングしてしまいましょう。それが、頼れるエンジニアへの第一歩です!
—
執筆者: シニア・セキュリティ・アーキテクト
「システムは壊れるものではなく、守るためにある。そのための杖として、この知見を捧げます。」
コメント