草庐IT

java - AccessController 没有考虑类的 ProtectionDomain

coder 2024-03-31 原文

上下文

我正在编写一个 Java 系统,其中的代码在非常严格的沙箱中执行。一个查询(由一个或多个类组成)在执行期间只允许访问一个文件夹(以及文件夹中包含的子文件夹和文件)。

我通过使用 SecurityManager 和每次查询执行一个新的 ClassLoader 来强制执行沙盒。当使用 defineClassClassLoader 中定义类时,我传递了一个包含应授予的文件读取权限的 ProtectionDomain

由于并非调用堆栈上的所有对象都具有所需的权限,因此查询中的读取操作在 AccessController.doPrivileged(...) block 中运行。

问题

  • 当我直接从 doPrivileged(...) block 中调用 AccessController.checkPermission(...) 时,它会静默返回
  • 当我调用 System.getSecurityManager().checkPermission(...) 时,它将请求转发给 AccessController,然后 AccessController 抛出异常。
  • 当通过 SecurityManager 调用 AccessController 时,ProtectionDomain 似乎丢失了?
  • 限制文件操作(如创建 java.io.FileReader),直接调用 SecurityManager 而不是 AccessController如何让 AccessController 在通过 SecurityManager 调用时遵守调用 的类的 ProtectionDomain doRestricted(...)-block?
  • 会不会是 SecurityManager 本身没有所需的权限?因此,通过夹在特权代码之间的调用堆栈中,AccessController 生成一个无特权联合?

下面是一个示例部分:

AccessController.doPrivileged(new PrivilegedAction<QueryResult>() {
  public QueryResult run() {
    String location = folderName + "/hello";
    FilePermission p = new FilePermission(location, "read");
    try {
      AccessController.checkPermission(p); // Doesn't raise an exception
      System.out.println("AccessController says OK");
      System.getSecurityManager().checkPermission(p);  // Raises AccessControlException
      System.out.println("SecurityManager says OK");
    } catch (AccessControlException e) {
      System.out.println("### Not allowed to read");
    }
    return null;
  }
});

程序生成的输出,包括部分堆栈跟踪(PATH 替换使用的长路径名):

AccessController says OK
Asked for permission: ("java.io.FilePermission" "PATH/hello" "read")
java.security.AccessControlException: access denied ("java.io.FilePermission" "PATH/hello" "read")
  at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
  at java.security.AccessController.checkPermission(AccessController.java:560)
  at com.aircloak.cloak.security.CloakSecurityManager.checkPermission(CloakSecurityManager.java:40)
  at com.dummycorp.queries.ValidQuery$1.run(ValidQuery.java:23)
  at com.dummycorp.queries.ValidQuery$1.run(ValidQuery.java:1)
  at java.security.AccessController.doPrivileged(Native Method)
  at com.dummycorp.queries.ValidQuery.run(ValidQuery.java:16)
  at com.aircloak.cloak.security.CloakSecurityManagerTest$1.run(CloakSecurityManagerTest.java:75)
  at java.lang.Thread.run(Thread.java:722)

CloakAccessController.checkPermission(...) 实现可能也很有趣。它看起来像这样:

public void checkPermission(Permission perm) {
  if (Thread.currentThread().getId() == this.masterThread) {
    return;
  } else {
    System.out.println("Asked for permission: "+perm.toString());
  }
  AccessController.checkPermission(perm);
}

它的作用主要是绕过创建它的线程的安全限制。


我的java.policy的内容文件是标准 MacOSX 系统的文件。我相信它不包含任何非标准更改。

最佳答案

我觉得回答我自己的问题有点尴尬,但我找到了正确的解决方案,并认为将其添加到此处是正确的,因此将其记录在案以防有人偶然发现这个问题。

长话短说:

我的习惯SecurityManager没有正确的权限。因为它位于调用 doPrivileged(...) block 和 AccessController 之间的调用堆栈上, 特权的交集是根本没有特权。

长版

Java 安全模型的工作原理如下。当AccessController验证一个类是否被允许调用一个方法,它从调用栈的顶部到底部查看权限。如果调用堆栈中的每个条目都具有权限,则允许该操作。

这是一个任意的例子,一切正常:

+-----------+-------------------+-----------------------+
| Callstack | Class permissions | Permissions in effect |
+-----------+-------------------+-----------------------+
| Some      | {Read,Write}      | {Read}                |
| Other     | {Read}            | {Read}                |
+-----------+-------------------+-----------------------+

现在,就我的问题而言,调用堆栈中的较低层根本没有权限。 因此,我们最终得到这样的图片,其中顶部的 query 实际上没有权限。

+-----------+-------------------+-----------------------+
| Callstack | Class permissions | Permissions in effect |
+-----------+-------------------+-----------------------+
| Query     | {Read}            | {}                    |
| Other     | {}                | {}                    |
+-----------+-------------------+-----------------------+

您可以使用 doPrivileged(...) block 来解决这个问题。这允许通过调用堆栈的权限搜索在调用特权操作的条目处结束:

+-----------+-------------------+-----------------------+
| Callstack | Class permissions | Permissions in effect |
+-----------+-------------------+-----------------------+
| Query     | {Read}            | {Read}                |
| Other     | {}                | {}                    |
+-----------+-------------------+-----------------------+

这就是为什么当我从查询中调用 AccessController.checkPermission(...) 时一切正常的原因。毕竟它确实拥有正确的权限。 (不)幸运的是 java API(为了向后兼容)总是调用 SecurityManager .在我的例子中 SecurityManager根本没有特权。因为它实际上位于进行特权调用的查询和 AccessController 之间的调用堆栈上。 ,最终得到的权限为无:

+-----------------+-------------------+-----------------------+
|    Callstack    | Class permissions | Permissions in effect |
+-----------------+-------------------+-----------------------+
| SecurityManager | {}                | {}                    |
| Query           | {Read}            | {Read}                |
| Other           | {}                | {}                    |
+-----------------+-------------------+-----------------------+

解决方案

解决方案是给出 SecurityManager一组基本权限。结果,授予 Query 的权限确实是需要的权限:

+-----------------+---------------------+-----------------------+
|    Callstack    |  Class permissions  | Permissions in effect |
+-----------------+---------------------+-----------------------+
| SecurityManager | {Read,Write,Delete} | {Read}                |
| Query           | {Read}              | {Read}                |
| Other           | {}                  | {}                    |
+-----------------+---------------------+-----------------------+

呸!那真是一口啊!希望这对外面的人有用:)

关于java - AccessController 没有考虑类的 ProtectionDomain,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13819380/

有关java - AccessController 没有考虑类的 ProtectionDomain的更多相关文章

  1. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  2. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  3. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  4. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  5. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  6. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  7. 没有类的 Ruby 方法? - 2

    大家好!我想知道Ruby中未使用语法ClassName.method_name调用的方法是如何工作的。我头脑中的一些是puts、print、gets、chomp。可以在不使用点运算符的情况下调用这些方法。为什么是这样?他们来自哪里?我怎样才能看到这些方法的完整列表? 最佳答案 Kernel中的所有方法都可用于Object类的所有对象或从Object派生的任何类。您可以使用Kernel.instance_methods列出它们。 关于没有类的Ruby方法?,我们在StackOverflow

  8. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

  9. ruby - Rails 关联 - 同一个类的多个 has_one 关系 - 2

    我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下

  10. ruby-on-rails - 有没有办法为 CarrierWave/Fog 设置上传进度指示器? - 2

    我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r

随机推荐