在本文中,我们讨论了对付 13 种不同静态暴露的技巧.对于每种暴露,我们解释了不处理 这些安全性问题所造成的影响. 我们还为您推荐了一些准则, 要开发不受这些静态安全性暴 露威胁的,健壮且安全的 Java 应用程序,您应该遵循这些准则.一有合适的时机,我们就 提供代码样本(既有暴露的代码也有无暴露的代码) . 对付高严重性暴露的技巧 请遵循下列建议以避免高严重性静态安全性暴露: 限制对变量的访问 让每个类和方法都成为 final,除非有足够的理由不这样做 不要依赖包作用域 使类不可克隆 使类不可序列化 使类不可逆序列化 避免硬编码敏感数据 查找恶意代码 限制对变量的访问 如果将变量声明为 public, 那么外部代码就可以操作该变量. 这可能会导致安全性暴露. 影响 如果实例变量为 public, 那么就可以在类实例上直接访问和操作该实例变量. 将实例变 量声明为 protected 并不一定能解决这一问题: 虽然不可能直接在类实例基础上访问这样的 变量,但仍然可以从派生类访问这个变量. 清单 1 演示了带有 public 变量的代码,因为变量为 public 的,所以它暴露了. 清单 1. 带有 public 变量的代码 class Test { public int id; protected String name;
Test(){ id = 1; name = "hello world"; } //code } public class MyClass extends Test{ public void methodIllegalSet(String name){ this.name = name; // this should not be allowed } public static void main(String[] args){ Test obj = new Test(); obj.id = 123; // this should not be allowed MyClass mc = new MyClass(); mc.methodIllegalSet("Illegal Set Value"); } } 建议 一般来说,应该使用取值方法而不是 public 变量.按照具体
问题具体对待的原则,在 确定哪些变量特别重要因而应该声明为 private 时, 请将编码的方便程度及成本同安全性需 要加以比较.清单 2
演示了以下列方式来使之安全的代码: 清单 2. 不带有 public 变量的代码 class Test {
private int id; private String name; Test(){ id = 1; name = "hello world"; } public void setId(int id){ this.id = id; } public void setName(String name){ this.name = name; } public int getId(){ return id; } public String getName(){ return name; } } 让每个类和方法都为 final 不允许扩展的类和方法应该声明为 final.这样做防止了系统外的代码扩展类并修改类 的行为.
影响 仅仅将类声明为非 public 并不能防止攻击者扩展类,因为仍然可以从它自己的包内访 问该类. 建议 让每个类和方法都成为 final,除非有足够的理由不这样做.按此建议,我们要求您放 弃可扩展性,虽然它是使用诸如 Java 语言之类的面向对象语言的主要优点之一.在试图提 供安全性时, 可扩展性却成了您的敌人; 可扩展性只会为攻击者提供更多给您带来麻烦的方 法. 不要依赖包作用域 没有显式
地标注为 public,private 或 protected 的类,方法和变量在它们自己的包内 是可访问的. 影响 如果
Java 包不是封闭的,那么攻击者就可以向包内引入新类并使用该新类来访问您想 保护的内容.诸如 java.lang 之类的一些包缺省是封闭的,一些 JVM 也让您封闭自己的包. 然而,您最好假定包是不封闭的. 建议 从软件工程观点来看, 包作用域具有重要意义, 因为它可以阻止对您想隐藏的内容进行 偶然的,无意中的访问.但不要依靠它来获取安全性.应该将类,方法和变量显式标注为 public,private 或 protected 中适合您特定需求的那种. 使类不可克隆 克隆允许绕过构造器而轻易地复制类实例. 影响 即使您没有有意使类可克隆,外部源仍然可以定义您的类的子类,并使该子类实现 java.lang.Cloneable.这就让攻击者创建了您的类的新实例.拷贝现有对象的内存映象生成了 新的实例;虽然这样做有时候是生成新对象的可接受方法,但是大多数时候是不可接受的. 清单 3 说明了因为可克隆而暴露的代码: 清单 3. 可克隆代码 clas