2011-06-13 46 views
5

关于我的previous question,关于ASP.net的默认Page.IsPostBack实现是否安全(不是;它可能是假的...... HTTP动词甚至不必是POST!),我在想;肯定有一个更好的方法来实现它?我们是否可以想出一个Page.IsPostBack实现,如果它是真的,几乎可以保证表明该页面是实际的ASP.net回发?如果只想进行一次安全检查(例如根据用户的角色是否显示某些内容),并且只有在不处理ASP.net回发时才这样做,这一点很重要。Page.IsPostBack的安全实现?

我的第一个想法是如何做到这一点的实现在属性检查代码,这样我就可以写这样的事情里面Page_Load

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

是否有安全地实现_isPostBack的方法吗?也许在ViewState中存储一些难以或不可能的东西来伪造回传?随机字符串?

+3

您在安全环境中询问“几乎可以保证”吗?这是没有意义的。它要么是安全的,要么是不安全的。 “几乎”与未安全相同 – jalf 2011-06-13 09:24:27

+1

嗯,我的意思是'几乎保证'在RSA加密“几乎安全”的情况下;理论上它可能是暴力强迫的,或者你可以'运气出去'并猜测某人的关键,但这是非常不可能的或困难的。 – Jez 2011-06-13 09:27:25

+0

您无法相信_anything_来自客户端。只要重做你的逻辑,你就拥有Session对象。 – 2011-06-13 09:38:22

回答

1

好的,这是我认为的解决方案:Page.IsPostBack 已经足够安全,只要启用事件验证即可。让我在下面解释我的推理,如果我发现错误,我会很高兴任何人添加评论。

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

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

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

0

饼干是一个更好的机制,以满足您的需求。 Cookie是一种令牌,只能由服务器生成,并为令牌持有人提供某些声明,例如最近登录并具有某些权限和/或偏好。其中一些功能内置到FormsAuthentication中。你可以实现你自己的cookie机制,但是你应该研究安全的cookie协议,因为有几个不明显的安全考虑因素。

好处是你不必每次请求都去数据库,你只需要信任它。对于某些DoS攻击的风险来说,这也可能是一个很好的策略,因为您可以对应用进行分层,以使应用服务器前的专用设备也可以验证令牌并抛出无效请求。

如果cookie不被允许,您可以将token作为URL的一部分发送,就像formsauth允许的一样,或者作为回发中的表单字段。但是,一旦你经历了生成一个合适的令牌的麻烦,那么更多的工作来管理cookies,恕我直言,恕我直言。

+0

那么在ASP.net中,可能最好的方法是使用Session吗?无论如何,这就是Cookie的ASP.net代表。 – Jez 2011-06-13 11:29:44

+0

[Kovacs et al。在安全Cookie协议中](http://www.cse.msu.edu/~alexliu/publications/Cookie/cookie.pdf)为您的问题引入了一种看似坚实的通用方法。我不知道ASP.Net FormsAuth是否具有这些优点,但几年前我在C#中成功实现了它们的确切协议(使用.Net crypto库),而没有太多麻烦。对我而言,这是一个有趣而平易近人的项目,并且令人满意。我不知道他们的工作是否有任何相关的批评或改进。 – 2011-06-14 03:18:06

2

几年前,我有一个项目,我们在代码上做了一些渗透测试。他们标记了事实,默认IsPostback不检查http动词。为了解决这个问题,我创建其自己的执行IsPostback一个抽象的页面类阴影默认implmentation:

Public Class ProjectPage : System.Web.UI.Page 

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

End Class 

这允许你做对HTTP动词的测试,但你可以很容易地扩展方法做其他检查也是如此。