Spring SpEL的#{variable}是否能抵御SQL注入攻击?
#{variable} in Spring Expression Language (SpEL) protect against SQL injection? Hey there! Let's start by clearing up a critical confusion here: the #{ID} syntax in your MyBatis mapper is not SpEL (Spring Expression Language). That's actually MyBatis's native parameter binding syntax, and it's built specifically to defend against SQL injection. Let's break this down:
1. MyBatis #{...} vs. SpEL #{...}
SpEL uses #{...} in contexts like @Value("#{someBean.property}") or Spring configuration to evaluate expressions. But in MyBatis mappers, #{...} is a placeholder for parameter binding—this has nothing to do with SpEL. That's why you couldn't find SpEL-related docs about SQL injection for your mapper code: they're unrelated technologies here.
2. How MyBatis #{...} prevents SQL injection
When you use #{ID} in your SQL statements:
- MyBatis replaces the placeholder with a JDBC
?parameter marker, creating aPreparedStatementunder the hood. - It then safely sets the parameter value using JDBC's parameter binding, which automatically escapes special SQL characters (like single quotes, semicolons, etc.).
- This means user input is never directly concatenated into the SQL string—so even if someone passes malicious input like
1'; DROP TABLE url;--, it will be treated as a literal value for theIDparameter, not executed as part of the SQL command.
3. Your code is safe
Looking at your mapper code:
@Mapper public interface UrlInfoMapper { public static final String SELECT_BY_ID = "select * from url WHERE ID=#{ID}"; public static final String DELETE_BY_ID = "DELETE FROM url WHERE ID=#{ID}"; @Select(SELECT_BY_ID) UrlInfo getFromUrlById(String ID); @Update(DELETE_BY_ID) void delete(@Param("ID")String ID); }
Both SELECT_BY_ID and DELETE_BY_ID use #{ID}, so these queries are protected against SQL injection. You don't need to manually escape characters here—MyBatis handles it for you.
4. What to watch out for
The risky syntax in MyBatis is ${...}, which directly substitutes the parameter value into the SQL string without any escaping. If you used ${ID} instead of #{ID}, that's when you'd be vulnerable to SQL injection. But your code doesn't do this, so you're in the clear.
内容的提问来源于stack exchange,提问作者Chloe

