ImageVerifierCode 换一换
格式:DOCX , 页数:13 ,大小:20.40KB ,
资源ID:22820521      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/22820521.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Java编写过程中安全问题解决指南Word文件下载.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Java编写过程中安全问题解决指南Word文件下载.docx

1、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;MyClass mc = new MyClass();mc.methodIllegal

2、Set(Illegal Set Value);建议 一般来说,应该使用取值方法而不是 public 变量。按照具体问题具体对待的原则,在确定哪些变量特别重要因而应该声明为 private 时,请将编码的方便程度及成本同安全性需要加以比较。清单 2 演示了以下列方式来使之安全的代码:清单 2. 不带有 public 变量的代码 private int id;private String name;public void setId(int id) this.id = id;public void setName(String name) public int getId() return id;

3、public String getName() return name;让每个类和方法都为 final 不允许扩展的类和方法应该声明为 final。这样做防止了系统外的代码扩展类并修改类的行为。仅仅将类声明为非 public 并不能防止攻击者扩展类,因为仍然可以从它自己的包内访问该类。让每个类和方法都成为 final,除非有足够的理由不这样做。按此建议,我们要求您放弃可扩展性,虽然它是使用诸如 Java 语言之类的面向对象语言的主要优点之一。在试图提供安全性时,可扩展性却成了您的敌人;可扩展性只会为攻击者提供更多给您带来麻烦的方法。没有显式地标注为 public、private 或 prote

4、cted 的类、方法和变量在它们自己的包内是可访问的。如果 Java 包不是封闭的,那么攻击者就可以向包内引入新类并使用该新类来访问您想保护的内容。诸如 java.lang 之类的一些包缺省是封闭的,一些 JVM 也让您封闭自己的包。然而,您最好假定包是不封闭的。从软件工程观点来看,包作用域具有重要意义,因为它可以阻止对您想隐藏的内容进行偶然的、无意中的访问。但不要依靠它来获取安全性。应该将类、方法和变量显式标注为 public、private 或 protected 中适合您特定需求的那种。克隆允许绕过构造器而轻易地复制类实例。即使您没有有意使类可克隆,外部源仍然可以定义您的类的子类,并使该

5、子类实现 java.lang.Cloneable。这就让攻击者创建了您的类的新实例。拷贝现有对象的内存映象生成了新的实例;虽然这样做有时候是生成新对象的可接受方法,但是大多数时候是不可接受的。清单 3 说明了因为可克隆而暴露的代码:清单 3. 可克隆代码 class MyClass public MyClass() id=1;name=HaryPorterpublic MyClass(int id,String name) this.id=id;this.name=name;public void display() System.out.println(Id =+id+Name=+name)

6、;/ hackers code to clone the user class public class Hacker extends MyClass implements Cloneable Hacker hack=new Hacker();try MyClass o=(MyClass)hack.clone();o.display();catch(CloneNotSupportedException e) e.printStackTrace();要防止类被克隆,可以将清单 4 中所示的方法添加到您的类中:清单 4. 使您的代码不可克隆 public final Object clone()

7、throws java.lang.CloneNotSupportedException throw new java.lang.CloneNotSupportedException();如果想让您的类可克隆并且您已经考虑了这一选择的后果,那么您仍然可以保护您的类。要做到这一点,请在您的类中定义一个为 final 的克隆方法,并让它依赖于您的一个超类中的一个非 final 克隆方法,如清单 5 中所示:清单 5. 以安全的方式使您的代码可克隆 throws java.lang.CloneNotSupportedException super.clone();类中出现 clone() 方法防止攻击

8、者重新定义您的 clone 方法。序列化允许将类实例中的数据保存在外部文件中。闯入代码可以克隆或复制实例,然后对它进行序列化。序列化是令人担忧的,因为它允许外部源获取对您的对象的内部状态的控制。这一外部源可以将您的对象之一序列化成攻击者随后可以读取的字节数组,这使得攻击者可以完全审查您的对象的内部状态,包括您标记为 private 的任何字段。它也允许攻击者访问您引用的任何对象的内部状态。要防止类中的对象被序列化,请在类中定义清单 6 中的 writeObject() 方法:清单 6. 防止对象序列化 private final void writeObject(ObjectOutputStr

9、eam out) throws java.io.NotSerializableException throw new java.io.NotSerializableException(This object cannot be serialized通过将 writeObject() 方法声明为 final,防止了攻击者覆盖该方法。通过使用逆序列化,攻击者可以用外部数据或字节流来实例化类。不管类是否可以序列化,都可以对它进行逆序列化。外部源可以创建逆序列化成类实例的字节序列。这种可能为您带来了大量风险,因为您不能控制逆序列化对象的状态。请将逆序列化作为您的对象的另一种公共构造器 ? 一种您无法控

10、制的构造器。要防止对对象的逆序列化,应该在您的类中定义清单 7 中的 readObject() 方法:清单 7. 防止对象逆序列化 private final void readObject(ObjectInputStream in) be deserialized通过将该方法声明为 final,防止了攻击者覆盖该方法。您可能会尝试将诸如加密密钥之类的秘密存放在您的应用程序或库的代码。对于你们开发人员来说,这样做通常会把事情变得更简单。任何运行您的代码的人都可以完全访问以这种方法存储的秘密。没有什么东西可以防止心怀叵测的程序员或虚拟机窥探您的代码并了解其秘密。可以以一种只可被您解密的方式将秘密

11、存储在您代码中。在这种情形下,秘密只在于您的代码所使用的算法。这样做没有多大坏处,但不要洋洋得意,认为这样做提供了牢固的保护。您可以遮掩您的源代码或字节码 ? 也就是,以一种为了解密必须知道加密格式的方法对源代码或字节码进行加密 ? 但攻击者极有可能能够推断出加密格式,对遮掩的代码进行逆向工程从而揭露其秘密。这一问题的一种可能解决方案是:将敏感数据保存在属性文件中,无论什么时候需要这些数据,都可以从该文件读取。如果数据极其敏感,那么在访问属性文件时,您的应用程序应该使用一些加密解密技术。从事某个项目的某个心怀叵测的开发人员可能故意引入易受攻击的代码,打算日后利用它。这样的代码在初始化时可能会启

12、动一个后台进程,该进程可以为闯入者开后门。它也可以更改一些敏感数据。这样的恶意代码有三类:类中的 main 方法 定义过且未使用的方法 注释中的死代码 入口点程序可能很危险而且有恶意。通常,Java 开发人员往往在其类中编写 main() 方法,这有助于测试单个类的功能。当类从测试转移到生产环境时,带有 main() 方法的类就成为了对应用程序的潜在威胁,因为闯入者将它们用作入口点。请检查代码中是否有未使用的方法出现。这些方法在测试期间将会通过所有的安全检查,因为在代码中不调用它们 ? 但它们可能含有硬编码在它们内部的敏感数据(虽然是测试数据)。引入一小段代码的攻击者随后可能调用这样的方法。避

13、免最终应用程序中的死代码(注释内的代码)。如果闯入者去掉了对这样的代码的注释,那么代码可能会影响系统的功能性。可以在清单 8 中看到所有三种类型的恶意代码的示例:清单 8. 潜在恶意的 Java 代码 public void unusedMethod() / code written to harm the system public void usedMethod() /unusedMethod(); /code in comment put with bad intentions, /might affect the system if uncommented / int x = 100;

14、/ x=x+10; /Code in comment, might affect the /functionality of the system if uncommented 应该将(除启动应用程序的 main() 方法之外的)main() 方法、未使用的方法以及死代码从应用程序代码中除去。在软件交付使用之前,主要开发人员应该对敏感应用程序进行一次全面的代码评审。应该使用“Stub”或“dummy”类代替 main() 方法以测试应用程序的功能。对付中等严重性暴露的技巧 请遵循下列建议以避免中等严重性静态安全性暴露:不要依赖初始化 不要通过名称来比较类 不要使用内部类 您可以不运行构造器而分

15、配对象。这些对象使用起来不安全,因为它们不是通过构造器初始化的。在初始化时验证对象确保了数据的完整性。例如,请想象为客户创建新帐户的 Account 对象。只有在 Account 期初余额大于 0 时,才可以开设新帐户。可以在构造器里执行这样的验证。有些人未执行构造器而创建 Account 对象,他可能创建了一个具有一些负值的新帐户,这样会使系统不一致,容易受到进一步的干预。在使用对象之前,请检查对象的初始化过程。要做到这一点,每个类都应该有一个在构造器中设置的私有布尔标志,如清单 9 中的类所示。在每个非 static 方法中,代码在任何进一步执行之前都应该检查该标志的值。如果该标志的值为

16、true,那么控制应该进一步继续;否则,控制应该抛出一个例外并停止执行。那些从构造器调用的方法将不会检查初始化的变量,因为在调用方法时没有设置标志。因为这些方法并不检查标志,所以应该将它们声明为 private 以防止用户直接访问它们。清单 9. 使用布尔标志以检查初始化过程 public class MyClass private boolean initialized = false;/Other variables public MyClass () /variable initialization method1();initialized = true;private void me

17、thod1() /no need to check for initialization variable public void method2() if(initialized=true) /proceed with the business logic else throw new Exception(Illegal State Of the objectcatch(Exception e) 如果对象由逆序列化进行初始化,那么上面讨论的验证机制将难以奏效,因为在该过程中并不调用构造器。在这种情况下,类应该实现 ObjectInputValidation 接口:清单 10. 实现 Obje

18、ctInputValidation interface java.io.ObjectInputValidation public void validateObject() throws InvalidObjectException;所有验证都应该在 validateObject() 方法中执行。对象还必须调用 ObjectInputStream.RegisterValidation() 方法以为逆序列化对象之后的验证进行注册。 RegisterValidation() 的第一个参数是实现 validateObject() 的对象,通常是对对象自身的引用。注:任何实现 validateObje

19、ct() 的对象都可能充当对象验证器,但对象通常验证它自己对其它对象的引用。RegisterValidation() 的第二个参数是一个确定回调顺序的整数优先级,优先级数字大的比优先级数字小的先回调。同一优先级内的回调顺序则不确定。当对象已逆序列化时,ObjectInputStream 按照从高到低的优先级顺序调用每个已注册对象上的 validateObject()。不要通过名称来比较类 有时候,您可能需要比较两个对象的类,以确定它们是否相同;或者,您可能想看看某个对象是否是某个特定类的实例。因为 JVM 可能包括多个具有相同名称的类(具有相同名称但却在不同包内的类),所以您不应该根据名称来比

20、较类。如果根据名称来比较类,您可能无意中将您不希望授予别人的权利授予了闯入者的类,因为闯入者可以定义与您的类同名的类。例如,请假设您想确定某个对象是否是类 com.bar.Foo 的实例。清单 11 演示了完成这一任务的错误方法:清单 11. 比较类的错误方法 if(obj.getClass().getName().equals(Foo) / Wrong!/ objects class is named Foo else / objects class has some other name 在那些非得根据名称来比较类的情况下,您必须格外小心,必须确保使用了当前类的 ClassLoader 的

21、当前名称空间,如清单 12 中所示:清单 12. 比较类的更好方法 if(obj.getClass() = this.getClassLoader().loadClass(com.bar.Foo) s class is equal to /the class that this class calls s class is not equal to the class that / this class calls 然而,比较类的更好方法是直接比较类对象看它们是否相等。例如,如果您想确定两个对象 a 和 b 是否属同一个类,那么您就应该使用清单 13 中的代码:清单 13. 直接比较对象来看它们是否相等 if(a.getClass() = b.getClass() / objects have the same class / objects have different classes 尽可能少用直接名称比较。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1