Skip to content

注入攻击

SQL 注入、命令注入、防护与 ORM。

Updated View as Markdown
For humans

注入攻击

注入是历史最悠久也最致命的漏洞:用户输入被当作代码执行。面试必考 SQL 注入。

SQL 注入

-- 危险: 用户输入直接拼接
SELECT * FROM users WHERE name = 'admin' OR '1'='1'  -- 恒真, 绕过登录

-- 变体: 时间盲注
SELECT ... WHERE id = 1 AND SLEEP(5)  -- 逐字符探测
类型 原理
联合注入 UNION 拼接查询其他表
报错注入 构造报错带出数据
布尔/时间盲注 无回显时逐字符探测

根因:SQL 语句和数据混在一个字符串里,数据库无法区分。

防护:参数化查询

# 正确: 参数化, 数据与语句分离
cursor.execute("SELECT * FROM users WHERE name = %s", (name,))

# 错误: 字符串拼接
cursor.execute(f"SELECT * FROM users WHERE name = '{name}'")
  • 参数化查询(预编译)是根治:语句结构固定,输入只当数据
  • ORM(SQLAlchemy)默认参数化,但要小心原生 SQL 和 raw 方法
  • 转义是次选(容易漏),白名单校验是辅助(ID 校验数字)

命令注入

# 危险: 拼接 shell 命令
os.system("ping " + host)   # host = "1.1.1.1; rm -rf /"

# 正确: 参数列表, 不走 shell
subprocess.run(["ping", host])
  • 根因:用户输入进入 shell 解释器
  • 防护:用参数列表传参(不经 shell)、白名单校验输入、最小权限运行

其他注入

类型 机制 防护
NoSQL 注入 操作符注入($ne、$gt) 类型校验、白名单
LDAP/XPath 注入 查询拼接 参数化/转义
模板注入(SSTI) 模板引擎执行 不信任用户模板、沙箱

面试追问

  1. SQL 注入原理? 用户输入拼进 SQL,数据和代码混淆。数据库把输入当语句执行
  2. 怎么根治? 参数化查询:语句和数据分离。ORM 默认安全,原生 SQL 要小心
  3. 盲注是什么? 无回显时用布尔/时间差异逐字符探测数据
  4. 命令注入怎么防? 参数列表传参(不经 shell)、白名单、最小权限
  5. ORM 一定安全吗? 不一定:raw SQL、拼接查询(filter 里拼字符串)仍有风险
Navigation

Type to search…

↑↓ navigate↵ selectEsc close