Page.IsPostBack的安全实现?

根据我之前的问题 ,ASP.net的默认Page.IsPostBack实现是否安全(它不是;它可以伪造…… HTTP动词甚至不必是POST!),我在想; 肯定有一个更好的方法来实现它? 我们能否提出一个Page.IsPostBack实现,当它成立时,几乎可以保证表明该页面是一个真正的ASP.net回发? 如果一个人只想进行一次安全检查(比如某些内容是否会根据用户的角色出现),并且只有在我们不处理ASP.net回发时才这样做,这一点很重要。

我对如何执行此操作的第一个想法是在属性中实现检查代码,因此我可以在Page_Load编写类似这样的内容:

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

有没有办法安全地实现_isPostBack ? 也许在ViewState中存储一些很难或不可能进行简单假冒回传的内容? 随机字符串?

几年前我有一个项目,我们对代码进行了一些渗透测试。 他们标记了默认情况下IsPostback不检查http动词的事实。 为了解决这个问题,我创建了一个抽象的Page类,它有自己的IsPostback实现,它IsPostback了默认的IsPostback

 Public Class ProjectPage : System.Web.UI.Page public new bool IsPostBack() { return (Page.IsPostBack && Request.HttpMethod.ToUpper() == "POST"); } End Class 

这允许您对http动词进行测试,但您也可以轻松扩展该方法以进行其他检查。

好的,这就是我认为的解决方案:只要启用了事件validation,Page.IsPostBack已经足够安全了。 让我解释一下我的推理,如果我出错了,我会很高兴有人发表评论。

为了将欺骗回发发布到ASP.net并触发控件的OnClick事件,启用事件validation,客户端必须发送__EVENTVALIDATION表单字段。 该字段包含一个唯一生成的字符串,该字符串基本上告诉ASP.net控制该页面可能源自的回发事件。 如果您尝试欺骗设置了.Visibility = false的按钮的回发,您将看到事件validation错误消息。 所以,看起来你不能直接欺骗隐藏控件上的点击。

如何欺骗您已呈现的页面上现有按钮之一的回发(即您有权查看/点击它)? 好吧,您可以将回发发送到页面,但是您需要提交有效的__VIEWSTATE否则您只会收到“状态信息无效”错误。 为了拥有有效的__VIEWSTATE ,您需要将页面作为非回发加载,对吧? 这意味着安全检查代码将至少执行一次,隐藏适当的控件并将其记录在__VIEWSTATE 。 所以,当你发布恶搞回发时,是的,它会导致Page.IsPostBack为真,但这没关系,因为已提交的__VIEWSTATE已经在前一个非回发页面加载时生成,以隐藏你不应该的内容无法访问…所以,您可以欺骗回发,但只能通过传递之前由非回发页面加载生成的__VIEWSTATE

因此,由于这些事实,仅将安全检查代码放在Page.IsPostBack == false块中应该是安全的。 在将有效的回发提交到ASP.net服务器之前,必须始终运行一次。 或者我错过了什么?

Cookie是一种更好的机制,可满足您的需求。 cookie是一个令牌,它只能由服务器生成,并为令牌持有者提供担保,例如最近登录并具有某些权限和/或偏好。 其中一些function内置于FormsAuthentication中。 您可以实现自己的cookie机制,但是您应该研究安全cookie协议,因为有几个非显而易见的安全性考虑因素。

好处是您不必在每次请求时都访问数据库,您只需信任它。 这也可能是抵御某些DoS攻击的好策略,因为您可以对应用程序进行分层,使得应用服务器前面的专用设备也会validation令牌,并抛出无效请求。

如果不允许使用cookie,您可以将令牌作为URL的一部分发送,如formauth允许的那样,或作为回发中的表单字段发送。 但是,一旦你遇到了生成正确令牌的麻烦,那么管理那些cookies,恕我直言,这是更多的工作。