【SpringBoot】JdbcTemplateはSQLインジェクション対策できているのか
SpringBatchのプロジェクトにおいて、JdbcTemplateを使ってDBアクセス処理を書いていた際、「これってちゃんとSQLインジェクション対策できてるの?」という問いが生まれました。
公式を読んでみても「出来てるよ!」という明言が見つからなかったため、ライブラリの中身まで確認し、調査してみました。
想定読者
- JdbcTemplateってSQLインジェクションされてるのか不安な人
- SpringBatch実装したことがある人
- 検証にはSpringBatchプロジェクトを利用しています。ステップやジョブの概念など、細かいものは省きます。
そもそもSQLインジェクションってなんだっけ、と言う人向け
以下サイトを参考にしてみてください!
結論
JdbcTemplateはSQLインジェクション出来てると思って問題ないと思います。検証に利用したバージョンとメソッドは以下。
※調査内容が膨大になるので、今回一つのSELECT系メソッドのみで検証しました。
※鵜呑みにはせず、ご自身のプロジェクト内で議論/検討/判断のうえ利用するようにしてくださいね。
Version
spring-boot-starter-batch:2.7.0を利用しています。
内部的にはspring-jdbc:5.3.23が呼ばれてるようです。
検証したメソッド
queryForObject
※JavaDoc
なぜ出来てると言えるのか
プレースホルダ(=「?」)使いつつ、内部的にPreparedStatementで型チェックされてるから、です。具体的には以下。
実験
検証用リポジトリで遊んでみました。
検証ソースの軽い仕様説明
上記ソースは、バッチに引数TASK_ID
を与えて実行することで利用します。 TASK
テーブルのID
カラムの値が、与えた引数TASK_ID
と一致していた場合、検索に成功しタスク名を標準出力するようなものです。
TASK_ID=1
と引数を与えれば、以下のようにタスク名を出力してくれます。
インジェクションしようとしてみる
↑このサイトを参考に、' OR 1=1--
という変な引数(※)を与えて実行してみます。
※単純な文字列結合でSQL生成していた場合(ダメな例)には、生成されるSQLが ...WHERE id = '' OR 1 = 1 --
となり、全件抜き出しを許してしまうような引数です。
データ変換でバッチが落ちてくれました。対策できてそうです。
参考
公式JavaDoc
公式チュートリアル「Spring JDBC JdbcTemplate で SQL 発行」
https://spring.pleiades.io/guides/gs/relational-data-access/
Discussion