为什么java安全编码很重要?

时间:2009-05-12 07:47:21

标签: java encapsulation security

我无法理解为什么java安全编码很重要。例如,为什么将变量声明为私有很重要?我的意思是我得到它将无法从类外部访问这些变量,但我可以简单地反编译该类以获取值。 类似地,将类定义为final将使得无法对此类进行子类化。什么时候继承类是危险的安全?如果有必要,我可以再次反编译原始类,并用我想要的任何恶意代码重新实现它。 当应用程序被用户“信任”时问题会出现吗?那么人们可能会以某种方式滥用这种信任? 基本上我正在寻找的是一个很好的例子,为什么应该遵循安全编码指南。

7 个答案:

答案 0 :(得分:15)

编程很难。

如果您定义了严格的API,那些不公开不应公开的变量(我们喜欢称之为encapsulation),那么您可以帮助API的用户,从而使编程更容易。这被认为是件好事。

原因主要不是“安全”,如保密秘密,清晰,简洁和可理解性。

作为奖励,如果您知道API的用户当然没有改变背后的“您的”变量,那么让事情正常工作要容易得多。

答案 1 :(得分:4)

它是“安全的”,意味着对使用它的人隐藏类内部工作。

术语安全未被使用,因为“保护服务器”用于表示一个类的用户不必担心类将如何执行他想要的任务这一事实。

举个例子:

暴露一个类的变量会让你的班级用户知道他们的存在,这是你不想要的,例如:你只需按一个按钮打开灯,你现在不需要在里面有铜或者它需要执行任务。

答案 2 :(得分:4)

Java是object-oriented programming语言,面向对象编程的关键概念之一是encapsulation

封装背后的想法是“隐藏”实现细节,例如保存对象状态的内部变量和算法等内部工作,并且只提供其他对象可以使用的接口以执行功能与对象。

使用该概念,人们希望通过使用private变量来隐藏内部状态,以防止其他对象直接影响内部状态。在Java中,通常会看到getter和setter(例如getColorsetColor)以便使用对象。

此外,封装也可以提高代码的健壮性。

例如,通过限制对内部状态的访问,可以在更改对象之前执行一些健全性检查。

作为一个可靠的例子,假设Score对象的percent0之间的值100。通过提供验证指定值在允许范围内的setPercent(int)方法,可以防止Score对象被设置为不可接受的状态。

因此,如果score.percent = 150方法导致错误,则可以阻止尝试通过编写类似setPercent的语句来直接操作内部状态,如果指定的值为Exception,则会抛出{{1}}不可接受的。

答案 3 :(得分:3)

这里有两个问题。

第一个将变量声明为protected或private时,它们不会成为您的公共API的一部分。其他课程可能在将来取决于您的课程,如果您想要包含新功能,提高绩效等,您可以尽可能地自由更改,这一点非常重要。如果您的所有价值观都是公开的,那么您的所有内容都是公开的。价值观和机制是公开的。改变它们可能会破坏依赖于你的其他类别。

第二个是,当暴露变量时,它允许其他类更改您的值。如果他们更改了您的内部值,可能会破坏您的程序,并创建奇怪的意外行为。如果您创建的系统依赖于您的类的准确性能,并且内部值发生了更改,那么您将无法再依赖该系统。子类化使这更复杂。您的系统可能依赖某种类型的类来执行预期的操作。通过子类化,可以创建一个看似相同类型但不执行预期操作的新类。

例如,如果您有一个带有受保护函数getArea()的类正方形,您希望返回一个正方形的区域。但是,可以制作一个扩展为square的新类,比如类矩形扩展为square。现在rectange可以覆盖getArea(),但它仍然是square类型,这可能会破坏依赖于square的功能的东西。通过让你的课程最终,你断言你的系统永远不会发生这种情况。

这种类型的“安全编码”不会阻止某人查看您的源代码,但它有助于使您的代码在将来更加可靠和可用。

答案 4 :(得分:1)

只是添加其他人已经说过的内容:其中一些功能也可以简单地被视为一种表达意图的方式。如果我成为一个成员private我让其他人“无法”访问它(这是可能的,但除了这里的重点之外),但更重要的是我告诉用户这是一个实现细节,他们不应该依赖。

答案 5 :(得分:1)

想象一下,如果您的对象具有非私有(隐藏)的内部属性,并且访问此属性的代码恰好在多线程环境中运行,那么N个线程将同时开始访问它,5个线程想要更​​改此属性,4阅读。你无法确保事情能够整齐地运行,这两个线程都不知道它当前拥有哪些数据并且成功地改变了该对象的属性。

您将需要编写一段特殊的代码来负责处理同步访问,但仍然无法保证您的代码能够正常工作,因为您仍需要检查程序中剩余的680个类,而不是访问该属性直接访问它。

简而言之,你遇到了一个大问题,调试是一场噩梦,因为你不知道数据何时被查询,哪个线程是这样做的,从哪里发生等等。

如果你没有封装......只有一种情况发生了......

好的,你的代码运行速度提高1%,堆栈负载更少,你可以获得可忽略不计的性能提升,你可以通过定期系统崩溃和成功调试的机会很小。

答案 6 :(得分:1)

术语“安全编码”指的是构建明显试图避免安全漏洞的软件,无论是C,Java,Ruby,汇编语言还是其他任何东西。在选择安全语言系统之后,也许最重要的部分是保持良好的编程实践。如果一个程序不清楚,那么你几乎没有机会值得信任。

对于Java,有两个值得注意的指南:

在Java中,有两种不同的安全编码模式。

在一个处理您可能没有代码所具有的所有权限的代码。例如,如果您正在编写库或签名代码,则需要执行此操作。恶意代码不可能以非预期的方式利用您的权限。这很难!

更常见的是,您正在处理仅处理不受信任数据的程序。例如,Web服务器(想想XSS和SQL注入)和桌面应用程序处理不受信任的文件(通常问题是C代码有缓冲区溢出 - 真正的C ++更好)。在某些情况下,拒绝服务(DoS)可能是一个严重的问题。

有一些重叠。例如,解释器以解释器代码的权限运行,并且可能非常“强大”。