ASP.NET WebForms参数篡改漏洞修复咨询
嘿,这个问题我太熟悉了——很多WebForms开发者都会误以为ViewState加密就能保护所有表单数据,但其实不是!ViewState加密只保护ViewState里的内容,而你表单里的txtUserID这类输入字段是作为POST参数传输的(哪怕用了HTTPS,Burp也能通过证书信任抓包篡改)。下面给你几个实打实的修复步骤:
1. 服务器端强制验证所有输入(最关键!)
永远不要信任客户端传来的任何数据,哪怕你在前端加了JS校验,也必须在服务器端再做一遍——因为前端校验可以被轻易绕过。
比如针对你的txtUserID,你可以在按钮点击事件里加这些验证逻辑:
protected void btnSubmit_Click(object sender, EventArgs e) { // 第一步:验证格式合法性(比如必须是数字) if (!int.TryParse(txtUserID.Text, out int userId)) { lblErrorMessage.Text = "用户ID格式无效,请输入数字"; return; } // 第二步:验证业务合法性(比如这个ID是否属于当前登录用户,或者是否存在于数据库) var currentUser = GetCurrentLoggedInUser(); // 你自己的获取当前用户方法 if (userId != currentUser.Id || !IsUserExists(userId)) // 检查ID是否存在 { lblErrorMessage.Text = "无权访问该用户ID"; return; } // 到这里才执行你的业务逻辑 ProcessUserRequest(userId); }
不管Burp怎么篡改txtUserID的值,服务器端都会把非法值拦下来,根本不会让它进入业务流程。
2. 启用ASP.NET请求验证做基础防护
确保你的Web.config里启用了请求验证,它能帮你拦截一些常见的恶意输入(比如脚本注入):
<configuration> <system.web> <httpRuntime requestValidationMode="4.5" /> <pages validateRequest="true" /> </system.web> </configuration>
注意:这只是基础防护,不能替代你自己的业务规则验证。
3. 把非用户输入的敏感值移到ViewState里
如果txtUserID不是需要用户手动输入的(比如是从当前用户会话里获取的),那完全没必要让用户输入它——直接把它存到ViewState里就行,因为你已经启用了ViewState加密和MAC,Burp根本篡改不了ViewState的内容。
示例代码:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // 页面首次加载时,把当前用户的ID存入ViewState ViewState["ValidUserID"] = GetCurrentLoggedInUser().Id.ToString(); } } protected void btnSubmit_Click(object sender, EventArgs e) { // 提交时直接从ViewState取,不用管文本框的值 int validUserId = int.Parse(ViewState["ValidUserID"].ToString()); ProcessUserRequest(validUserId); }
这种情况下,你甚至可以把txtUserID隐藏掉,或者直接去掉这个输入框,彻底杜绝篡改可能。
4. 强制全站HTTPS
你已经用了自签名证书,那一定要确保全站都走HTTPS,避免请求在传输过程中被明文窃听。可以在Web.config里加重写规则实现自动跳转:
<system.webServer> <rewrite> <rules> <rule name="HTTP转HTTPS" stopProcessing="true"> <match url="(.*)" /> <conditions> <add input="{HTTPS}" pattern="off" ignoreCase="true" /> </conditions> <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" /> </rule> </rules> </rewrite> </system.webServer>
虽然HTTPS不能阻止Burp抓包(只要攻击者信任了自签名证书),但它能防止普通的中间人窃听,同时配合服务器端验证,就能彻底解决篡改后的非法值被应用接受的问题。
5. 权限控制(如果适用)
如果这个txtUserID是管理员专用的字段,那要在页面层面做权限校验,确保只有授权用户能访问这个表单,或者直接隐藏输入框,用服务器端传递的参数,不给攻击者篡改的机会。
总结一下:ViewState加密和MAC是保护ViewState的,和表单POST的输入字段无关。解决这个问题的核心就是永远不信任客户端输入,在服务器端做严格的验证,再配合合适的字段存储方式和HTTPS,就能彻底堵住这个漏洞。
内容的提问来源于stack exchange,提问作者Chendur

