跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何防止SQL注入非法提权_严格控制数据库系统权限

SQL注入能否直接提权取决于数据库账户权限是否失控;绝大多数提权源于应用使用root/sa等超级账户连接,而非漏洞本身强度,因此须实施权限最小化策略,禁用高危权限如FILE、CREATE、SUPERUSER等。 SQL注入能直接提权?先看数据库账户权限是否失控 绝大多数SQL注入导致的提权,根本不是漏洞本身有多强,而是应用连数据库都用
root
或
sa
这类超级账户连接。一旦注入成功,攻击者就等于拿到数据库的“管理员钥匙”。 防不住注入时,权限最小化就是最后一道闸门。 生产环境绝不能用
root
(MySQL)、
sa
(SQL Server)、
postgres
(PostgreSQL)等默认高权限账号连接应用 为每个业务模块创建独立账号,比如
app_user_order
、
app_user_report
,只赋予对应库表的
SELECT
、
INSERT
、
UPDATE
权限,禁用
DROP
、
CREATE
、
ALTER
、
EXECUTE
、
FILE
确认权限是否生效:用该账号登录后执行
SHOW GRANTS
(MySQL)或
\du+
+
\dp
(PostgreSQL),别只信配置文件里写了啥 为什么 prepared statement 不能代替权限控制 很多人以为用了
PreparedStatement
(Java)、
pg_query_params
(PHP)、
cursor.execute(sql, params)
(Python)就万事大吉——其实它只防参数拼接型注入,对动态表名、列名、
ORDER BY
子句、
UNION SELECT
后的结构控制完全无效。这时候如果账号权限过大,照样能拖库甚至写 shell。
SELECT * FROM ? WHERE id = ?
—— 第一个
?
在绝大多数驱动里根本不支持参数化,会直接报错或被忽略
ORDER BY ?
虽然语法上允许,但实际可能绕过类型检查,拼进恶意字段如
id; DROP TABLE users--
即便所有查询都参数化,若账号有
SELECT INTO OUTFILE
(MySQL)或
COPY ... FROM PROGRAM
(PostgreSQL),仍可能通过注入触发系统命令执行 MySQL 中 FILE 权限是提权高危项,必须显式回收 只要数据库账号有
FILE
权限,配合注入就能读取服务器任意可读文件(如
/etc/passwd
、Web 配置),甚至写入 Web 目录生成一句话木马。这个权限和增删改查无关,却常被忽略。 检查当前用户是否有
FILE
:执行
SELECT * FROM mysql.user WHERE User='app_user' AND File_priv='Y';
回收命令是
REVOKE FILE ON *.* FROM 'app_user'@'%';
,不是
DROP
或注释掉配置 某些云数据库(如阿里云 RDS)默认关闭
secure_file_priv
,但仍需人工确认账号无
FILE
权限,不能依赖平台限制 PostgreSQL 的 public schema 和默认角色要特别当心 PostgreSQL 默认把新用户加进
public
schema,且
public
对所有用户可读写。一旦注入点出现在建表、临时表或函数调用场景,攻击者可能创建恶意函数或覆盖已有视图。 执行
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
,再为必要用户单独授权 避免使用
CREATEROLE
或
SUPERUSER
属性,哪怕只给一个运维账号也极危险 检查是否存在未审计的自定义函数,如
CREATE OR REPLACE FUNCTION exec_cmd(text) RETURNS text AS $$...$$ LANGUAGE plsh;
—— 这类函数本身就是提权后门 权限控制不是设完就完的事。每次上线新功能、接入新服务、迁移数据库,都要重新核对账号权限清单。最麻烦的是——你永远不知道哪行日志里藏着一句没走参数化的
query
,所以数据库账号必须从第一天起就按“已被注入”来设计。

相关文章