如何解决单参数WebMethod中的API Mass Assignment问题?
解决WebForms中ASMX WebMethod的Mass Assignment漏洞问题
针对你遇到的ASMX WebMethod接受额外POST参数返回200 OK的审计问题,以下是两种可行的修复方案:
方案1:直接校验请求参数白名单(适配现有单参数方法)
ASMX WebMethod默认会忽略未定义的参数,因此需要手动读取请求原始数据,校验所有参数是否在允许的白名单内。
代码实现
[WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] // 匹配前端AutoCompleteExtender的请求格式 public List<string> GetWorsList(string prefixText) { // 校验请求参数是否仅包含允许的字段 ValidateRequestParams(new[] { "prefixText" }); List<string> workNames = null; if (!Validations.ValidWorkNoAjax(prefixText)) { return workNames; } // 原有业务逻辑代码 if (con.State == ConnectionState.Closed) { con.Open(); } System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("", con); cmd.Parameters.Add("@prefixText", SqlDbType.VarChar, 500).Value = "%" + prefixText + "%"; /*Some Code*/ return workNames; } private void ValidateRequestParams(string[] allowedParams) { var request = HttpContext.Current.Request; JObject requestData = null; // 读取并解析POST请求内容(兼容JSON和表单格式) if (request.ContentType.Contains("application/json")) { request.InputStream.Position = 0; using (var reader = new StreamReader(request.InputStream)) { var json = reader.ReadToEnd(); requestData = JObject.Parse(json); } } else { requestData = new JObject(); foreach (string key in request.Form) { requestData[key] = request.Form[key]; } } // 检查是否存在不在白名单内的参数 var invalidParams = requestData.Properties().Select(p => p.Name).Except(allowedParams).ToList(); if (invalidParams.Any()) { // 返回400错误拒绝请求 HttpContext.Current.Response.StatusCode = 400; HttpContext.Current.Response.Write($"Invalid parameters: {string.Join(", ", invalidParams)}"); HttpContext.Current.Response.End(); } }
说明
- 该方法直接读取请求原始数据,覆盖JSON和表单两种POST格式
- 发现额外参数时直接返回400错误,替代原有200 OK响应,满足审计要求
- 需要引用
Newtonsoft.Json(可通过NuGet安装)来解析JSON数据
方案2:修复Model参数绑定问题(更规范的参数接收方式)
之前使用Model参数报错,大概率是Model定义或WebMethod配置缺失导致,按以下步骤修正:
1. 定义可序列化的Model类
[Serializable] // ASMX WebMethod需要此标记支持序列化 public class WorkSearchModel { public string prefixText { get; set; } }
2. 修改WebMethod使用Model作为参数
[WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = false)] public List<string> GetWorsList(WorkSearchModel model) { if (model == null || string.IsNullOrEmpty(model.prefixText)) { HttpContext.Current.Response.StatusCode = 400; return null; } // 复用方案1的参数校验逻辑,拒绝额外参数 ValidateRequestParams(new[] { "prefixText" }); List<string> workNames = null; if (!Validations.ValidWorkNoAjax(model.prefixText)) { return workNames; } // 原有业务逻辑代码 if (con.State == ConnectionState.Closed) { con.Open(); } System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("", con); cmd.Parameters.Add("@prefixText", SqlDbType.VarChar, 500).Value = "%" + model.prefixText + "%"; /*Some Code*/ return workNames; }
3. 补充Web.config配置(若仍报错)
确保Web.config中开启JSON序列化支持:
<system.web.extensions> <scripting> <webServices> <jsonSerialization maxJsonLength="50000000"/> </webServices> </scripting> </system.web.extensions>
关键说明
- QueryString校验无效的原因:POST请求的参数(JSON/表单)不会出现在QueryString中,因此无法覆盖该场景
- 关于Mass Assignment风险:ASMX本身不会自动将额外参数绑定到业务对象,实际不存在赋值风险,但审计要求拒绝额外参数请求,因此需要手动校验
- 两种方案都能实现拒绝含额外参数的POST请求,返回非200响应,满足审计要求
内容的提问来源于stack exchange,提问作者Amit Kaushal
相关产品推荐
相关产品推荐

