是否了解SQL注入及预编译防护原理?

1 个回答

  • 沙之影
    明知不可为而为之就是我最大的诚意
    ## 作用 - **SQL 注入**:攻击者在用户输入中插入额外 SQL 片段,程序若通过字符串拼接构造 SQL,数据库会把这些输入当成 SQL 语法执行,可能造成数据泄露、篡改、删除甚至命令执行。 - **预编译/参数化查询**:将 SQL 结构和参数值分离,用户输入只作为普通参数值传递,不会被解释成 SQL 指令,从而从根本上防止 SQL 注入。 - 典型注入方式包括: - **布尔盲注**:根据页面返回差异逐字符猜测数据。 - **时间延迟注入**:通过 `SLEEP` 等函数造成响应延迟来判断条件。 - **联合查询注入**:利用 `UNION SELECT` 把其他表的数据拼接到查询结果中。 ## 原理 ### 1. 危险写法:字符串拼接 例如登录查询直接拼接用户名和密码: ```sql SELECT * FROM users WHERE username = '$username' AND password = '$password' ``` 当用户名输入: ```text admin' OR '1'='1 ``` 拼接后的 SQL 变成: ```sql SELECT * FROM users WHERE username = 'admin' OR '1'='1' ``` 由于 `OR '1'='1'` 恒为真,查询可能返回用户表中的数据,导致绕过登录。 ### 2. 安全写法:预编译参数绑定 先固定 SQL 模板: ```sql SELECT * FROM users WHERE username = ? ``` 再通过占位符绑定参数: ```python query = "SELECT * FROM users WHERE username = ?" cursor.execute(query, (username,)) ``` 即使用户输入 `admin' OR '1'='1`,数据库也只会把它整体当作用户名字符串,而不会执行其中的 `OR`、引号等 SQL 语法。 ### 3. 预编译的核心区别 - **字符串拼接**:用户输入参与 SQL 语法解析,可能改变原有 SQL 逻辑。 - **参数化查询**:SQL 语句结构先确定,参数后传入,输入始终只是值。 - 数据库或驱动会负责参数转义和绑定,特殊字符不会逃逸成 SQL 代码。 - 预编译语句还可能被数据库复用执行计划,带来一定性能优势。 ### 4. 使用要点 - 所有外部输入,包括请求参数、表单、Cookie、HTTP 头等,都不应直接拼接进 SQL。 - 优先使用 `PreparedStatement`、参数化 API 或安全 ORM。 - 表名、列名、排序字段等不能作为普通参数绑定的部分,应使用白名单限制。 - 参数化查询是核心防护,输入校验、最小权限、WAF 和 ORM 可作为辅助防御手段。
    发布于 2026-10-22 02:08 •IP属地 北京
    举报
    评论
    收藏