不采用SQL拼接,而采用SQL语句的预编译(prepare)和查询参数绑定功能。
#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。
order by语句后用了${},那么不做任何处理的时候是存在SQL注入危险的。更精确的过滤则可以查询一下输入的参数是否在预期的参数集合中。
第二种避免SQL注入攻击的方式:存储过程。存储过程(Stored Procedure)是一组完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过调用存储过程并给定参数(如果该存储过程带有参数)就可以执行它,也可以避免SQL注入攻击。
用户也可以在前端做字符检查,这也是一种避免SQL注入的方式:比如对于上面的userId参数,用户检查到包含分号就提示错误。
最根本的原因看,SQL注入攻击之所以存在,是因为app在访问数据库时没有使用最小权限。