控制 DOM,第 3 部分
Weblet 是运行在浏览器中的 Java 程序,使用 DirectDOM来直接操作被显示的文档。就像大多数基于 Web 的程序一样,如果对Weblet 管理不当,就会对系统安全造成威胁。幸好,Weblet 附带的 Java沙箱(Java Sandbox)可提高系统的内建安全性。在这个关于 DirectDOM和基于 Weblet 开发的三部系列的最后一部分,Paul Everett说明了如何使用沙箱来达到最佳效果。通过简单的工作示例,Paul 演示了Weblet在缺省情况下能做什么和不能做什么,还说明了在需要的情况下如何回避沙箱的约束。
您大概已经对 Applet 沙箱比较熟悉。Applet 与 Weblet 一样是在浏览器中运行的 Java 小程序。它们经常是从未知系统不知不觉地载入您的机器,所以必须保证它们是绝对安全的。缺省情况下,Applet 沙箱是应用到 Applet 的一套限制和许可。沙箱可以保护用户和客户机系统不受低质量程序或恶意 Applet 的侵害。
如果您已经开发过 Applet,那么实现 Weblet 安全性对您来说应该是很直观的。Weblet 与 Applet 有同样的安全隐患,也需要同样的保护。事实上,Weblet 和 Applet 甚至使用同样的沙箱。缺省情况下 Weblet 沙箱禁止 Weblet 执行下列有潜在危险的活动:
- 读文件或写文件
- 启动其它的程序
- 读取某个系统属性
- 关闭 JVM
- 打印
- 访问当前 Java 安全策略
- 通过套接字或 URL 连接服务器而非主机
与 Applet 一样,Weblet 可以在它们的沙箱中非常自由地运行,所以您可以使用它做许多工作,而无需受安全性的约束。在本文中,我将向您说明缺省情况下 Weblet 沙箱是如何工作的,以及您如何在需要的情况下安全地扩展其参数。我们将使用一个示例开始探索 Weblet 安全性。
注意:本文所描述的 Weblet 安全性在写这篇文章时已经在 DirectDOM 的 alphaWorks 版本中得到了实现,请阅读有关文档来查看新的变化和增强的功能(请参阅 参考资料)。
SecurityOps 是一个 Weblet,用来尝试几个安全性敏感的操作。我已经在下一章显示了每一个操作(包括异常)的结果。现在开始,可以在 清单 1 中查看这个 Weblet 的 HTML 文件。
现在,让我们来看一下 清单 2 中的 SecurityOps.java 。注意:对于每一个操作都有一个 try/catch 子句和一个已命名的输出区域。
如果编译 SecurityOps.java ,把生成的类放在 SecuritySamples.jar 文件中并载入 HTML 文件,输出将会如 清单 3所示。
只有 2 个操作是成功的:读取 os.name 系统属性和连接到服务主机。稍后,我们将会知道为什么它们会成功。其它的操作都产生了一些不同的 AccessControlException 异常。
![]() ![]() |
![]()
|
Weblet 在执行时可以访问自己所在的 jar 文件内部的类(在它的 HTML 文件的 WEBLET_CODEBASE 标记中指定)。除此之外,对 Weblet 的安全性和访问控制的管理还要考虑以下三种情况:
- DirectDOM 插件调用 SecurityManager。
当运行独立的 Java 程序时,它们通常会毫无限制地运行。如果您使用 -Djava.security.manager 参数调用 java ,您的程序就会在 SecurityManager 的控制下运行。 SecurityManager 会探测到那些可能不太安全可靠的操作并对之进行异常处理。同样,DirectDOM“引擎”会使用 SecurityManager 启动 JVM,这样就实现了沙箱。请参阅 参考资料,以获取更多关于安全管理器和策略文件的信息。 - java.policy 设置安全策略。
当 SecurityManager 在未经特殊配置的情况下运行时,所有的敏感操作都会产生一个异常;也就是说,所有这样的操作都会被阻塞。如果您想许可一个程序执行这些操作,可以在 java.policy 中创建 grant 语句, SecurityManager 读入该语句并强制执行。在下一章您会了解到如何通过对 java.policy 进行特殊配置来更改您的 Weblet 安全策略。 - Weblet 能连接到它们的主机。
与 Applet 一样,缺省情况下 Weblet 能连接到它的主机。与其它系统的连接会被堵塞,但是可以通过 java.policy 允许连接。在谈到连接这个课题时,我们将对此做更多的讨论。
![]() ![]() |
![]()
|
在这一章我将向您显示如何通过对 java.policy 文件进行特殊配置来启用 SecurityOps weblet 中的附加操作。在对自己系统中的 java.policy 进行特殊配置时,您最好先学习 Java 2 平台的安全性文档(请参阅 参考资料),并备份您的 java.policy 文件。
清单 4 显示了 java.policy 示例文件的一部分。请仔细看一下,我们将在下面对它进行详细讨论。
通过浏览这个 java.policy 文件,您会看到几个 grant 语句(尽管最后几句被注释掉了)。每一个 grant 列出一个或多个将被授予一组特殊程序的许可。可通过命名一个 permission 类对这些许可进行定义,这个类是 java.security.Permission 的一个子类。各种 Java API 都提供 permission 类来管理对特定资源的访问。例如:
- java.net.SocketPermission 控制通过套接字对网络的访问。
- java.util.PropertyPermission 控制读/写系统属性。
- java.lang.RuntimePermission 控制运行时的行为,比如对打印作业进行排队。
permission 类可能会需要 java.policy 中的一些参数;细节问题请参阅 参考资料。
被授予许可的程序是通过“codebase”进行定义的,它本质上是一个 URL,Java 类通过它被载入。清单 4 中的第一个(也是最大的一个) grant 语句没有定义 codebase,所以不管那些程序是从本地文件载入还是通过 Web 载入,列出的许可都被授予 所有的程序。这个 grant 是从缺省 java.policy 中复制过来的,它定义了 Applet、Weblet 以及其它所有在 SecurityManager 控制下运行的类的缺省沙箱。
在这里添加许可要非常小心!
grant 语句授予“看”特定系统属性的许可。例如,列出了 os.name ,SecurityOps 就能载入该属性。没有列出的系统属性就无法获取,这就是为什么试图载入 user.name 时会抛出一个异常。
清单 4 显示了三个 grant 语句,这些语句可以启用这个 SecurityOps weblet 中的附加功能。由于它们被注释掉了,所以示例程序初始在缺省的沙箱中运行。在所有这三种情况下,codebase 是由 SecuritySamples.jar 构成。前两种情况适用于 jar 文件从本地磁盘载入的情况。如果把这两句的注释去掉并且对 codebase 进行特殊配置以适合您的安装,您可以启用 SecurityOps weblet 中的“print”和“connect”示例。例如,我的策略文件包含对本地 Weblet 的许可,如清单 5 所示。
清单 5. java.policy:本地 Weblet 的许可
// Enable printing, when loaded from a local file |
清单 6 显示如何在 grant 语句中授予和清单 5 中相同的两种许可;如果 jar 文件是从服务器载入的,您会用到这种类型的许可。
清单 6. java.policy:接受服务的 Weblet 许可
// Enable printing and connections, when served by a web server |
当然,必须对 codebase 中定义的特定目录或服务器进行特殊配置以适合您的安装环境。
注意,当 codebase 被作为特定的 jar 文件定义时, grant 中的 codebase 可以被定义为下面几种类型:
- 一个特定的 jar 文件(本地的或者接受服务的)
- 特定目录中的 jar 文件
- 目录树中的 jar 文件
- 来自特定服务器的 jar 文件
- 带有一个特殊电子签名的 jar 文件
授予许可时最好是定义得尽可能明确。如果一个 Weblet 需要附加的许可,最好是把这个 Weblet 的类隔离到一个专门的 jar 文件中,然后只需对 该 jar 文件授予那些许可即可。这样可以减少无意负面影响的发生机率(也即,为一个特定 Weblet 指定的特权不会被意外地授予其它的代码)。
通过添加附加的许可,可以启用 SecurityOps 中的许多操作。利用 java.policy 文件可以做许多工作,我们只是接触了一些皮毛。有关更多信息,请参阅 参考资料。
![]() ![]() |
![]()
|
如您所见,一个 Weblet 可以在缺省情况下连接到为之服务的服务器。另外,还可以通过对 java.policy 文件进行特殊配置,以授予 Weblet 连接其它系统的许可。到目前为止,Weblet 安全性与 Applet 安全性很相似。但是在这里要指出 Weblet 与 Applet 之间有一个很重要(而且很复杂)的差异。
如果您的浏览器被配置成通过 SOCKS 代理连接到其它的系统,那个代理将会破坏 Weblet 的建立连接的能力。在这样的配置下,所有的连接实际上是连到 SOCKS 代理,此代理代表您建立连接并返回数据。例如,如果您想要连接到“my.home.server.com”,您会看到一个异常报告说您需要连接“ my.socks.proxy”的许可。这是很令人头痛的,但是我们可以设法解决这个问题。
您可以授予您的 Weblet 连接到 SOCK 服务器的许可,但是,在授权的时候,应该仔细限制许可的范围;也就是说,将 grant codebase 限制为 仅需要这种许可的 Weblet。可以连接到 SOCKS 服务器的 Weblet,也可通过 URL 操作连接到其它的系统。所以,给予“所有人”连接 SOCKS 服务器的许可是一个安全隐患。只应该将这种许可授予那些您信任的“人”。清单 7 显示了如何回避 SOCKS。
清单 7. java.policy:回避 SOCKS
// enable sample weblet connections in a SOCKS environment |
据说,将来的 JDK 将包含一个改进的 socket factory。这可能是 SOCKS 问题的真正解决方案;目前,我们只能小心(并仔细)地启用 Weblet 以连接到 SOCKS 服务器。
![]() ![]() |
![]()
|
您已经看到了,DirectDOM 被很好的建立来帮助您管理系统的 Weblet 安全性。在本文中,我们已经逐步了解了 DirectDOM 的基本工作原理,如下所述:
- 在启动时,DirectDOM 引擎调用 SecurityManager ,使用 Java 平台的安全性方法实现 Weblet 沙箱。
- DirectDOM 动态地授予 Weblet 的类连接自己的 hosting server 的许可。
- 在缺省的沙箱中被授予的许可是由可应用的 java.policy 文件的内容来控制的。所以,同一个系统中的 Weblet 和 Applet 共享同一个沙箱。
记住这些设置,通过我已经提供的示例,以及 Java 安全性工作的基本知识(请参阅 参考资料),您应该能够开发安全可靠的 Weblet。练习您已经学过的东西 ― 记住仅在必需许可的时候才授予许可,仅对那些需要许可的 Weblet 类授予许可。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130444/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/374079/viewspace-130444/