AllowUnsafeUpdates 的最佳模式
到目前为止,在我的研究中,我发现在 GET 请求操作上设置 AllowUnsafeUpdates 以避免跨站点脚本编写是不明智的。 但是,如果需要允许这样做,处理这种情况以减轻风险的正确方法是什么?
如果您绝对需要允许 Web 或站点更新 GET 请求,那么这是我对可靠模式的最佳初步猜测。
最佳实践?
protected override void OnLoad(System.EventArgs e)
{
if(Request.HttpMethod == "POST")
{
SPUtility.ValidateFormDigest();
// will automatically set AllowSafeUpdates to true
}
// If not a POST then AllowUnsafeUpdates should be used only
// at the point of update and reset immediately after finished
// NOTE: Is this true? How is cross-site scripting used on GET
// and what mitigates the vulnerability?
}
// Point of item update
using(SPSite site = new SPSite(SPContext.Current.Site.Url, SPContext.Current.Site.SystemAccount.UserToken))
{
using (SPWeb web = site.RootWeb)
{
bool allowUpdates = web.AllowUnsafeUpdates; //store original value
web.AllowUnsafeUpdates = true;
//... Do something and call Update() ...
web.AllowUnsafeUpdates = allowUpdates; //restore original value
}
}
欢迎提供有关最佳模式的反馈。
So far, in my research I have seen that it is unwise to set AllowUnsafeUpdates on GET request operation to avoid cross site scripting. But, if it is required to allow this, what is the proper way to handle the situation to mitigate any exposure?
Here is my best first guess on a reliable pattern if you absolutely need to allow web or site updates on a GET request.
Best Practice?
protected override void OnLoad(System.EventArgs e)
{
if(Request.HttpMethod == "POST")
{
SPUtility.ValidateFormDigest();
// will automatically set AllowSafeUpdates to true
}
// If not a POST then AllowUnsafeUpdates should be used only
// at the point of update and reset immediately after finished
// NOTE: Is this true? How is cross-site scripting used on GET
// and what mitigates the vulnerability?
}
// Point of item update
using(SPSite site = new SPSite(SPContext.Current.Site.Url, SPContext.Current.Site.SystemAccount.UserToken))
{
using (SPWeb web = site.RootWeb)
{
bool allowUpdates = web.AllowUnsafeUpdates; //store original value
web.AllowUnsafeUpdates = true;
//... Do something and call Update() ...
web.AllowUnsafeUpdates = allowUpdates; //restore original value
}
}
Feedback on the best pattern is appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您正在执行任何修改某些内容的操作,那么任何可以说服用户单击链接的人都可以执行该操作。 例如,假设您有一个对页面的 GET 请求,该页面允许用户将管理员添加到站点,并且用户单击指向执行 Response.Redirect("http://yourserver/_layouts/admin.aspx?operation=addAdministrator&username=attackerNameHere")。
虽然通常情况下 POST 并不能提供太多的保护(没有什么可以阻止某人使用
GET 上的 AllowUnsafeUpdates 不存在安全问题的唯一情况是您不接受用户的输入。 例如,如果您有一个 Web 部件也记录对列表的访问,则不会暴露任何安全漏洞。
编辑:如果您要使用AllowUnsafeUpdates,则无需将其重置为之前的值。 它不会被持久化。 这只是您在执行 GET 更新(或其他情况)之前需要在 SPWeb 对象上设置的内容
If you're performing any operations which modify something, then anyone that can convince the user to click on a link can perform that operation. For instance, let's assume that you have a GET request to a page which lets the user add an administrator to a site, and the user clicks a link to a page which does a Response.Redirect("http://yourserver/_layouts/admin.aspx?operation=addAdministrator&username=attackerNameHere").
While normally a POST does not offer much protection against this (nothing will stop someone from having a <form method="post" action="http://yourserver/_layouts/admin.aspx">), SharePoint has a concept of form digests, which contain information about the previous request that is generating the post back (including the user's name). This reduces the footprint for this kind of attack significantly.
The only time that it is not a security issue to AllowUnsafeUpdates on a GET is if you're not taking input from the user. For instance, if you have a web part which also logs visits to a list, then there's no security vulnerability exposed.
Edit: If you are going to use AllowUnsafeUpdates, there's no need to reset it to its previous value. It does not get persisted. It's just something you need to set on an SPWeb object before performing updates from a GET (or other cases)
我会稍微修改 Trent 的委托以接受网络更新:
然后扩展 HttpContext 来封装表单摘要的验证,并可以选择使用 此处描述的技术:
用法:
I would slightly modify Trent's delegate to accept the web to update:
And then extend HttpContext to encapsulate verification of the form digest, with an option to elevate using the technique described here:
Usage:
另一种干净的实现方法是使用扩展方法和匿名委托的组合,如下所示:
使用上述扩展方法,您可以执行“不安全更新”操作,如下所示:
Another clean way to implement would be to use a combination of extension methods and anonymous delegates as such:
Using the above extension method, you can then perform your "unsafe update" action as follows:
对于AllowUnsafeUpdates,我遵循以下流程:
For AllowUnsafeUpdates, I follow this process:
不太确定是否值得记住允许不安全更新的先前值。
我希望将调用包装在尽可能少的代码周围,这样就不会发生对其的嵌套调用。
然后你可以将其设置为 false。
Not so sure it is worth remembering the previous value of allow unsafe updates.
I would want to wrap the call around the minimum possible amount of code, so that nested calls to it would not occur.
Then you can just turn it to false afterwards.
我使用包装类来处理 SPWeb 对象的大多数操作。 这帮助我记住关闭网络,并且缓解了不安全更新设置的问题。 它有点臃肿,因为我已经修补了新的构造函数和成员。 但话又说回来; SPWeb 类也是如此。
用法:
类定义:
I use a wrapper class for handling most manipulation of SPWeb objects. This helps me remember to close the web, and it eases the problems of unsafeupdates setting. It is a bit bloated, as I have patched on new constructors and members. but, then again; so is the SPWeb class.
Usage:
The class definition: