您的 Java 代码安全吗?
虽然客户仍然很关心您为他们构建的应用程序的可伸缩性和可用性,但他们可能变得也很关心安全性,而且要求特别严格。应用程序可能容易受到两类安全性威胁的攻击:静态和动态。虽然开发人员不能完全控制动态威胁,但在开发应用程序时,您可以采取一些预防措施来消除静态威胁。本文概括并解释了 13 种类型的静态暴露 ― 它们是系统中的缺陷,它使系统暴露在想要篡夺该系统的特权的攻击者面前。您将学会如何处理这些暴露,以及如何发现(如果不处理这些暴露)这些暴露可能造成的影响。
在开发 Java Web 应用程序时,您需要确保应用程序拥有完善的安全性特征补充。这里在谈到 Java 安全性时,我们并不谈及 Java 语言提供的安全性 API,也不涉及使用 Java 代码来保护应用程序。本文将着重讨论可能潜伏在您的 Java 应用程序中的 安全性暴露。安全性暴露是系统中的缺陷,它使系统无法 ― 即使系统被正常使用 ― 防止攻击者篡夺对系统的特权、控制系统的运行、危及系统上的数据安全或者假冒未经授权的信任。相对于安全性暴露,许多开发人员更加关心网站的感官效果。
毫无疑问,客户现在既严格地关注性能、可伸缩性和可用性也严格地关注安全性。应用程序可能容易受到两类安全性威胁的攻击: 动态和 静态。动态威胁是那些同未经授权进入系统有关的威胁,或那些同跨越网络传输的数据的完整性、隐私和机密性有关的威胁。这些威胁同应用程序的功能代码没有多大关系;使用加密、加密术和认证技术来消除这些威胁。相比之下,静态威胁却同应用程序的功能代码 有关;它们同进入系统的授权用户所做的事情有关。未知用户闯入系统是动态威胁的一个示例;授权用户以未授权方式操作系统内的代码或数据是静态威胁的示例。应用程序开发人员并不能完全控制动态威胁;但开发人员在构建应用程序时却可以采取预防措施来消除静态威胁。
在本文中,我们讨论了对付 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. 可克隆代码
class MyClass{
private int id;
private String name;
public MyClass(){
id=1;
name="HaryPorter";
}
public MyClass(int id,String name){
this.id=id;
this.name=name;
}
public void display(){
System.out.println("Id ="+id+"/n"+"Name="+name);
}
}
// hackers code to clone the user class
public class Hacker extends MyClass implements Cloneable {
public static void main(String[] args){
Hacker hack=new Hacker();
try{
MyClass o=(MyClass)hack.clone();
o.display();
}
catch(CloneNotSupportedException e){
e.printStackTrace();
}
}
}
建议
要防止类被克隆,可以将清单 4 中所示的方法添加到您的类中:
清单 4. 使您的代码不可克隆
public final Object clone()
throws java.lang.CloneNotSupportedException{
throw new java.lang.CloneNotSupportedException();
}
如果想让您的类可克隆并且您已经考虑了这一选择的后果,那么您仍然可以保护您的类。要做到这一点,请在您的类中定义一个为 final 的克隆方法,并让它依赖于您的一个超类中的一个非 final 克隆方法,如清单 5 中所示:
清单 5. 以安全的方式使您的代码可克隆
public final Object clone()
throws java.lang.CloneNotSupportedException {
super.clone();
}
类中出现 clone() 方法防止攻击者重新定义您的 clone 方法。
分享到:
相关推荐
Java 代码审计案例及修复旨在提供一个 Java 代码审计的实践指南,涵盖了 Java 代码审计的基本概念、安全编码规范、漏洞示例和修复方法等内容。 安全编码规范 在 Java 编程中,安全编码规范是非常重要的,它可以...
在这样的背景下,《Java代码审计(入门篇)》一书应运而生,为Java开发人员提供了一本详尽的代码安全审计指南,帮助他们掌握如何在开发阶段发现并修复安全漏洞,提升Java Web应用的安全性。 书中开篇即明确指出,...
总的来说,这份“Java安全性编程指南源代码”资源涵盖了Java安全编程的核心概念和技术,对于学习和实践Java安全编程有着极大的帮助。通过深入研究源代码,开发者可以更好地理解和应用这些安全机制,提高应用程序的...
【标题】:“#资源分享达人# 代码审计[java安全编程].doc.zip”指出这是一个关于Java安全编程的代码审计主题的资源,其中包含了对Java代码进行安全性审查的实践指南或教程。这个压缩包可能包含了一份详细的文档,...
### Java代码安全审计 在数字化转型的背景下,软件开发安全成为了企业关注的重点之一。Java作为全球最流行的编程语言之一,在企业级应用、Web服务及移动应用等领域占据着举足轻重的地位。因此,确保Java代码的安全...
Java代码审查表中关于安全性规则的重要性激活级别检查项有: * 是否确认了所有输入数据的合法范围是否都被进行了判断?(尤其是数组)(重要Y20) * 是否确认了所有函数对错误的处理是恰当的?(重要100) 九、...
代码安全性:Java提供了强大的安全机制,如访问控制、类加载验证、沙箱模型等。这些机制确保代码在运行时不会执行恶意操作或访问未经授权的资源。 身份认证和访问控制:Java安全包括用户身份认证和授权机制,以确保...
Java安全性编程是Java平台的核心特性之一,它旨在保护应用程序免受恶意代码的攻击,并确保敏感信息的安全处理。这个压缩包包含的源代码很可能是不同章节关于Java安全性的实例和示例,涵盖了广泛的议题。让我们逐一...
总结而言,该JAVA安全编码规范参考文档为开发者在编写安全的Java代码时提供了一套全面的指导方针,从基本原则到具体漏洞的解决办法,都有详细说明。遵守这些安全编码规范,能有效减少系统漏洞,提高Java应用的安全性...
13. **枚举与注解**:Java枚举类型提供了一种安全的常量表示方式,注解则用于提供元数据信息,两者在源代码中都有可能涉及。 14. **接口与默认方法**:Java 8引入了默认方法,使得接口不仅可以定义行为,还可以提供...
这个“Java代码直接转化成Smali代码工具”是一个完整的项目,它旨在帮助开发者或安全研究人员将Java源代码转换为Smali指令集,以便于理解、调试或修改Android应用的底层逻辑。 1. **Java与Smali的关系**:在Android...
PMD 是一个开源的静态代码分析工具,能够检查 Java 代码中的编码风格、命名约定、安全性、性能等方面的缺陷。PMD 提供了大量的规则和配置项,能够满足不同的需求和标准。 Jtest 是一个商业的静态代码分析工具,能够...
"Java代码保护,防止反编译" 本文讨论了Java程序的保护方法,以防止反编译和盗版。由于Java语言的特点,使得反编译变得非常容易。因此,保护Java程序变得非常重要。本文首先讨论了保护Java程序的基本方法,然后对...
Java代码实现短信猫发送短信是一项常见的通信应用,主要利用了串行通信技术。短信猫,又称GSM调制解调器,是一种硬件设备,通过USB或串口与计算机连接,可以实现短信的收发功能。在Java编程环境中,我们可以利用Java...
Java代码生成数字证书涉及到几个关键概念和技术,包括Java的密钥和证书管理、RSA加密算法以及非交互式证书创建。在此,我们将深入探讨这些主题,以便理解如何在Java环境中生成和使用数字证书。 1. **数字证书**:...
例如,使用AES加密的Java代码通常会涉及到`javax.crypto.Cipher`类,以及`SecretKey`的生成。开发者需要先创建一个密钥,然后利用`Cipher`类的`init()`方法初始化加密或解密模式,最后调用`doFinal()`方法执行加密或...
"java简单实例程序源代码"这个压缩包包含了一系列章节相关的Java实例源代码,适合初学者和有经验的开发者用来加深对Java语言的理解。以下是这些章节可能涉及的重要知识点的详细解释: 1. **CH11**: 这个章节可能...
Java代码混淆器是一种用于保护Java源代码安全的技术,通过让源代码变得难以理解和反编译,从而达到防止源代码泄露和被恶意利用的目的。在目前Java字节码反编译变得十分容易的背景下,源代码的混淆显得尤为重要。 ...