资深程序员使用了最差的编程实践


37

我知道说起来似乎很奇怪,但是工作中的一名程序员故意使用了一些不良的编程实践!我会解释。首先,我要说他是一个有才华的人,大部分时间他都会编写可理解的代码。

他被要求在以Java编写的Web应用程序项目上实施许可。由于它是Java,因此如果真的愿意,人们可能会黑客打开罐子并读取其中编写的类和方法的名称。他对这个问题的解决方案是,从字面上说来笨拙地调用不太明显的名称和变量,并将它们植入已经拥挤的类中,而不是生成新类。

他的理由是,如果黑客想要切换某些类以绕过许可检查(并因此获得产品的免费副本),那么如果不清楚哪种方法,他将花费更多的时间。执行这些特定任务。只有在他完成之后,我才与他面对面,这表明我们也许可以购买某种混淆器库来为我们做,同时保持良好的编程习惯。他声称没有时间或资源来寻找这种解决方案。

..这让我陷入了困境。我是否正在寻找Java中的混淆器库并修复他的旧代码(对于重塑他的代码可能有些麻烦),还是我将其保留下来,以至于让我感到无休止?


4
如果您的问题是关于如何处理这种情况的政治问题,那么这里的许多答案都指向正确的方向,但是如果您的评论提出建议,那么您真的想提出一个更好的替代方案时,您可能需要检查一下出这个问题的答案:stackoverflow.com/questions/6018215/...
马克·布思

8
如果有权访问您的干净源代码的黑客可以破解您的身份验证,那么它是可入侵的。没有多少混淆会有所帮助。如果您正在寻找一种可以阻止某些黑客的解决方案,那么除了令人困惑之外,您还可能希望使用他的一些误导做法(将事情隐藏在不太容易发生的类中,不能轻易替换)。经常更改身份验证实践的频繁更新也有帮助。许多用户厌倦了依靠黑客而只是购买它。
Bill K

2
他是在重命名当地人吗?如果是这样,他就是在浪费时间-它们在已编译的代码中不以已命名变量的形式存在。
尼克·约翰逊

1
它被称为“混淆”,尽管近来越来越多地使用它,但它并不是完全可靠的。尽管它会延迟某人破解代码的速度,但还是可以破解!我想看到的是一个编译器可以对目标代码进行加密,并且只能使用正确的密钥来执行,因此即使使用磁盘编辑器,反汇编程序或任何其他破解工具的人也永远无法从中脱颖而出!
Frank R.

6
“他对这个问题的解决方案是,从字面上看,笨拙地调用不太明显的名称和变量,并将它们植入已经拥挤的类中,而不是生成新类。” 和“首先让我说他是一个聪明的人”在同一段中表现不佳!
2011年

Answers:


94

通过混淆进行的安全性永远不是好的安全性。必须有更好的方法来保护您的知识产权。这就是您和您的同事应该与您的经理共同提出的问题。如果管理层随后决定他们不愿意花费时间或金钱来提高安全性,那么你们俩都必须接受这个决定(这不是您的产品,而是公司的产品),最好不要花费(浪费?)在这个问题上有更多的时间。


31
+1迷惑不是安全的,只是舒适的毯子。
uɐɪ

7
如果您能提供比混淆更好的解决方案,那么我会将您的答案标记为正确的答案。您如何才能保证具有战争文件访问权限的人至少在许可方面不能修改其功能?
尼尔,

5
当有人可以访问文件时,您根本无法保证。但事实是:最简单的机制可以防止99,99%的用户对您的软件造成伤害。一个专门且技术娴熟的黑客将永远找到绕过应用程序安全性的方法。但是,您可以切换到远程验证,因此您的程序仅在针对您的服务进行身份验证时才会运行。为了确保安全,您需要加密整个程序并拥有某种引导程序。但是:如果有人获得了有效的密钥,他仍然可以再次对软件进行反向工程。
猎鹰

7
@Neil:在作为USB软件狗连接的微控制器中实现核心业务逻辑。您没有说它必须便宜或易于实现;)
SF。

8
@SF .:触摸。我认为应该同时需要三颗卫星同时链接,这只是它的地狱。;)
尼尔

84

原文:您的老板怎么说?找出来-做到这一点。


我被要求详细说明以上内容:

首先,我认为您有多个难题:

  • 您是否应该“修复”他人密码?
  • 其他人的实现(从A开始)是否足够糟糕,应该用其他东西代替?
  • 混淆器(此后为B)对于这种“嵌入到我们的应用程序中的许可”会更好吗?

首先,从业务案例来看,问题得以解决。A已经到位,并且很可能是该问题的“足够好”的解决方案。您的公司可能对它基本上只是受到足够的保护而感到满意,以至于需要为破坏它而刻意努力。

这意味着即使您不喜欢它(并且相信我,您在整个职业生涯中会看到很多更糟糕的事情),它仍然可以满足您的需求。因此,在解决问题后,您不应该“随便做”,而应说服负责您的工作的人长期此实现的价格将足够高,可以保证回滚并选择股票混淆器。这将需要您做大量准备工作,并且还请注意,混淆器也有您需要了解的缺点(其他答案很好地涵盖了这一点)。例如,堆栈跟踪不能立即使用,等等。这完全取决于避免盗版的重要性。请注意,最难破解的是那些需要硬件加密狗才能运行的加密狗,而且最有可能比客户希望的价格贵。

因此,此决定不是您要做出的,因为您的公司需要使用额外的资源去B。因此,您需要将您的疑虑带给负责人,充分解释此问题以及其他任何长期疑虑,以使他理解为什么您认为它不如您的建议。然后让他做出决定,无论结果如何,都要尊重并以专业的方式做出相应的举止。请注意,原始作者极有可能在撰写时仍然要对其进行维护,如果他离开或不再想要保留它,则可以再次提出该问题。

换句话说:您的老板怎么说?找出来-做到这一点。

还要注意,如果您提早提出问题,那么在实施A上浪费的时间会更小,这将是不同的。换句话说,当要在A和B之间进行选择时。

最后,我想评论一下您关于“仅修复其他人的代码”的问题。这对现有代码不是一个小小的修正(我发现它很好,并受到鼓励,特别是在进行测试的情况下)。这是一种破坏性的回滚和重新实现,即使在拥有通用代码所有权的团队中,未经事先批准,这也是不可接受的做法-至少对我来说是这样。

希望这可以澄清我的观点。


8
我的老板不是程序员,我可能很难解释为什么我们应该花时间和金钱做一些最终不会改变程序行为的事情。
尼尔

15
@Neil:...所以也许是时候向您的老板介绍“维护成本”的概念了吗?
SF。

21
这是否将成为对有关同事或工作环境的每个问题的默认回答?我知道一定要去告诉您将其发布为答案,但是请问,这不是答案。这实际上是一个关于半透明的安全性问题的半体面的问题(尽管措辞笨拙)。这个“答案”是侮辱性的。
亚伦诺特,2011年

8
@Aaronaught。当答案是“实现A不好,我建议我们执行实现B”时,这个答案就直截了当了,因为需要做额外的工作(等于钱)。如果在实施A或B之间进行选择,答案将是不同的。如果您想要更详细的答案,建议您在meta上提问。

22
“这是否将成为对有关同事或工作环境的每个问题的默认回答?” 为什么不?如果将其表述为技术性问题,例如“自动模糊处理v的手工编码(=不良实践)模糊处理哪个更好”,那么这是一个完全不同的问题,需要进行技术讨论。全部“我应该将其固定在我的同事后面吗?” 问题最终归结为“不,请团队/更高权力的关注”
Binary Worrier

13

我是否正在寻找Java中的混淆器库并修复他的旧代码(对于重塑他的代码可能有些麻烦),还是我将其保留下来,以至于让我感到无休止?

,与编写可疑代码一开始相比,落后于某个人并更改他们负责的代码将是更糟糕的冒犯。

您已经将它与程序员联系起来了,下一步就是保持警惕,或者与管理人员保持联系,然后对它保持警惕。


然后,当我将来在这些课程中钓鱼时,我想我只会nose鼻涕。
尼尔

3
如果您对该代码负有直接责任,则可以根据自己的喜好更改它,但是如果有共同责任,则需要有人进行仲裁。在这样的情况下很容易损害工作关系并浪费时间,最好是尽可能不提出问题。如果需要解决问题,请尽快解决。
DKnight

6

是否有任何形式的官方代码审查?或者您是否遇到过非正式的“代码审查”?我要说的是,由于这是诸如安全和许可之类的微妙而重要的主题,因此您需要将其提升到整个环节。您已经完成了第一部分-与程序员面对。但是,由于他现在不在听,您可以/应该接受它。如果您不这样做,则可能是问题的一部分。

我会告诉他您将要这样做-这可能会改变他的想法。如果不是,请向您的老板写一封政治上正确,准确而简洁的电子邮件,告知您的老板,并抄送程序员。在电子邮件中,要求你们三个人和/或任何其他参与方之间开会。

始终直面这些事情-但以政治和友好的方式。


当然是值得称赞的方法。我自己注意到代码修改,从SVN更新了我的代码。尽管有机会,但是如果他不同意,说服我的老板采取这些安全预防措施很可能不会导致任何改变,因为程序员可能会说它已经“起作用”了。
尼尔

2

如果您发现可以混淆类签名(方法名称等)的混淆器,那么,建议购买并使用它。

到那时,您可能不得不忍受它。我承认在最近的Grails项目中做过类似的事情-许可证检查被故意嵌入到已经很大的登录方法中,因此要替换该方法以绕过检查将非常困难。


1
我无法告诉您有多少困扰我,尽管您可能是正确的,我将不得不忍受它。
尼尔

2

他是否可以证明这样的黑客攻击是可行的,还是只是他有点担心的假设情况?他可以现场演示此工作吗?他应该尝试。说真的 如果有效,则应将其提交给管理层,然后建议使用混淆器。

如果混淆器不够安全,您是否研究过其他保护JAR的方法,例如加密它或将其编译为本地代码?

RE:修改他的代码:这仅仅是重命名吗?许多IDE都有重构工具,可以很容易地做到这一点。


他让我有点偏执,尽管我能明白为什么。如果产品被黑客入侵,则可能意味着他的工作。我不会说这是有可能的,但是我知道足以知道如何查找方法名称,如果有一个明显的方法叫做“ isLicenseValid”,那将是编写具有此方法并始终返回true的类的问题。 “砍”它。我认为该程序足够复杂,无需进一步复杂化,尽管他似乎想确定这一点。我想我可以通过重命名轻松修复他的代码,是的。
尼尔

仅仅因为您有一个名为“ isLicenseValid”的方法,并不意味着可以通过使用相同方法编写一个类来对其进行黑客入侵。如果您将类标记为“密封”(这是C#语法),则第三方不能仅仅通过编写子类并覆盖您的方法来规避安全检查。无论如何,除非这个人是公司的安全官,否则如果该产品被黑客入侵,那这意味着他的工作是什么呢?
Tundey 2011年

2
@Tundey,这与子类无关(如何加载它们):与编写相同的类并将被黑版本早于类路径搜索列表有关。
彼得·泰勒

1
ha。我记得用Java进行类加载的乐趣。仍然必须有一种更好的方法来减轻这种情况。实际上,如果您的类加载器没有受到损害,那么有人怎么能编写与您的类相同的类?特别是如果您的JAR已签名?签署您的JAR并密封您的班级是否可以解决某人编写与您的姓名相同的班级的问题?
Tundey 2011年

1
@Tundey Sun JVM是(大多数)开源的,您可以对其进行修改。
Spudd86

2

无论您的IP有多有价值,聪明的事情都不是为了使黑客感到困惑而破坏代码。除了继续前进将是一场噩梦之外,它并不能真正解决任何问题。这只会使难度增加,但并非没有可能。因此,这并不是真正的解决方案,副作用也很严重。这就像服药无效并且有不良副作用。

您的问题是如何保护您的IP。查找解决方案:混淆器,许可证服务器等。


我同意您的110%。关于保护IP的问题,这是我们客户的保障措施,因为尽管您提出了一个正确的观点,但运行Web应用程序的是他们的计算机,而不是我们自己的计算机。我更关心可以直接在他们的机器上访问我们的产品并可以将其拆开的客户。许可证服务器仅与客户端安全性一样好。如果您可以绕过访问许可证服务器,那么本书中的任何技巧都不会阻止您使用无许可证程序。
尼尔

1

我遇到了类似的问题时,另一位开发人员命名我们的加密/解密程序str__copystr__delete(注意第二个下划线)。这很la脚,本来可以做得更好,所以我们一直等到有一个故事需要更新许可。管理层在这几个小时的工作中没有问题,因为我们将其描述为“清理工作,因此下次我们进行许可时,将花费更少的时间,而且会更安全”。问题解决了,没有受伤的感觉。


当然,我们以后总是可以更改它,尽管我认为更改比代码更重要。
尼尔

1
@Neil然后,我建议您是需要换头的人。如果该代码有效,经过了充分的测试并且得到了很好的评论,那么使用该方法而不是使用混淆器并不是最好的选择,但这也不是世界末日。如果有问题,请稍后修复,否则继续进行。
Christopher Bibbs,

@Christopher_Bibbs:请放心。我几乎可以肯定地向您保证,实际上它最终会带来问题。
尼尔

1

我的第一个想法是维护该代码。如果代码已经被混淆并且他继续前进,那么请好运尝试获取该代码的句柄。然后,您将成为试图解密代码的黑客。

相反,我建议清理代码并使用混淆器来完成所有艰苦的工作。从长远来看,您将拥有许多易于管理的代码,并且所有疯狂的复杂性都留给了想要破解许可证的人。

请记住,没有一个混淆者是完美的,一个非常有决心的黑客可以对任何东西进行逆向工程,但至少只有他自己。加上混淆处理程序比一个人可能增加的复杂性高得多。


0

我高度同意您应该向老板询问此问题并回答他的意见的答案。

但是,这些答案的一个非常重要的附录是,您应该记录对安全性和可维护性的关注。无论您是否更改代码,重要的是让人们知道您所关注的内容以及原因。这很重要,既要主动(您的老板无法做出他甚至都不知道需要做出的决定),也要在防御上(如果/当黑客在安全性较差的许可系统中打洞时,他们不能责怪您的行为,这很重要)错误。)


0

“不要成为最了解问题的高级专业人员”。

换句话说,告诉老板,然后从那里去。如果您保持安静,并且您是那个秘密的顶极人物,那么当推到顶时,您将负责。告诉你的老板过去,让他决定解决的方法。这样,您就可以摆脱选择的负担。

不要仅仅告诉您的老板,因为很多管理人员可能不像技术人员那样,而是照常行事:给出问题和可能的解决方案,以及每种解决方案的优缺点。然后让他们决定并通过。这就是为什么经理/领导者获得高额薪水的原因!


0

一个简单的事实是,只要有足够的时间和资源,任何东西都可以被破解。这是您的应用受欢迎程度的简单功能。它越受欢迎,它吸引的技能就越强,并且将更多的时间用于破坏它。代码混淆提供了这一点-一种类似于加密的方法,可以增加破解它所需的时间。因此,如果您的代码被混淆了,则需要攻击者熟练并且花时间去编写,否则攻击者会绝望并放弃。您必须问自己,您的应用程序是否值得承担两端的麻烦。

实际上,破解混淆代码会变得多么困难,这真是令人惊讶。您可以通过混淆轻松地将一个简单的10行C程序转换为100行汇编。如果您尝试调试它,那么您将在代码中无意义地跳来跳去,可能真的很沮丧。最终它会破裂,但会变得非常困难,并且因为没有什么是真正不可能的,这才是重点。对代码的混淆减少了能够破坏代码的人数。

当然,有更好的方法,例如尝试使调试器(而不是破解程序)混乱,但这是一种廉价而有效的方法。但是,尴尬地命名并不能完全解决问题。您必须更改控制流调用函数,这些函数实际上不会为您的整体代码做任何事情,但是会增加代码的大小和复杂性:从真正起作用的内部函数调用返回值未在任何地方使用的伪函数。您已经知道如何使它真正令人困惑。

您拥有攻击者没有的东西。原始源代码。找到一种更好地为自己组织的方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.