为何SNYK提示ASP.NET MVC的GET请求需添加AntiForgeryToken?
为什么SNYK会建议给GET请求的ASP.NET MVC Action加AntiForgeryToken?
首先明确:SNYK的告警并非误判,核心原因是你的ChooseCompany Action可能涉及会话状态变更,哪怕用的是GET请求,也存在CSRF风险。
具体原因:
- SNYK的规则逻辑:它的检测不会只看HTTP方法,而是关注操作是否会影响应用状态。很多开发者会违规用GET做状态变更操作(比如修改用户会话、数据库数据),所以SNYK做了兜底检测,只要是用户触发的、可能改变状态的Action,都会建议加反伪造验证。
- GET请求的CSRF风险:虽然REST规范要求GET是只读、幂等的,但如果你的
ChooseCompany实际在做这些操作——比如把选中的Company_id存入Session、Auth Cookie,或者关联到当前用户的登录状态,那攻击者可以构造恶意链接,诱导已登录用户点击,强制切换用户的当前公司,这就是典型的CSRF攻击。 - 你的场景匹配:用户点击链接后,必然需要将选中的公司和当前用户绑定,这属于状态变更,符合SNYK的告警触发条件。
解决方案:
方案1:遵循REST规范,改为POST请求(推荐)
把状态变更操作改成POST,同时添加[ValidateAntiForgeryToken]属性,视图里用表单提交替代<a>链接:
控制器代码:
[HttpPost] [ValidateAntiForgeryToken] public ActionResult ChooseCompany(string Company_id) { // 处理选中公司的逻辑,比如存入Session Session["CurrentCompanyId"] = Company_id; return RedirectToAction("Dashboard"); }
视图代码:
@* 公司X的提交表单 *@ @using (Html.BeginForm("ChooseCompany", "Account", FormMethod.Post)) { @Html.AntiForgeryToken() <input type="hidden" name="Company_id" value="xxxxxxx" /> <button type="submit" class="btn">选择公司X</button> } @* 公司Y的提交表单 *@ @using (Html.BeginForm("ChooseCompany", "Account", FormMethod.Post)) { @Html.AntiForgeryToken() <input type="hidden" name="Company_id" value="yyyyyyy" /> <button type="submit" class="btn">选择公司Y</button> }
方案2:坚持用GET的前提
如果一定要保留GET请求,必须确保ChooseCompany完全不做任何状态变更——比如只返回视图、跳转页面,不修改Session、Cookie、数据库等。这种情况下可以在SNYK里标记该告警为误报,但务必确认没有状态变更操作,否则风险依然存在。
内容的提问来源于stack exchange,提问作者rd1218
相关产品推荐
相关产品推荐

