为什么 Java 安全编码很重要?
-
21-08-2019 - |
题
我无法理解为什么 java 安全编码很重要。例如,为什么将变量声明为私有很重要?我的意思是,我知道这将导致无法从类外部访问这些变量,但我可以简单地反编译该类来获取值。类似地,将一个类定义为 Final 将导致无法对该类进行子类化。什么时候对一个类进行子类化会对安全造成危险?如果有必要的话,我可以再次反编译原始类并使用我想要的任何恶意代码重新实现它。当应用程序被用户“信任”时,问题会出现吗?那么人们会以某种方式滥用这种信任吗?基本上我正在寻找的是一个很好的例子来说明为什么应该遵循安全编码指南。
解决方案
编程是困难的。
如果您定义的API严格,不暴露是不应该暴露变量(我们喜欢称之为的封装),您帮您的API的用户,从而使编程更加容易。这被认为是一件好事。
的原因并不主要是“安全”,如在保密事情秘密,尽可能清楚,简单性和可理解性。
作为奖励,它更容易把事情正常工作,如果你能知道API的用户是不会改变你的背后“你的”变量,当然。
其他提示
据“安全”,这意味着一类的内部工作是隐藏到谁使用它。
术语安全没有用作“保护服务器”用于打算的事实,一个类的用户不必担心类将如何执行,他希望它的任务。
以你的示例:
揭露一类变量,将让你的类知道它们的存在,这是你不想要的,例如用户:您只需按下一个按钮,把灯打开,你现在不需要这里面有铜或whater它需要执行的任务。
Java是一种面向对象编程的langauge,和的关键概念之一在面向对象的编程是封装。
后面封装的想法是“藏起来”的实现细节诸如保持物体和内部工作如算法的状态的内部变量,并且仅提供了其它的目的可以以执行函数使用的接口与对象
使用这一概念,一个想通过使用private
变量,以防止其它的目的从直接影响的内部状态来隐藏内部状态。在Java中,常见的是看到getter和setter(例如getColor
和setColor
),以便与对象一起工作。
此外,封装可以提高代码的鲁棒性为好。
例如,通过限制访问的内部状态,这将是可能的对象被改变之前执行一些完整性检查。
作为固体例如,假设有,这是有Score
和percent
之间的0
值的100
对象。通过提供一种验证该指定值的允许范围内的setPercent(int)
方法,这将防止Score
对象被设成不可接受的状态。
因此,试图通过写像score.percent = 150
一个语句直接操纵的内部状态可以防止,如果setPercent
方法导致错误或抛出Exception
如果指定值是不可接受的。
这里有两个问题。
第一个声明时变量作为保护或私有,他们不会成为你的公共API的一部分。其他类可能取决于你在未来的类,并且您可以自由更换尽可能多的,如果你想有新的功能,提高性能,等等。如果所有的值都是公开的比你们所有的内部是很重要的价值观和机制是公开的。改变它们可能会破坏其取决于你的其他类。
第二个是,曝光的变量时,它允许其他类改变你的值。如果他们改变你的内在价值,如果可以打破你的程序,并建立奇怪的意外行为。如果您创建依赖于一个你的类和内在价值的准确性能的系统被改变,比你可以不再依赖该系统上。继承使得这更复杂。您的系统可能依靠一类特定类型的执行预期的操作。通过继承,可以创建一个似乎是同一类型,但不执行预期的操作的新类。
例如,如果你有一个保护功能的getArea()一类方形,您希望返回一个正方形的面积。然而,一个新的类可以进行延伸广场,说类矩形扩展广场。现在rectange可以覆盖的getArea(),但它仍然是类型方形,这可能会破坏一些东西,取决于平方米的该功能的。通过使你的类最终你断言,这永远不能在你的系统出现。
这类型的“安全编码”不会阻止其他人看到你的源代码,但它有助于使你的代码在未来更可靠和可用的。
刚刚添加到别人已经说过:一些功能也可以简单地被视为一种方式来陈述打算。如果我做一个成员private
我让“不可能”为他人访问它(这是可能的,但是这除了这里的点),但更重要的是,我告诉用户,这是一个实现细节,他们不应该依赖。
想象一下,如果你的对象有内部属性这不是私有的(隐藏)和代码访问此属性发生在多线程环境下运行,所以N个线程将同时开始访问它,5个线程想改变这个属性,4读取。有没有办法,你要确保事情会整齐地运行两个线程就知道它持有该数据在当下并没有成功地改变了对象的属性。
您将不得不代码专题片将负责处理同步访问程序,仍然是不会成为guarrantee您的代码将正确的工作,因为你还是要检查680班的其余部分在你的程序访问该属性不直接访问它。
总之,你是在一个巨大的问题,和调试是因为你的噩梦不知道什么时候的数据chagned,哪个线程这样做,从那里它的发生等。
只是一个,如果你不封装发生了什么......的情况
好东西,你的代码运行速度更快的1%,对堆栈负荷较小,你已经取得了可能可以忽略不计的性能提升,你将与系统的周期性崩溃和全成调试轻微的机会付出。
术语“安全编码”是指明显试图避免安全漏洞的软件构造,无论是 C、Java、Ruby、汇编语言还是其他语言。在选择安全的语言系统之后,也许最核心的部分是保持良好的编程实践。如果一个程序不清楚,那么你就不太可能相信它值得信任。
对于 Java 有两个值得注意的指南:
- Java 编程语言的安全编码指南,版本 2.0。 两年前更新过,现在需要更新。
- CERT Sun Microsystems Java 安全编码标准。 由 CERT 和 Sun 支持的新 wiki,可以根据您认为重要的内容进行更新。这需要比 Sun 指南更广阔的视野。例如,Sun 指南并不真正关心整数溢出,因为所有数组边界都会被检查,但 wiki 却关心整数溢出,因为它仍然可能导致程序错误。
在 Java 中,有两种不同的安全编码模式。
在其中一种情况下,您正在处理的代码可能不具有您的代码所具有的所有权限。例如,如果您正在编写库或签署代码,您需要这样做。恶意代码不可能以意想不到的方式利用您的权限。这是困难的!
更常见的是,您处理的程序仅处理不受信任的数据。例如,Web 服务器(想想 XSS 和 SQL 注入)和处理不受信任文件的桌面应用程序(通常问题是 C 代码存在缓冲区溢出 - 真正的 C++ 更好)。在某些情况下,拒绝服务 (DoS) 可能是一个严重的问题。
有一些重叠。例如,解释器以解释器代码的权限运行,并且可能非常“强大”。