最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
防止SQL注入时: 输入验证应放在客户端还是服务端?
时间:2026-07-21 09:46:55 编辑:袖梨 来源:一聚教程网
客户端验证拦不住SQL注入,因为JavaScript校验可被禁用脚本、curl直发、篡改前端或抓包重放等方式绕过,攻击者无需访问网页即可发送恶意payload;服务端才是唯一可信的入口守门人,必须对所有输入源进行白名单校验、危险字符过滤或转义,并配合参数化查询兜底防护。
必须放在服务端,客户端验证只能当辅助,不能当防线。
为什么客户端验证拦不住SQL注入
浏览器里的 JavaScript 验证可以被轻易绕过:禁用脚本、用 curl 直接发请求、改前端代码、抓包重放——所有这些操作都不经过你的 JS 校验逻辑。攻击者根本不需要打开网页,就能把 ' OR 1=1 -- 这类 payload 发到后端接口。
- 用户提交的任何数据,只要没经过服务端处理,就等同于“未验证”
-
HTML5的type="email"或pattern属性、Vue的表单规则、React的onChange校验,全属于客户端行为,不具安全约束力 - 哪怕你用 WebAssembly 或加密校验,只要验证逻辑跑在浏览器里,就存在逆向和跳过的可能
服务端验证该怎么做才有效
服务端验证不是“再检查一遍”,而是“唯一可信的入口守门人”。它要覆盖所有输入源:GET 查询参数、POST 表单、JSON 请求体、Cookie、HTTP 头(比如 X-Forwarded-For)、甚至 gRPC 或 WebSocket 消息。
- 优先用白名单:比如用户名只允许
[a-zA-Z0-9_]{3,20},ID 强制转成int类型 - 对不可预知格式的字段(如搜索关键词),至少过滤或转义危险字符:
'、"、;、--、/*、UNION、SELECT等(注意:过滤不能替代参数化查询) - 验证失败必须立即中断请求,返回通用错误(如
400 Bad Request),绝不能泄露字段名、校验规则或数据库结构
常见错误:把验证逻辑混进 ORM 或框架默认行为里
很多开发者误以为用了 ORM(如 Django ORM、Sequelize、MyBatis)就自动防注入,其实不然。ORM 的安全前提是:你没手动拼接 SQL 字符串。
-
MyBatis中写${username}是拼接,危险;用#{username}才是预编译,安全 -
Django的filter(name__icontains=request.GET.get('q'))是安全的,但raw()或extra()里拼字符串就直接破防 -
SQLAlchemy的text()如果插了用户输入,照样中招;必须用bindparam或execute(..., {'val': user_input})
真正容易被忽略的点是:验证和参数化查询不是二选一,而是必须同时存在。验证负责提前拦截明显非法输入(比如负数 ID、超长邮箱),参数化查询兜底处理所有漏网之鱼。少一个,防护链就断了。
相关文章
- 梦幻西游凌波城109级装备搭配 07-28
- 三角洲行动仿星器控制室位于何处 07-28
- 三角洲行动压水堆服务器室在何处 07-28
- 三角洲行动铁路通道何处 07-28
- 三角洲行动托卡马克数据中心在哪 07-28
- 三角洲行动后处理厂机房何在 07-28