为什么某些 'potentially dangerous Request.Path' HttpExceptions 会忽略 httpErrors 设置?
Why do some 'potentially dangerous Request.Path' HttpExceptions ignore httpErrors settings?
我有一个 .Net 网站,其中包含使用 web.config httpErrors
部分配置的自定义错误页面:
<httpErrors errorMode="Custom" existingResponse="Replace">
<clear/>
<error statusCode="400" path="/page-not-found/" responseMode="ExecuteURL" />
<error statusCode="404" path="/page-not-found/" responseMode="ExecuteURL" />
<error statusCode="500" path="/error/" responseMode="ExecuteURL" />
</httpErrors>
和
<httpRuntime requestValidationMode="2.0" targetFramework="4.5" />
当我访问 http://www.example.com/<
the site displays the correct "page not found" page, however if I visit http://www.example.com/<a
时,它显示一个带有 500 状态代码响应的 YSOD header。
我连接了 Elmah,两个 URL 可以预见地抛出完全相同的错误 System.Web.HttpException: A potentially dangerous Request.Path value was detected from the client (<).
但是为什么两个网址的处理方式不一样呢?为什么一个重写到我的自定义错误页面,而另一个没有?我希望任何异常都有相同的行为。
编辑:
我应该提前提到这是一个 Umbraco 项目。我认为这不是一个促成因素,但我创建了一个没有依赖项的准系统 .Net 项目,并且按预期工作,即两个 URL 都遵守 httpErrors 配置。所以这一定是 Umbraco 特定的东西,可能是一个模块。
验证辅助方法首先调用输入验证,然后调用路径验证。
在验证位于 "syste.web/httRuntime" requestPathInvalidCharactersArray 属性的默认 web.config 设置中的输入时,验证辅助方法的默认配置中设置的默认值是:
<,>,*,%,&,:,\,?
如您所见,“<”被视为无效的 PATH,而“
如果您对我是如何想到这一点感到好奇的,我只是查看了验证辅助方法的源代码,然后按照它回到了源代码。
[编辑]
ValidateInputIfRequiredByConfig 方法显示它抛出一个 400
[编辑 2]
public NameValueCollection QueryString
{
get
{
this.EnsureQueryString();
if (this._flags[1])
{
this._flags.Clear(1);
this.ValidateHttpValueCollection(this._queryString, RequestValidationSource.QueryString);
}
return this._queryString;
}
}
调用这个 属性 命中 ValidateHttpValueCollection 可以验证查询字符串,如果验证源是查询字符串,它在这个 属性 中。
在这个方法中有一个方法叫做ValidateString。在 ValidateString 中,它确定它是否是有效字符串,如果不是,则抛出 HttpRequestValidationException
经过大量挖掘,我发现这实际上是由名为 ClientDependency 的第 3 方模块引起的。删除它并返回正常行为,但显然在这种情况下后台将无法正常运行。
项目需要补丁,我已经提交了。
更新:
自 v1.8.3 起,ClientDependency 中的这个错误已得到修复
我有一个 .Net 网站,其中包含使用 web.config httpErrors
部分配置的自定义错误页面:
<httpErrors errorMode="Custom" existingResponse="Replace">
<clear/>
<error statusCode="400" path="/page-not-found/" responseMode="ExecuteURL" />
<error statusCode="404" path="/page-not-found/" responseMode="ExecuteURL" />
<error statusCode="500" path="/error/" responseMode="ExecuteURL" />
</httpErrors>
和
<httpRuntime requestValidationMode="2.0" targetFramework="4.5" />
当我访问 http://www.example.com/<
the site displays the correct "page not found" page, however if I visit http://www.example.com/<a
时,它显示一个带有 500 状态代码响应的 YSOD header。
我连接了 Elmah,两个 URL 可以预见地抛出完全相同的错误 System.Web.HttpException: A potentially dangerous Request.Path value was detected from the client (<).
但是为什么两个网址的处理方式不一样呢?为什么一个重写到我的自定义错误页面,而另一个没有?我希望任何异常都有相同的行为。
编辑:
我应该提前提到这是一个 Umbraco 项目。我认为这不是一个促成因素,但我创建了一个没有依赖项的准系统 .Net 项目,并且按预期工作,即两个 URL 都遵守 httpErrors 配置。所以这一定是 Umbraco 特定的东西,可能是一个模块。
验证辅助方法首先调用输入验证,然后调用路径验证。
在验证位于 "syste.web/httRuntime" requestPathInvalidCharactersArray 属性的默认 web.config 设置中的输入时,验证辅助方法的默认配置中设置的默认值是:
<,>,*,%,&,:,\,?
如您所见,“<”被视为无效的 PATH,而“
如果您对我是如何想到这一点感到好奇的,我只是查看了验证辅助方法的源代码,然后按照它回到了源代码。 [编辑] ValidateInputIfRequiredByConfig 方法显示它抛出一个 400 [编辑 2] 调用这个 属性 命中 ValidateHttpValueCollection 可以验证查询字符串,如果验证源是查询字符串,它在这个 属性 中。 在这个方法中有一个方法叫做ValidateString。在 ValidateString 中,它确定它是否是有效字符串,如果不是,则抛出 HttpRequestValidationException public NameValueCollection QueryString
{
get
{
this.EnsureQueryString();
if (this._flags[1])
{
this._flags.Clear(1);
this.ValidateHttpValueCollection(this._queryString, RequestValidationSource.QueryString);
}
return this._queryString;
}
}
经过大量挖掘,我发现这实际上是由名为 ClientDependency 的第 3 方模块引起的。删除它并返回正常行为,但显然在这种情况下后台将无法正常运行。
项目需要补丁,我已经提交了。
更新:
自 v1.8.3 起,ClientDependency 中的这个错误已得到修复