
在360安全产品(如引擎)中,防止SQL注入的核心策略是通过输入端严格验证(白名单过滤危险字符)、执行端参数化查询(分离SQL与参数)、结合ORM框架安全配置(自动转义与禁用动态拼接),实现“输入-处理-执行”全链路防护,确保用户输入不会篡改SQL逻辑。
SQL注入是指恶意用户通过在输入字段中插入特殊字符(如单引号、分号),构造恶意SQL语句,绕过应用逻辑执行非法操作。具体策略如下:
?或命名参数)传递,数据库引擎按原样执行参数,不会解析参数中的SQL(参数被当作数据而非代码处理)。类比:填空题,用户输入是“空格里的内容”,SQL是“题目”,数据库按题目原样执行,空格内容不影响题目逻辑。setString)传递参数,减少手动拼接SQL的风险。类比:ORM工具自动帮你处理SQL拼接,避免手动拼接时出错。| 方法 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 输入验证 | 对用户输入进行字符过滤或格式校验 | 依赖手动规则,可能遗漏复杂注入 | 简单表单、非复杂查询 | 需覆盖所有输入点,否则易被绕过 |
| 参数化查询 | 将SQL语句与参数分离,参数作为占位符传递 | 防止SQL解析,性能较高 | 大多数应用,尤其是动态SQL | 需正确使用占位符(如?或命名参数) |
| ORM框架安全配置 | ORM工具自动处理SQL拼接,提供安全方法 | 减少手动错误,支持复杂查询 | 使用ORM框架的应用 | 需配置安全选项(如自动转义、禁用动态SQL拼接) |
假设360引擎中用户登录场景,用户输入用户名“admin' or '1'='1”,密码“123”。正确处理(参数化查询)的伪代码(Python + SQLAlchemy):
username = request.form.get('username')
password = request.form.get('password')
# 参数化查询
result = session.query(User).filter(User.username == username, User.password == password).first()
if result:
# 登录成功
else:
# 登录失败
恶意输入“admin' or '1'='1”和“123”,参数化查询后,SQL变为SELECT * FROM users WHERE username = 'admin' or '1'='1' AND password = '123',数据库按原样执行,不会执行“or '1'='1”逻辑(参数被当作字符串处理)。
(若使用MyBatis,配置如下:)
<select id="selectUser" resultType="User">
SELECT * FROM users WHERE username = #{username} AND password = #{password}
</select>
输入验证时,用户名通过正则表达式过滤,仅允许字母数字,过滤单引号后,恶意输入被拦截。
在360安全产品中,防止SQL注入主要采用三方面策略:一是输入验证,对用户输入进行白名单过滤(如用户名仅允许字母数字),过滤单引号、分号等危险字符;二是参数化查询,将SQL语句与参数分离,用占位符(如?)传递参数,数据库按原样执行,不会解析参数中的SQL(比如登录时用SELECT * FROM users WHERE username = ? AND password = ?,传入用户名和密码,即使输入“admin' or '1'='1”,也不会改变查询逻辑);三是ORM框架安全配置,比如MyBatis的<set>标签自动转义,Hibernate的setString方法处理参数,减少手动拼接SQL的风险。通过这些措施,从输入到执行全链路防护,有效防止SQL注入攻击。
setString、setParam)传递参数,确保参数与SQL语句分离。?占位符或安全函数处理拼接部分)。sql = f"SELECT * FROM users WHERE username = '{username}'"),此时用户输入“admin' or '1'='1”会改变SQL逻辑。sql = f"SELECT * FROM users WHERE id = {user_id}",若user_id来自用户输入,且未转义,可能导致注入。