SQL 注入缺陷是大多数动态网页所面临的共同问题,所有的 SQL 注入都是从用户的请求开始的,当一个动态网页程序(例如 ASP 、 JSP 等)中存在一个 SQL 查询,并且该 SQL 查询使用用户的请求数据作为参数时,用户可以提交一些数据作为 SQL 查询的参数(一般是在浏览器地址栏或者在 HTTP 消息报头中进行,它们都是通过正常的 WWW 端口访问),通常这些数据是非法字符,然后根据程序返回的结果,获得某些它想得知的数据,这就是所谓的 SQLInjection (即 SQL 注入)。
SQL Injection 构造符合条件的 SQL 语句绕过条件查询或者构造恶意的其它应用,例如使用下面的 URL 地址再次请求前面的网页: http://localhost/test.asp?Age=300or1'='1' 。
这意味着构成了如下的 SQL 语句:
select * from exampleTable where Age =300 or '1'='1'
因为 '1'='1' 肯定成立,所以可以通过任何条件子句,并返回结果,而不会出现错误信息。
设想一下,如果 SQL 语句是用来进行用户验证的,例如下面的语句:
sql = "select * from table where id= ' + yourID + ";' and passwd='" + yourPassword+";'
如果把" 'or '1'='1 "作为 yourPassword 查询变量的值传入进来,构造如下的一个查询字符串:
ourURL?yourName=anyString&yourPassword=anyString 'or '1'='1
这将会形成如下的 SQL 语句,从而轻松通过用户验证:
select * from table where id= 'anyString' and passwd='anyString' or '1' = '1'
更有甚者,把" ';DROP TABLE tb_name;' "作为 yourPassword 传入进来,则会形成如下的 SQL 语句,可能会删除数据库表:
select * from table where id= 'anyString' and passwd=";DROP TABLE tb_name;'
使用参数化查询可以防止恶意 SQL 注入。参数化查询为数据库访问应用程序开发提供了一种安全、封装性的方法,它可以将输入交由数据库进行预处理。
参数化查询指定 SQL 语句使用问号(?)作为参数占位符,例如下面的 SQL 语句:
sql = 'select \* from employees where Age = ?';
然后使用 executeSql() 方法的第 2 个参数为参数化查询中的问号赋值(问号将被第 2 个参数数组中对应的项替代),代码如下:
tx.executeSql(sql, [40]);
如果存在多个问号,那么顺次与数组中的项对应,代码如下:
sql = 'INSERT INTO employees (firstName,lastName,EmpType,age) VALUES (?,?,?,?)';
`js tx.executeSql(sql, ['myFirst','myLast','myEmpType',40]);