[JAVA] Watch out for embedded variables in S2Dao

About S2Dao, which has just been EOLed. I use it for business, but it is dangerous if I use it incorrectly, so make a note of it.

Embedded variables

S2Dao provides embedded variables. If you use it incorrectly, it will behave very dangerously, so make a note of it.

How to use embedded variables

The embedded variable is described as follows.

/ \ * $ Argument name * / literal

Actual code

BalanceDao


@S2Dao(bean = Balance.class)
public interface BalanceDao {
    @Sql("select id, name, amount, created_at, updated_at from balance where name = '/*$name*/'Tanaka''")
    public List<Balance> findByName(String name);
}

I will move it

curl


$ curl -G "localhost:8080/sastruts/balance/findname" --data-urlencode "name=Taro Tanaka"
id:1name:Taro Tanaka created_ad:2019-05-03 19:25:33.0updated_ad:null

Runtime log


DEBUG 2019-05-04 12:51:36,087 [http-nio-8080-exec-5] select id, name, amount, created_at, updated_at from balance where name = 'Taro Tanaka'

In this way, you can see that the part (embedded variable) set in / * $ name * / is replaced and SQL is executed.

SQL injection

Then, what is dangerous about embedded variables is that the SQL part is replaced with the contents of the argument as it is, so there is a danger of SQL injection.

I'll give it a try.

Try SQL injection

curl


$ curl -G "localhost:8080/sastruts/balance/findname" --data-urlencode "name=A'or'A'='A"
id:1name:Taro Tanaka created_ad:2019-05-03 19:25:33.0updated_ad:null
id:2name:Hanako Sato created_ad:2019-05-03 23:48:40.0updated_ad:null

Runtime log


DEBUG 2019-05-04 12:54:57,636 [http-nio-8080-exec-6] select id, name, amount, created_at, updated_at from balance where name = 'A'or'A'='A'

In this way, all the data can be acquired.

Countermeasures

I think there are two ways to deal with it.

Basically, I think it's better to use bind variable comments.

Usage is simple. Just specify the following:

/ \ * Argument name * / literal

Example of using bind variables

BalanceDao


@Sql("select id, name, amount, created_at, updated_at from balance where name = /*name*/'Tanaka'")
public List<Balance> findByName(String name);

Try SQL injection.

Nothing is returned


$ curl -G "localhost:8080/sastruts/balance/findname" --data-urlencode "name=A'or'A'='A"
$

Runtime log


DEBUG 2019-05-04 13:01:31,270 [http-nio-8080-exec-3] select id, name, amount, created_at, updated_at from balance where name = 'A'or'A'='A'

It looks like the SQL injection was successful on the execution log, but nothing was actually returned.

reference

S2Dao Reference

Recommended Posts

Watch out for embedded variables in S2Dao
Things to watch out for in Java equals
Things to watch out for in future Java development
[Ransack] Watch out for ransackable_scopes!
Things to watch out for when creating a framework
Use variables for class and id names in haml
Things to watch out for when using Deeplearning4j Kmeans
What is object-oriented after all or just one thing to watch out for in programming
[Java] Make variables in extended for statement and for Each statement immutable