【问题标题】:Google app engine JRE Class "Black List"谷歌应用引擎 JRE 类“黑名单”
【发布时间】:2010-10-19 15:20:43
【问题描述】:

Google App Engine 有一个“JRE Class White List”。

我真正想要的是“黑名单”——换句话说,Java API 不能在 GAE 上运行。这样的清单存在吗?是否有任何开发人员在 GAE 上遇到 Java API 问题?

【问题讨论】:

  • 黑名单 = 所有类 - 白名单。我们还能说什么?
  • 正是mmyers所说的。如果这是一个答案,我会赞成!
  • 这是一个(糟糕的)用于得出答案的算法,而不是答案。而且没有帮助。
  • 实际上,这更像是一种表达“我不明白这个问题”的方式。
  • 但是,如果 Google 只是发布“白名单”,那么根据定义,这是否意味着所有其他类都将在“黑名单”上?

标签: google-app-engine java


【解决方案1】:

当我遇到此查询时,我正在寻找一些东西,因此想在 GAE(Google App Engine)的黑白名单上分享详细信息,以便任何遇到此类问题的人都可以正确解决它。详情:-

appengine-agentruntime.jar 有两个实例变量:-

private static Agent agent      
private static Set<String> blackList

我们从 agent & agent = AppEngineDevAgent.getAgent() 获得黑名单。所以如果我们检查 b) appengine-agent.jar 我们可以发现代理是Class&lt;?&gt; implClass = agentImplLoader.loadClass("com.google.appengine.tools.development.agent.impl.AgentImpl");

然后转到 AgentImpl 类,即 c) appengine-agentimpl.jar 我们可以 请参阅使用静态初始化在类加载时填充黑名单变量,它引用白名单来过滤允许的类。

static {
            initBlackList();
        }

    public static Set<String> getBlackList() {
        return blackList;
    }

    private static boolean isBlackListed(String className) {
        Set<String> whiteList = WhiteList.getWhiteList();
        return (!whiteList.contains(className))
                && (!className.startsWith("com.sun.xml.internal.bind."));
    }

终于可以检查 d) appengine-tools-sdk-1.8.3.jar 以获取所有 WhiteList 类的列表。

结论: 作为一种技巧,为了使用任何不属于此 WhiteList 的 JRE 类,需要使用 WhiteList 或 BlackList。如果您解压缩 appengine-agentruntime.jar 库并将拒绝方法的内容注释为

public static void reject(String className) {
    /*throw new NoClassDefFoundError(className + " is a restricted class. Please see the Google " + " App Engine developer's guide for more details.");*/
  }

然后再次 jar 并在您的项目中使用。希望它有所帮助。

----------------------------------------------- ------------------------------

a) appengine-agentruntime.jar :- 它包含实际的 Runtime 类,该类会为以下类抛出异常(来自 reject 方法)不属于上述白名单。

package com.google.appengine.tools.development.agent.runtime;

import com.google.appengine.tools.development.agent.AppEngineDevAgent;
import com.google.appengine.tools.development.agent.impl.Agent;
import com.google.apphosting.utils.clearcast.ClearCast;
//REMOVED OTHER IMPORTS TO KEEP IT SHORT

public class Runtime {

    private static Agent agent = (Agent) ClearCast.cast(
            AppEngineDevAgent.getAgent(), Agent.class);

    private static Set<String> blackList = agent.getBlackList();

    public static ClassLoader checkParentClassLoader(ClassLoader loader) {
        ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
        return (loader != null) && (loader != systemLoader) ? loader
                : Runtime.class.getClassLoader();
    }

    public static void recordClassLoader(ClassLoader loader) {
        agent.recordAppClassLoader(loader);
    }

    public static void reject(String className) {
        throw new NoClassDefFoundError(className
                + " is a restricted class. Please see the Google "
                + " App Engine developer's guide for more details.");
    }

    private static boolean isBlackListed(Class klass) {
        String className = klass.getName().replace('.', '/');
        return blackList.contains(className);
    }

    // REMOVED OTHER METHODS TO KEEP IT SHORT
}

b) appengine-agent.jar :-

package com.google.appengine.tools.development.agent;

import com.google.apphosting.utils.clearcast.ClearCast;
//REMOVED OTHER IMPORTS TO KEEP IT SHORT

public class AppEngineDevAgent {
    private static final String AGENT_IMPL = "com.google.appengine.tools.development.agent.impl.AgentImpl";
    private static final String AGENT_IMPL_JAR = "appengine-agentimpl.jar";
    private static final Logger logger = Logger.getLogger(AppEngineDevAgent.class.getName());
    private static Object impl;

    public static void premain(String agentArgs, Instrumentation inst) {
        URL agentImplLib = findAgentImplLib();
        URLClassLoader agentImplLoader = new URLClassLoader(
                new URL[] { agentImplLib }) {
            protected PermissionCollection getPermissions(CodeSource codesource) {
                PermissionCollection perms = super.getPermissions(codesource);
                perms.add(new AllPermission());
                return perms;
            }
        };
        try {
            Class<?> implClass = agentImplLoader
                    .loadClass("com.google.appengine.tools.development.agent.impl.AgentImpl");
            impl = ((AgentImplStruct) ClearCast.staticCast(implClass,
                    AgentImplStruct.class)).getInstance();
            AgentImplStruct agentImplStruct = (AgentImplStruct) ClearCast.cast(
                    impl, AgentImplStruct.class);
            agentImplStruct.run(inst);
        } catch (Exception e) {
            logger.log(
                    Level.SEVERE,
                    "Unable to load the App Engine dev agent. Security restrictions will not be completely emulated.",
                    e);
        }
    }

    public static Object getAgent() {
        return impl;
    }

    //REMOVED OTHER METHODS TO KEEP IT SHORT
}

c) appengine-agentimpl.jar :-

package com.google.appengine.tools.development.agent.impl;

import com.google.apphosting.runtime.security.WhiteList;
//REMOVED OTHER IMPORTS TO KEEP IT SHORT

public class BlackList {
    private static final Logger logger = Logger.getLogger(BlackList.class.getName());
    private static Set<String> blackList = new HashSet();

    static {
        initBlackList();
    }

    public static Set<String> getBlackList() {
        return blackList;
    }

    private static boolean isBlackListed(String className) {
        Set<String> whiteList = WhiteList.getWhiteList();
        return (!whiteList.contains(className))
                && (!className.startsWith("com.sun.xml.internal.bind."));
    }

    private static void initBlackList() {
        Set<File> jreJars = getCurrentJreJars();
        for (File f : jreJars) {
            JarFile jarFile = null;
            try {
                jarFile = new JarFile(f);
            } catch (IOException e) {
                logger.log(
                        Level.SEVERE,
                        "Unable to read a jre library while constructing the blacklist. Security restrictions may not be entirely emulated. "
                                + f.getAbsolutePath());
            }
            continue;

            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = (JarEntry) entries.nextElement();
                String entryName = entry.getName();
                if (entryName.endsWith(".class")) {
                    String className = entryName.replace('/', '.').substring(0,
                            entryName.length() - ".class".length());
                    if (isBlackListed(className)) {
                        blackList.add(className.replace('.', '/'));
                    }
                }
            }
        }
        blackList = Collections.unmodifiableSet(blackList);
    }

    private static Set<File> getCurrentJreJars() {
        return getJreJars(System.getProperty("java.home"));
    }

    //REMOVED OTHER METHODS TO KEEP IT SHORT
}

d) appengine-tools-sdk-1.8.3.jar :- 它有一个名为 WhiteList 的类,其中包括所有允许的 JRE 类。

package com.google.apphosting.runtime.security;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class WhiteList {
    private static Set<String> whiteList = new HashSet(
            Arrays.asList(new String[] {
                    "java.beans.Transient",
                    "java.lang.BootstrapMethodError",
                    "java.lang.Character$UnicodeScript",
                    "java.lang.ClassValue",
                    "java.lang.SafeVarargs",

                    //Removed other classes to keep this article short

                    "java.net.URLClassLoader",
                    "java.security.SecureClassLoader",
                    "sun.net.spi.nameservice.NameService" }));

    public static Set<String> getWhiteList() {
        return whiteList;
    }
}

【讨论】:

    【解决方案2】:

    我在我的 GAE 项目中使用 Servlet,但它不在白名单中,即使它可以正常工作。事实上,Google 提到了如何使用 Servlet,但它并没有在白名单中

    导入 javax.servlet.http.*;

    这里提到:

    http://code.google.com/appengine/docs/java/runtime.html

    但不包括在此处:

    http://code.google.com/appengine/docs/java/jrewhitelist.html

    我喜欢 GAE(因为免费配额),但文档一团糟。

    我使用 IntelliJ,当导入不在白名单中时,它会标记为错误。但是,可以禁用它。

    【讨论】:

      【解决方案3】:

      我在 Google I/O 上获得了一张宣传这项服务的卡片:

      LTech AppEngine Compatibility Analyzer

      听起来可能对您有用。我没试过,如果你试过,请回来评论。谢谢!

      【讨论】:

        【解决方案4】:

        他们似乎采取了更多的白名单方法:http://code.google.com/appengine/docs/java/jrewhitelist.html

        这里还有关于沙盒的更多详细信息(它可以访问哪些文件等等):http://code.google.com/appengine/docs/java/runtime.html#The_Sandbox

        这些限制似乎很直观(例如限制文件系统访问、没有 JNI 等)。

        【讨论】:

        • 其实安全限制的一般概念是可以理解的。但我不同意这解释了白名单是如何组成的。我的感觉是,它更多地基于开发人员对 API 的熟悉程度,而他们不太了解的 JDK 部分被忽略了。我的具体示例是 JSR-173(又名“Stax”),javax.xml.stream 下的类(没有明显原因被排除在外),但可能还有其他类。所以我希望有人对“如何”部分有一个很好的解释。
        猜你喜欢
        • 2014-08-26
        • 2023-03-28
        • 2013-05-03
        • 2011-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多