Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
做java';s的内部类会带来安全风险吗?_Java_Security_Inner Classes - Fatal编程技术网

做java';s的内部类会带来安全风险吗?

做java';s的内部类会带来安全风险吗?,java,security,inner-classes,Java,Security,Inner Classes,最近,我项目的安全团队发布了一份安全代码指南文档,该文档旨在作为我们代码审查的一部分。首先让我印象深刻的是一条写着“不要使用内部类”的条款。我认为这似乎是一个非常严厉和笼统的声明。如果使用正确的话,内部类是很好的,对吗?但是我在谷歌上搜索了一下,找到了,这里引用是为了方便 规则5:不要使用内部类 一些Java语言书籍说 内部类只能由用户访问 包围它们的外部类。 事实并非如此。Java字节码具有 没有内部类的概念,所以内部 类由编译器翻译 进入普通的班级 可以访问同一版本中的任何代码 包裹第四条规

最近,我项目的安全团队发布了一份安全代码指南文档,该文档旨在作为我们代码审查的一部分。首先让我印象深刻的是一条写着“不要使用内部类”的条款。我认为这似乎是一个非常严厉和笼统的声明。如果使用正确的话,内部类是很好的,对吗?但是我在谷歌上搜索了一下,找到了,这里引用是为了方便

规则5:不要使用内部类

一些Java语言书籍说 内部类只能由用户访问 包围它们的外部类。 事实并非如此。Java字节码具有 没有内部类的概念,所以内部 类由编译器翻译 进入普通的班级 可以访问同一版本中的任何代码 包裹第四条规则说不要依赖 关于包装的保护范围

但是等等,情况变得更糟了。内心 类获取对 包含外部类,即使这些 字段被声明为私有。和 内部类被转换为 单独上课。为了让这个 对字段的单独类访问 外部类,编译器静默运行 将这些字段从私有更改为 包装范围!这已经够糟糕的了 内部类是暴露的,但它是 更糟糕的是,编译器是 默默地推翻你的决定 将一些字段设置为私有。不要使用 如果可以的话,可以使用内部类。 (讽刺的是,新的Java 2 doPrivileged()API使用指南 建议您使用一个内部类来 编写特权代码,这就是其中之一 为什么我们不喜欢这个 doPrivileged()API。)

我的问题是

  • 这种行为在Java5/6中仍然存在吗
  • 考虑到任何试图访问外部类私有成员的类(外部类和内部类除外)都不会编译,这实际上是一种安全风险吗
  • 它是否构成了足够的安全风险来警告“准则”“不要使用内部类”
  • 是的,这种行为仍然存在
  • 这是一个安全风险,因为rogue类可以用标准javac以外的其他东西构建
  • 这取决于你有多偏执:)如果你不允许在JVM中运行外来类,我看不出问题所在。如果你这样做了,你会有更大的问题(沙盒和所有)
  • 我知道你只有3个问题,但和这里的其他人一样,我认为这是一个愚蠢的限制

  • 在代码中使用这种安全性的想法有点愚蠢。如果需要代码级安全性,请使用模糊处理工具。正如@skaffman在上面的评论中所说,“代码可见性从来都不是一个安全特性。即使是私有成员也可以使用反射进行访问。”

    如果您正在分发编译后的代码,并且没有对其进行混淆,那么如果您担心有人修补您的隐私,那么使用内部类是您最后的担忧

    如果你正在托管你的代码,那么为什么你会担心有人窥探你的内部类呢

    如果您要链接一些您不信任的第三方代码,并且在运行时无法检查这些代码,那么就对其进行沙箱处理


    正如上面所说的,如果这是你公司的一个政策,请及时向你的公司报告

    < P>你应该考虑你的申请需要提供什么样的安全性。具有安全体系结构的应用程序不会遇到这些命名问题

    如果不允许用户对代码执行某些操作,则必须将此功能分离,并在服务器上运行(用户无权访问类文件)


    请记住,您始终可以反编译java类文件。不要依赖“默默无闻的安全”。即使是模糊的代码也可以被分析、理解和修改。

    恶意代码可以使用java反射来获取JVM中的任何信息,除非有安全管理器禁止这样做,这包括将私有字段更改为公共字段等等


    我个人的观点是,不这样做的原因被其他可能性所压倒,因此如果您需要它,使用内部类是有意义的,也是可读的。

    请注意,列出的缺点不适用于
    静态
    内部类,因为它们没有隐式访问其封闭类(或真正的对象)的权限

    因此,如果这条规则对您的公司有所帮助,那么最好将静态内部类排除在外,因为它们提供了一种封装方法,在许多情况下都很有用


    @Tom引用了“成员类可能是静态的,在这种情况下,它们无法访问周围类的实例变量”

    这一信息已经过时了大约十年。通过
    AccessController.doPrivileged
    广泛使用匿名内部类应该是一个线索。(如果不喜欢API,考虑<代码>的比例,尝试 >代码>最后< /COD>在JDK中不正确丢失的块)

    策略是,如果两个类由不同的类加载器加载或具有不同的证书,则它们不能共享同一个包。为了获得更多的保护,请在罐子的清单中将包装标记为密封的。因此,从安全的角度来看,“规则4”是假的,因此这条规则也是假的

    在任何情况下,制定安全策略时,您都应该了解您要防范的是什么。这些策略用于处理可能具有不同信任级别的移动代码(移动的代码)。除非您正在处理移动代码,或者您的代码将被放入可能需要的库中,否则这些预防措施没有什么意义。然而,使用健壮的编程风格几乎总是一个好主意,例如复制和验证参数和返回值

    这种行为在Java5/6中仍然存在吗

    您可以使用该工具确定二进制文件的公开内容和方式。

    package demo; public class SyntheticAccessors { private boolean encapsulatedThing; class Inner { void doSomething() { encapsulatedThing = true; } } }
    Compiled from "SyntheticAccessors.java"
    public class demo.SyntheticAccessors extends java.lang.Object{
        public demo.SyntheticAccessors();
        static void access$0(demo.SyntheticAccessors, boolean);
    }
    
    public class InnerExample {
        private int field = 42; 
    
        private class InnerClass {
            public int getField () { return field; };
        }
    
        private InnerClass getInner () { 
            return new InnerClass();
        }
    
        public static void main (String...args) {
            System.out.println(new InnerExample().getInner().getField());
        }
    }
    
    
    $ javap -classpath bin -private InnerExample
    Compiled from "InnerExample.java"
    public class InnerExample extends java.lang.Object{
        private int field;
        public InnerExample();
        private InnerExample$InnerClass getInner();
        public static void main(java.lang.String[]);
        static int access$000(InnerExample);
    }
    
    
    $ javap -classpath bin -c -private InnerExample
    static int access$000(InnerExample);
      Code:
       0:   aload_0
       1:   getfield    #1; //Field field:I
       4:   ireturn
    
    import java.lang.reflect.*;
    
    public class InnerThief {
        public static void main (String...args) throws Exception {
            for (Method me : InnerExample.class.getDeclaredMethods()){
                System.out.println(me);
                System.out.printf("%08x\n",me.getModifiers());
            }
    
            System.out.println(InnerExample.access$000(new InnerExample()));
        }
    }