GraphQL的SQL注入风险源于Resolver中直接拼接用户输入,而非协议本身;正确做法是所有数据库操作必须使用参数化查询,并对输入严格校验、过滤与白名单控制。

GraphQL Resolver里直接拼接SQL就是高危操作
GraphQL本身不执行SQL,但很多开发者在Resolver函数中把用户传入的参数直接拼进SQL字符串,这等于把SQL注入漏洞从REST接口原样搬到了GraphQL层。典型错误写法像这样:db.query(`SELECT * FROM users WHERE id = ${args.id}`)——只要args.id没校验,攻击者填个1 OR 1=1就能绕过条件。
- 这种写法在Node.js(Apollo)、Python(Graphene、Strawberry)、PHP(Webonyx)里都存在,不是语言问题,是逻辑误判
- GraphQL查询字段名、嵌套结构不会触发SQL注入,真正危险的是解析器里对
args或context中原始输入的处理 - ORM/Query Builder也不能盲目信任:比如TypeORM的
createQueryBuilder().where("id = " + args.id)照样中招,必须用参数占位符
所有参数必须走预编译或参数化查询
无论用什么数据库驱动,只要涉及用户输入参与WHERE、ORDER BY、LIMIT等子句,就必须剥离执行逻辑与数据内容。核心原则只有一条:变量值绝不能出现在SQL字符串拼接中。
- Node.js + PostgreSQL:用
pg的参数化语法,client.query('SELECT * FROM users WHERE id = $1', [args.id]) - Python + SQLAlchemy:用
session.query(User).filter(User.id == args['id']),避免.filter(text("id = %s" % args['id'])) - PHP + PDO:绑定参数,
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$args['id']]); - 特别注意ORDER BY和LIMIT:它们不支持标准占位符,需白名单校验字段名或数值范围,例如
if (!in_array($args['sort'], ['name', 'created_at'])) { throw new Error('Invalid sort field'); }
Resolver层要做最小权限输入校验
参数化只是基础,Resolver还应承担第一道过滤职责。不能假定前端传来的id一定是数字、email一定符合格式,更不能让args原封不动流进数据库操作。
- 对ID类参数,强制转整型或使用UUID验证:
parseInt(args.id, 10)或uuid.validate(args.id) - 对字符串类参数,限制长度并过滤控制字符:
args.search.trim().substring(0, 100).replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/g, '') - 对布尔/枚举类参数,严格比对合法值:
if (args.status !== 'active' && args.status !== 'inactive') throw new Error('Invalid status') - 避免在Resolver里调用
eval()、Function()、JSON.parse()等可执行任意代码的函数处理用户输入
复杂场景下别硬扛,该切就切
有些业务逻辑天然不适合用参数化处理,比如动态表名、字段名、复杂搜索条件组合。这时候强行“安全拼接”反而容易漏掉边界情况,不如明确拆分责任。
- 动态表名:改用配置驱动,把允许的表名写死在白名单数组里,用
args.tableName查表,匹配不到就报错 - 全文搜索:交给Elasticsearch或PostgreSQL的
to_tsvector,不要自己拼LIKE '%xxx%' - 多条件组合查询:用GraphQL输入对象定义结构,Resolver内用if-else分支分别构造安全查询,而不是用
Object.keys(args).map(k => `${k} = ${args[k]}`).join(' AND ') - 最关键是——别在Resolver里做权限判断以外的业务规则解释,那些应该下沉到Service层统一处理
GraphQL的SQL注入风险不在协议本身,而在Resolver怎么用输入。很多人以为关掉内省、加个深度限制就万事大吉,结果上线后发现args还是直通数据库。真正的防护点,永远落在那几行调用query或execute的代码上。

















