【问题标题】:Is the use of rendered in a JSF component sufficient security to prevent a forged action invocation?在 JSF 组件中使用呈现是否足够安全以防止伪造的操作调用?
【发布时间】:2014-01-06 18:40:46
【问题描述】:

我们一直在使用自定义 @Secure 拦截器来保护我们的支持 bean 方法,以防止对该方法的伪造调用。

但最近,如果调用该操作的组件未呈现,则这些方法无法访问。据我了解,JSF 将生成视图,如果组件不是基于权限呈现的(例如带有 isUserInRole 的 EL),那么任何以该组件为源的伪造 POST 都不会触发,因为在恢复视图。这是正确的吗?

基本上,任何伪造都必须有一个受损的当前 JSESSIONID,甚至可能是 ViewState,这取决于它们是否需要相同的视图。

有人可以确认我的假设是正确的,如果可能的话,请指出我在规范中的某个位置?

谢谢

【问题讨论】:

标签: security jsf-2


【解决方案1】:

好的,我想我已经确认根据规范确实无法访问非渲染组件的操作。

规范第 2.2.2 节规定:

在应用请求值阶段,JSF 实现必须 调用组件的 UIViewRoot 的 processDecodes() 方法 tree.[P1-end] 这通常会导致 processDecodes() 方法 递归调用树中的每个组件,如中所述 UIComponent.processDecodes() 方法的 Javadocs。

它还指出:

在请求值的解码过程中,一些组件执行了特殊的 处理,包括:实现ActionSource的组件(如 UICommand),它识别出它们已被激活,将排队 动作事件。该事件将在申请请求结束时交付 如果组件的立即属性为真,则为阶段赋值,或者在 如果为 false,则 Invoke Application 阶段结束。

因此,ActionSource 组件只有在根据 processDecodes 处理时才会对操作进行排队。查看javadoc:

执行Apply Request所需的组件树处理 请求处理生命周期的所有方面的值阶段 此组件,此组件的所有子组件,以及此组件 本身,如下。

  • 如果此 UIComponent 的渲染属性为 false,则进一步跳过 处理。

所以第一个检查必须是组件是否被渲染,如果没有,则跳过其余部分。 ActionSource 永远不会排队,操作也永远不会被调用。

还有一点需要注意的是,从 JSF 2.2 开始,ViewState 似乎只对按照规范进行的 CSFR 预防可靠:

https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-869

以前的实现显然过于可预测并且没有涵盖 GET 请求。规范现在需要这个。

因此,虽然保护服务器端的安全可能仍然是一个好习惯,但似乎控制 ActionSource 组件的呈现就足够了。

【讨论】:

    【解决方案2】:

    JSESSIONID 是绝对需要的。但是如果用户登录,就可以很容易地访问它——我说的是用户登录的情况,但据说没有访问特定方法的权限。

    另一部分更棘手。如果状态存储在客户端,则可以伪造。此外,还有一些机制可以提供到动作和页面的直接链接——比如漂亮或简单的链接。如果该方法以任何这些方式公开,则应加以限制。

    我会保护它们以防止将来不断监控以何种方式公开哪种方法的麻烦——想象一下,如果您想为应用程序添加 REST 或 SOA 接口。

    【讨论】:

    • 我同意,我认为最好为未来的 REST 服务抢先保护它,并了解在这种情况下任何伪造请求都需要 JSESSIONID。我也不使用客户端状态保存,但承认我没有想到这一点。我想我正在寻找确认,如果我在支持 bean 上有一个像“save”这样的方法,并且我唯一调用的地方是通过有条件呈现的命令按钮,是否可以安全地假设它无法访问,除非按钮是渲染?规范中有讨论这个的地方吗?
    • 顺便说一句:我认为使用我自己的 JSESSIONID 来“提升”我的权限是不够的,因为我还必须提供一个 ViewState id,它与按钮的恢复视图相关联,如果我没有合适的角色,就不会发生这种情况。
    • 另一点是如何防止按钮呈现。如果渲染属性为假,那么按钮仍然在树中,我认为可以伪造一个调用。另一方面,如果使用 c:if,则它根本不在树中,调用失败。
    • 嗯,我不是说你错了,但我认为实际上如果按钮呈现为假,则该按钮不在视图树中。至少这是我推定的信任。我会进行测试并报告回来。
    • 我确认如果创建一个带有条件按钮的页面并让按钮呈现,我可以使用 GET 获取具有适当 URL 参数的相同页面。如果我随后更改条件以使按钮不呈现,则不会调用该操作。如果我通过 FacesContext 检查 ViewRoot,我可以确认您是对的,按钮仍然存在,但不确定这与 JSF 在生命周期中所做的树和/或验证相同。简而言之,我可以确认至少在 Mojarra 中,通过伪造请求无法执行该操作。我只是不知道这是 Mojarra 还是规范的东西。
    猜你喜欢
    • 2015-11-05
    • 1970-01-01
    • 2019-07-29
    • 2013-09-20
    • 1970-01-01
    • 2019-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多