简体   繁体   English

Page.IsPostBack 的安全实现?

[英]A secure implementation of Page.IsPostBack?

Following my previous question as to whether ASP.net's default Page.IsPostBack implementation is secure (it's not; it can be faked... the HTTP verb doesn't even have to be POST,);根据我之前关于ASP.net 的默认 Page.IsPostBack 实现是否安全的问题(它不是;它可以被伪造...... HTTP 动词甚至不必是 POST,); I was thinking?我刚在想? surely there must be a better way to implement it.肯定有更好的方法来实现它。 Can we come up with a Page,IsPostBack implementation which, when it is true?我们能想出一个 Page,IsPostBack 实现,当它是真的时? is almost guaranteed to indicate that the page is an actual ASP.net postback, This is important if one wants to do security checking only once (like whether some content is going to appear, based on the user's role(s)).几乎可以保证表明该页面是实际的 ASP.net 回发,如果只想进行一次安全检查(例如是否会根据用户的角色显示某些内容),这一点很重要。 and wants to do it only if we're NOT dealing with an ASP.net postback.并且只有在我们不处理 ASP.net 回发时才想这样做。

My first thoughts as to how to do this are to implement the checking code in a property, so I can write something like this inside Page_Load :关于如何做到这一点,我的第一个想法是在属性中实现检查代码,因此我可以在Page_Load中编写类似这样的内容:

if (!_isPostBack)
{
    // Do security check
    if (userIsNotAuthorized)
    {
        btnViewReports.Visible = false;
        btnEditDetails.Visible = false;
        // etc.
    }
}

Is there a way to securely implement _isPostBack ?有没有办法安全地实施_isPostBack Perhaps storing something in the ViewState that would be hard or impossible to jerry-rig to fake a postback?也许在 ViewState 中存储一些难以或不可能通过 jerry-rig 伪造回发的东西? A random string?随机字符串?

I had a project a couple of years ago where we had some penetration testing done on the code.几年前我有一个项目,我们对代码进行了一些渗透测试。 They flagged up the fact that by default IsPostback doesn't check the http verb.他们指出了默认情况下IsPostback不检查 http 动词的事实。 To address this I created an abstract Page class with its' own implementation of IsPostback that shadows the default implmentation:为了解决这个问题,我创建了一个抽象的页面 class ,它有自己的IsPostback实现,它隐藏了默认的实现:

Public Class ProjectPage : System.Web.UI.Page

    public new bool IsPostBack()
    {
        return (Page.IsPostBack && Request.HttpMethod.ToUpper() == "POST");
    }

End Class

This allows you to do testing on the http verb, but you could easily extend the method to do other checks as well.这允许您对 http 动词进行测试,但您也可以轻松扩展该方法以进行其他检查。

OK, here's what I think is the solution: Page.IsPostBack is already secure enough, as long as event validation is enabled.好的,这就是我认为的解决方案: Page.IsPostBack已经足够安全,只要启用了事件验证。 Let me explain my reasoning below and I'd be happy for anyone to add a comment if I've gotten something wrong.让我在下面解释我的推理,如果我有什么问题,我很乐意任何人添加评论。

In order for a spoof postback to be posted to ASP.net and trigger a control's OnClick event, with event validation enabled, the client has to send the __EVENTVALIDATION form field.为了将欺骗回发发布到 ASP.net 并触发控件的OnClick事件,启用事件验证,客户端必须发送__EVENTVALIDATION表单字段。 This field contains a uniquely-generated string that basically tells ASP.net which controls a postback event for that page may have originated from.此字段包含一个唯一生成的字符串,它基本上告诉 ASP.net 控制该页面的回发事件可能源自哪个。 If you try to spoof a postback for a button which has had .Visibility = false set on it, you'll see an event validation error message.如果您尝试欺骗已设置.Visibility = false的按钮的回发,您将看到事件验证错误消息。 So, it looks like you can't directly spoof a click on a hidden control.所以,看起来你不能直接欺骗隐藏控件的点击。

What about spoofing a postback of one of the existing buttons on the page that you has been rendered (ie. you do have permission to view/click on it)?欺骗您呈现的页面上现有按钮之一的回发怎么样(即您确实有权查看/单击它)? Well, you can send the postback to the page, but you need to submit a valid __VIEWSTATE or you'll just get a 'state information invalid' error.好吧,您可以将回发发送到页面,但您需要提交有效的__VIEWSTATE否则您只会收到“状态信息无效”错误。 In order to have a valid __VIEWSTATE , you already need to have loaded the page as a non-postback, right?为了获得有效的__VIEWSTATE ,您已经需要将页面加载为非回发,对吗? That means that the security-checking code will have executed at least once, hiding the appropriate controls and recording that in the __VIEWSTATE .这意味着安全检查代码将至少执行一次,隐藏适当的控件并将其记录在__VIEWSTATE中。 So, when you post the spoof postback, yes it will cause Page.IsPostBack to be true, but it doesn't matter because the submitted __VIEWSTATE will already have been generated on the previous non-postback page load to hide the content that you shouldn't have access to... so, you can spoof a postback, but only by passing a __VIEWSTATE that has been previously generated by a non-postback page load.因此,当您发布欺骗回发时,是的,它会导致Page.IsPostBack为真,但这没关系,因为提交的__VIEWSTATE已经在之前的非回发页面加载时生成,以隐藏您应该隐藏的内容'无权访问...因此,您可以欺骗回发,但只能通过传递先前由非回发页面加载生成的__VIEWSTATE

So, because of these facts, it should be safe to only put security-checking code inside a Page.IsPostBack == false block.因此,由于这些事实,只将安全检查代码放在Page.IsPostBack == false块中应该是安全的。 This must always get run once before a valid postback can be submitted to the ASP.net server.这必须始终运行一次,然后才能将有效的回发提交到 ASP.net 服务器。 Or am I missing something?还是我错过了什么?

A cookie is a much better mechanism for your needs. cookie 是一种更好的机制来满足您的需求。 The cookie is a token that could only have been generated by the server and vouches for the holder of the token certain claims such as having signed in recently and for having certain permissions and/or preferences. cookie 是一个只能由服务器生成的令牌,并为令牌持有者提供某些声明,例如最近登录以及拥有某些权限和/或偏好。 Some of these features are built into FormsAuthentication.其中一些功能内置在 FormsAuthentication 中。 You can implement your own cookie mechanism, but you should research secure cookie protocols because there are several non-obvious security considerations.您可以实现自己的 cookie 机制,但您应该研究安全 cookie 协议,因为有几个不明显的安全注意事项。

The benefit is that you don't have to go to the database on every request, you just trust it.好处是您不必在每次请求时都向数据库发送 go,您只需信任它。 This could also be a good strategy for weathering certain DoS attacks because you can tier your app such that a dedicated device in front of your app servers validates tokens too and throws out invalid requests.这也可能是抵御某些 DoS 攻击的好策略,因为您可以将应用分层,以便应用服务器前面的专用设备也验证令牌并抛出无效请求。

If cookies aren't allowed, you can send the token as part of the url, as formsauth allows, or as a form field in your postback.如果不允许 cookies,您可以将令牌作为 url 的一部分(如 formsauth 允许的那样)或作为回发中的表单字段发送。 But that's more work to manage then cookies, IMHO, once you've gone through the trouble of generating a proper token.但是,一旦您遇到了生成适当令牌的麻烦,那么管理工作就比 cookies 恕我直言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM