Spring

【SpringBoot】JdbcTemplateはSQLインジェクション対策できているのか

2022年11月21日

SpringBatchのプロジェクトにおいて、JdbcTemplateを使ってDBアクセス処理を書いていた際、「これってちゃんとSQLインジェクション対策できてるの?」という問いが生まれました。

公式を読んでみても「出来てるよ!」という明言が見つからなかったため、ライブラリの中身まで確認し、調査してみました。

ITエンジニア6年目の山根です。X(Twitter)やってます。自己紹介,お問い合わせはこちらまで!

想定読者

  • JdbcTemplateってSQLインジェクションされてるのか不安な人
  • SpringBatch実装したことがある人
    • 検証にはSpringBatchプロジェクトを利用しています。ステップやジョブの概念など、細かいものは省きます。

そもそもSQLインジェクションってなんだっけ、と言う人向け

以下サイトを参考にしてみてください!

www.ipa.go.jp

結論

JdbcTemplateはSQLインジェクション出来てると思って問題ないと思います。検証に利用したバージョンとメソッドは以下。

※調査内容が膨大になるので、今回一つのSELECT系メソッドのみで検証しました。

※鵜呑みにはせず、ご自身のプロジェクト内で議論/検討/判断のうえ利用するようにしてくださいね。

Version

spring-boot-starter-batch:2.7.0を利用しています。

内部的にはspring-jdbc:5.3.23が呼ばれてるようです。

スクリーンショット 2022-11-06 20.00.13.png

検証したメソッド

queryForObject

※JavaDoc

https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html#queryForObject-
java.lang.String-org.springframework.jdbc.core.RowMapper-java.lang.Object..

スクリーンショット 2022-11-06 20.15.36.png

https://github.com/spring-projects/spring-framework/blob/main/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java#L883-L888

なぜ出来てると言えるのか

プレースホルダ(=「?」)使いつつ、内部的にPreparedStatementで型チェックされてるから、です。具体的には以下。

https://github.com/spring-projects/spring-framework/blob/main/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java#L694-L733

実験

検証用リポジトリで遊んでみました。

https://github.com/kannna5296/jdbctemlate_example

検証ソースの軽い仕様説明

上記ソースは、バッチに引数TASK_IDを与えて実行することで利用します。
TASKテーブルのIDカラムの値が、与えた引数TASK_IDと一致していた場合、検索に成功しタスク名を標準出力するようなものです。

TASK_ID=1と引数を与えれば、以下のようにタスク名を出力してくれます。

スクリーンショット 2022-11-06 20.24.57.png

インジェクションしようとしてみる

https://marunouchi-tech.i-studio.co.jp/2056/

↑このサイトを参考に、' OR 1=1--という変な引数(※)を与えて実行してみます。

※単純な文字列結合でSQL生成していた場合(ダメな例)には、生成されるSQLが ...WHERE id = '' OR 1 = 1 -- となり、全件抜き出しを許してしまうような引数です。

スクリーンショット 2022-11-06 20.26.24.png

データ変換でバッチが落ちてくれました。対策できてそうです。

参考

公式JavaDoc

https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html

公式チュートリアル「Spring JDBC JdbcTemplate で SQL 発行」

https://spring.pleiades.io/guides/gs/relational-data-access/

-Spring