You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET GET API参数安全防护:如何阻止恶意参数填充?

问题描述

我用ASP.NET搭建了网站,其中GET请求API的URI格式为:https://www.example.com/api/results/?country=&city=&value=。漏洞测试时发现以下问题:

  • 敏感目录/文件探测:比如请求 https://www.example.com/api/results/?country=&city=admin/access_log&value=
  • 内容注入:比如请求 https://www.example.com/api/results/%20Site%20is%20moved%20to%20wastest.indusface.com%20kindly%20visit%20wastest.indusface.com.%20?country=undefined&city=undefined&value=
  • Iframe注入:比如请求 https://www.example.com/api/results/?country=%3Ciframe%20src%3D%22https%3A%2F%2Fwas.indusface.com%2F2085%22%20class%3D'haikumsg'%3E%3C%2Fiframe%3E&city=&value=

这些问题本质是API接收了恶意参数值,但我有大量参数,手动逐个校验工作量大还影响性能,请问怎么解决这个“参数填充”问题?

我的API定义如下:

Iexample.vb

<OperationContract()>
<Web.WebInvoke(Method:="GET", ResponseFormat:=Web.WebMessageFormat.Json, BodyStyle:=Web.WebMessageBodyStyle.Bare,
UriTemplate:="results/?country={country}&province={province}&city={city}&value={value}")>

example.svc.vb

Public Function results(ByVal country As String, ByVal province As String,
    ByVal city As String, ByVal value As String) As Stream Implements Iexample.results

解决方案

针对WCF REST服务的批量参数校验,推荐以下几种高效方案,避免手动逐个校验:

1. 自定义校验属性 + 反射批量校验

创建自定义校验属性定义规则,通过反射自动校验所有参数,无需重复编写校验逻辑:

步骤1:定义校验属性

<AttributeUsage(AttributeTargets.Parameter)>
Public Class ValidateInputAttribute
    Inherits Attribute
    ' 允许的字符正则(白名单)
    Public Property AllowedPattern As String
    ' 参数最大长度限制
    Public Property MaxLength As Integer = 100

    Public Function IsValid(value As String) As Boolean
        If String.IsNullOrEmpty(value) Then Return True ' 允许空值可根据业务调整
        If value.Length > MaxLength Then Return False
        If Not String.IsNullOrEmpty(AllowedPattern) Then
            Return Regex.IsMatch(value, AllowedPattern)
        End If
        Return True
    End Function
End Class

步骤2:给接口参数添加校验属性

<OperationContract()>
<Web.WebInvoke(Method:="GET", ResponseFormat:=Web.WebMessageFormat.Json, BodyStyle:=Web.WebMessageBodyStyle.Bare,
UriTemplate:="results/?country={country}&province={province}&city={city}&value={value}")>
Function results(
    <ValidateInput(AllowedPattern:="^[a-zA-Z0-9\s-]*$")> country As String,
    <ValidateInput(AllowedPattern:="^[a-zA-Z0-9\s-]*$")> province As String,
    <ValidateInput(AllowedPattern:="^[a-zA-Z0-9\s-]*$")> city As String,
    <ValidateInput(AllowedPattern:="^[a-zA-Z0-9\s-]*$")> value As String
) As Stream

步骤3:实现通用校验方法

Private Sub ValidateParameters(methodInfo As MethodInfo, parameters() As Object)
    Dim paramInfos = methodInfo.GetParameters()
    For i = 0 To paramInfos.Length - 1
        Dim attr = paramInfos(i).GetCustomAttribute(Of ValidateInputAttribute)()
        If attr IsNot Nothing AndAlso parameters(i) IsNot Nothing Then
            Dim value = parameters(i).ToString()
            If Not attr.IsValid(value) Then
                Throw New WebFaultException(Of String)($"参数 {paramInfos(i).Name} 格式非法", HttpStatusCode.BadRequest)
            End If
        End If
    Next
End Sub

Public Function results(country As String, province As String, city As String, value As String) As Stream Implements Iexample.results
    ' 调用通用校验
    ValidateParameters(MethodBase.GetCurrentMethod(), {country, province, city, value})
    ' 原有业务逻辑
End Function

2. WCF消息拦截器实现全局校验

通过实现IDispatchMessageInspector,在请求到达服务方法前统一拦截所有GET参数,批量校验,无需修改每个服务方法:

步骤1:实现消息拦截器

Public Class InputValidationInspector
    Implements IDispatchMessageInspector

    Public Function AfterReceiveRequest(ByRef request As Message, channel As IClientChannel, instanceContext As InstanceContext) As Object Implements IDispatchMessageInspector.AfterReceiveRequest
        If request.Properties.ContainsKey(HttpRequestMessageProperty.Name) Then
            Dim httpProp = CType(request.Properties(HttpRequestMessageProperty.Name), HttpRequestMessageProperty)
            Dim queryParams = HttpUtility.ParseQueryString(httpProp.QueryString)
            
            ' 定义非法字符规则(优先用白名单,这里示例黑名单)
            Dim invalidChars = "<>|\/\\'"";"
            For Each key In queryParams.AllKeys
                Dim value = queryParams(key)
                If Not String.IsNullOrEmpty(value) AndAlso value.IndexOfAny(invalidChars.ToCharArray()) >= 0 Then
                    Throw New WebFaultException(Of String)($"参数 {key} 包含非法字符", HttpStatusCode.BadRequest)
                End If
            Next
        End If
        Return Nothing
    End Function

    Public Sub BeforeSendReply(ByRef reply As Message, correlationState As Object) Implements IDispatchMessageInspector.BeforeSendReply
        ' 无需处理
    End Sub
End Class

步骤2:注册拦截器到WCF配置

创建配置元素类:

Public Class InputValidationElement
    Inherits BehaviorExtensionElement

    Public Overrides ReadOnly Property BehaviorType As Type
        Get
            Return GetType(InputValidationBehavior)
        End Get
    End Property

    Protected Overrides Function CreateBehavior() As Object
        Return New InputValidationBehavior()
    End Function
End Class

Public Class InputValidationBehavior
    Implements IEndpointBehavior

    Public Sub AddBindingParameters(endpoint As ServiceEndpoint, bindingParameters As BindingParameterCollection) Implements IEndpointBehavior.AddBindingParameters
    End Sub

    Public Sub ApplyClientBehavior(endpoint As ServiceEndpoint, clientRuntime As ClientRuntime) Implements IEndpointBehavior.ApplyClientBehavior
    End Sub

    Public Sub ApplyDispatchBehavior(endpoint As ServiceEndpoint, endpointDispatcher As EndpointDispatcher) Implements IEndpointBehavior.ApplyDispatchBehavior
        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(New InputValidationInspector())
    End Sub

    Public Sub Validate(endpoint As ServiceEndpoint) Implements IEndpointBehavior.Validate
    End Sub
End Class

修改web.config:

<system.serviceModel>
  <extensions>
    <behaviorExtensions>
      <add name="inputValidation" type="YourNamespace.InputValidationElement, YourAssembly" />
    </behaviorExtensions>
  </extensions>
  <behaviors>
    <endpointBehaviors>
      <behavior>
        <inputValidation />
      </behavior>
    </endpointBehaviors>
  </behaviors>
</system.serviceModel>

3. 通用正则批量校验(快速实现)

如果所有参数校验规则一致,可在服务方法中批量遍历参数校验:

Public Function results(country As String, province As String, city As String, value As String) As Stream Implements Iexample.results
    ' 定义允许的字符正则(白名单)
    Dim allowedRegex = New Regex("^[a-zA-Z0-9\s-]*$", RegexOptions.Compiled)
    ' 批量封装参数
    Dim params = New Dictionary(Of String, String) From {
        {"country", country},
        {"province", province},
        {"city", city},
        {"value", value}
    }
    ' 批量校验
    For Each kvp In params
        If Not String.IsNullOrEmpty(kvp.Value) AndAlso Not allowedRegex.IsMatch(kvp.Value) Then
            Throw New WebFaultException(Of String)($"参数 {kvp.Key} 格式非法", HttpStatusCode.BadRequest)
        End If
    Next
    ' 原有业务逻辑
End Function

关键注意事项

  • 优先用白名单规则:只允许明确合法的字符,比黑名单更安全,不易被绕过
  • 输出也要编码:如果参数值需要输出到页面,即使做了输入校验,也要用HttpUtility.HtmlEncode做HTML编码,防止XSS
  • 正则优化:编译正则表达式(RegexOptions.Compiled)可提升重复校验的性能,避免正则回溯问题

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 18:13:09