1

I'd like to check my input string for potential SQL-Injection.

Here is my class, method and query:

public class UserNamesQuery {

   public static String getUserNames(Map<String, Object> params) {
       String userNames = (String) params.get("userNames");
       return "SELECT * FROM users WHERE name IN (" + userNames + ") ";
   }

}

Is there a tool or a quick way to validate that userNames is without SQL-Injection?

Notice that I use Mybatis

4
  • 3
    You probably want to use a PreparedStatement instead of reinventing the wheel. Commented Mar 7, 2016 at 12:02
  • 2
    Prepared statements is good advice, but this in an IN value list. PreparedStatement with list of parameters in a IN clause Commented Mar 7, 2016 at 12:09
  • @AlexK. is correct - I have an issue with IN Commented Mar 7, 2016 at 12:11
  • 1
    Any issue can be solved using the proper way. Commented Mar 7, 2016 at 12:15

3 Answers 3

8

No. There is no way. And no need.

To be frank, there is no such thing like "SQL injection". There is only an exploit of improperly formatted query.

So, instead of hunting down whatever "injections" you have to format your queries properly, by means of using prepared statements.

Any data, depends on context, could be either a potential injection or a harmless chunk of text. So, with whatever filtering function there will be too much false positives. Worse yet, whatever filtering is a "black list" implementation, means it will always be incomplete - it's just impossible to filter out all the codes used to exploit an injection.

On the other hand, prepared statement is a relatively simple solution that will be immune to any type of injection without even knowing them. Just because it won't let the data to interfere with the query.

Sign up to request clarification or add additional context in comments.

5 Comments

How would you purpose to overcome the IN in my query, and how can I apply it to mybatis?
And no problem with MyBatis there, since you can give the parameters as #{parameterName} which will be automatically translated into a prepared statement. For your IN clause, you typically use a foreach statement in the MyBatis mapping.
@Florian Schaetz how do I do that exactly? maybe you'll write it in a separate answer
To answer that question completely, I would have to reproduce the whole MyBatis documentation. Start with mybatis.org/mybatis-3/getting-started.html , then have a look at mybatis.org/mybatis-3/dynamic-sql.html#foreach - If there are more specific questions open after you tried that, simply ask them in a new question, since YCS' answer is completely correct for this one.
Just a little addition: Especially important for you is the chapter about parameters mybatis.org/mybatis-3/sqlmap-xml.html#Parameters and especially String substitutions mybatis.org/mybatis-3/sqlmap-xml.html#String_Substitution (in short: Don't use them for user input, use parameters instead - and as an addition: NEVER, EVER build your query with user input. ). This article might also help somewhat: software-security.sans.org/developer-how-to/…
0

Sanitizing input is not the way to prevent injections like this. Using prepared statements is the way to go.

PreparedStatement ps = connection.prepareStatement("SELECT * FROM users WHERE username IN (?)"); //Add however many ?'s you want, if you have an array you can use a StringBuilder for this to add more ?'s
ps.setString(1, userName);
ResultSet rs = ps.executeQuery();

This will set the ? in the code to your string. The database driver then handles the rest. If you have multiple values in the IN clause, use a StringBuilder and a loop to add more Questionmarks.

Also notice how the indexing starts with 1 instead of 0.

Comments

-1

mybatis sql template may be a good choose. FYI:

<sql id="orderTypeSql">
    <trim prefix=" ">
        <if test="orderType=='desc'">desc</if>
    </trim>
</sql>

<sql id="oderColumnSql">
    <trim prefix="order by " suffix="" >
        <choose>
            <when test="orderColumn==null or orderColumn==''"></when>
            <when test="orderColumn=='id'">
                id<include refid="orderTypeSql"/>
            </when>
            <when test="orderColumn=='name'">
                `name`<include refid="orderTypeSql"/>
            </when>
        </choose>
    </trim>
</sql>

<select id="testOrderBy" resultType="User">
    select
    id,
    `name`
    from t_user
    <include refid="oderColumnSql"/>
    limit 0, 10
</select>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.