C、C++和Java安全编码实践提示与技巧

对于所有类型环境中的开发人员来说,安全性正成为一个越来越重要的主题,即便过去一直认为安全性不成问题的嵌入式系统也是如此。本文将介绍几种类型的编码漏洞,指出漏洞是什么、如何降低代码被攻击的风险、如何更好地找出代码中的此类缺陷。

注入攻击

通过将信息注入正在运行的流程,攻击者可以危害进程的运行状态,以反射到开发人员无法保护的某种最终目标。例如,攻击者可能会通过堆栈溢出(stack corruption)将代码注入进程,从而执行攻击者选定的代码。此外,攻击者也可能尝试将数据注入数据库,供将来使用;或将未受保护的字符串注入数据库查询,获取比开发人员更多的信息。无论出于怎样的目的,注入总是一件坏事,总是需要谨慎对待的。

最恶劣的注入攻击形式也许是代码注入——将新代码置入正在运行的进程的内存空间,随后指示正在运行的进程执行这些代码。此类攻击如果成功,则几乎可以进行任何操作,因为正在运行的进程完全被劫持,可执行攻击者希望执行的任何代码。

此类攻击最著名的示例之一就是 Windows 动画光标攻击,这正是本文要讨论的模式。攻击者利用一个简单的 Web 页面将形式不当的动画光标文件下载到查看者的 PC 中,导致浏览器调用此动画光标,动画光标调用时可能发生任意代码的注入。实际上,这是一个完美的攻击载体:因为它不要求对被攻击机器的任何实际访问、最终用户根本意识不到任何可能发生的麻烦;此外,如果攻击效果的恶意也是适度的,则对最终用户的外部影响几乎是零。

考虑示例 1(a),当然,这改写自 Windows 攻击,它构成了此类攻击载体的基础。这里的开发人员对于传入流的可靠性做出了基本的假设。信任流和并相信一切都没问题。使用基于堆栈的将被非串形化(deserialized)的类型调用函数,未知数据流和代码注入肯定会在某个时间点出现。

(a)
void LoadTypeFromStream(unsigned char* stream, SOMETYPE* typtr)
{
int len;
// Get the size of our type's serialized form
memcpy(&len, stream, sizeof(int));
// De-serialize the type
memcpy(typtr, stream + sizeof(int), len);
}
(b)
void foo(unsigned char* stream)
{
SOMETYPE ty;
LoadTypeFromStream(stream, &ty);
}
(c)
void LoadTypeFromStream
(unsigned char* stream, SOMETYPE* typtr)
{
int len;
// Get the size of our type's serialized form
memcpy(&len, stream, sizeof(int));
// GUARD
if( len < 0 || len > sizeof(SOMETYPE) )
throw TaintedDataException();
// De-serialize the type
memcpy(typtr, stream + sizeof(int), len);
}

示例1 注入攻击。

这是怎样发生的?假设您调用示例 1(b)中的函数。我们就得到了一个易于利用的攻击载体。这里的问题在于 SOMETYPE 在编译时的大小是固定的。假设此类型在内存中使用 128 个字节表示。再假设您构建传入流时,使前 4 个字节(要非串形化的内容的长度)的读数为 256。现在,您没有检查正在处理的内容的有效性,而是将 256 个字节复制到了仅为 128 个字节的保留堆栈空间内。

考虑到发布模式堆栈的典型布局,您显然遇到了麻烦。查看堆栈,了解原因所在。每个被调用的函数都会将其本地数据布设到堆栈的一个帧内,通常是通过在输入时从堆栈指针减去本地数据的已知大小(加上处理调用链本身所需的任何管理数据)实现的。编译器发出的理想函数 prolog(伪代码)如下所示:

.foo
sub sp, 128  ; sizeof SOMETYPE

随后,对可利用函数的调用应如下所示:

push sp   ; push the SOMETYPE
local variable
push ap   ; push the stream
pointer (comes from 1st argument)
call LoadTypeFromStream
ret

时间: 2024-08-02 06:11:38

C、C++和Java安全编码实践提示与技巧的相关文章

Java 理论与实践:变还是不变?

不变对象具有许多能更方便地使用它们的特性,包括不严格的同步需求和不必考虑数据讹误就能自由地共享和高速缓存对象引用.尽管不变性可能未必对于所有类都有意义,但大多数程序中至少有一些类将受益于不可变.在本月的 Java 理论与实践中,Brian Goetz 说明了不变性的一些长处和构造不变类的一些准则.请在附带的论坛中与作者和其他读者分享您关于本文的心得.(也可以单击文章顶部或底部的"讨论"来访问论坛.) 不变对象是指在实例化后其外部可见状态无法更改的对象.Java 类库中的 String.

Java理论与实践:平衡测试,第2部分:编写和优化bug检测器

这一简短系列的 第 1 部分 介绍了如何进行有效测试,它构建了 FindBugs 插件来查找一个简单的 bug 模式(只需调用 System.gc() 即可).Bug 模式会 标识有问题的编码实践,它们常常位于 bug 所在的区域.当然,并不是所有出 现 bug 模式的地方都一定出现 bug,但这并不能抹杀 bug 模式检测器的巨大作 用.一个有效 bug 模式检测器的主要功能是发现更高百分比的可疑代码,使该 模式具有更大的使用价值.创建 bug 模式检测器可以提高使用价值:创建检测 器之后,无

Java理论与实践: 您的小数点到哪里去了?

许多程序员在其整个开发生涯中都不曾使用定点或浮点数,可能的例外是, 偶尔在计时测试或基准测试程序中会用到.Java语言和类库支持两类非整数类型 ― IEEE 754 浮点( float 和 double ,包装类(wrapper class)为 Float 和 Double ),以及任意精度的小数( java.math.BigDecimal ).在本月的 Java 理论和实践中,Brian Goetz 探讨了在 Java 程序中使用非整数类型时一 些常碰到的陷阱和"gotcha". 虽

Java安全编码:糟糕的在线建议和令人困惑的APIs

对于程序员和软件开发人员来说,网络论坛提供了一个交流知识和寻找具体编码难题答案的好地方.遗憾的是,他们并不总是准确信息的来源. 弗吉尼亚理工大学的一组研究人员分析了数百篇关于Stack Overflow的文章,(Stack Overflow是一个很受欢迎的开发者论坛或者说Q&A网站)发现许多提供答案的开发人员并没有意识到编码选项的安全含义,并显示出了缺乏网络安全培训. 他们发现的另一件事是,有时,最热门的帖子或答案包含了一些不安全的建议,这些建议会在软件中引入安全漏洞,而正确的修复程序不那么受欢

我的Java开发学习之旅------&amp;gt;Java字符编码解析

Java开发中,常常会遇到乱码的问题,一旦遇到这种问题,常常就很扯蛋,每个人都不愿意承认是自己的代码有问题.其实编码问题并没有那么神秘,那么不可捉摸,搞清Java的编码本质过程就真相大白了.               其实,编码问题存在两个方面:JVM之内和JVM之外.   1.Java文件编译后形成class 这里Java文件的编码可能有多种多样,但Java编译器会自动将这些编码按照Java文件的编码格式正确读取后产生class文件,这里的class文件编码是Unicode编码(具体说是UT

Hadoop项目实战-用户行为分析之编码实践

1.概述 本课程以用户行为分析案例为基础,带着大家去完成对各个KPI的编码工作,以及应用调度工作,让大家通过本课程掌握Hadoop项目的编码.调度流程.下面我们来看看本课程有哪些课时,如下图所示: 2.内容 2.1 Hadoop项目基础代码 本课时介绍编写Hadoop基础代码及脚本,在前面搭建好的Hadoop项目工程上, 完成项目的基本代码的编写,以及一些注意事项,为编写核心代码做准备,让大家掌握Hadoop项目的基础代码开发. 本课时主要包含以下知识点,如下图所示: 下面,我为大家介绍Hado

ElasticSearch实战-编码实践

1.概述 前面在<ElasticSearch实战-入门>中给大家分享如何搭建这样一个集群,在完成集群的搭建后,今天给大家分享如何实现对应的业务功能模块,下面是今天的分享内容,目录如下所示: 编码实践 效果预览 总结 2.编码实践 由于 ES 集群支持 Restful 接口,我们可以直接通过 Java 来调用 Restful 接口来查询我们需要的数据结果,并将查询到的结果在在我们的业务界面可视化出来.我们知道在 ES 集群的 Web 管理界面有这样一个入口,如下图所示: 我们可以在此界面的入口中

Kafka项目实战-用户日志上报实时统计之编码实践

1.概述 本课程的视频教程地址:<Kafka实战项目之编码实践>  该课程我以用户实时上报日志案例为基础,带着大家去完成各个KPI的编码工作,实现生产模块.消费模块, 数据持久化,以及应用调度等工作, 通过对这一系列流程的演示,让大家能够去掌握Kafka项目的相关编码以及调度流程.下面,我们首先来预览本课程所包含的课时,他们分别有: 接下来,我们开始第一课时的学习:<数据生产实现> 2.内容 2.1 数据生产实现 本课时主要给大家演示Kafka数据生产的代码实现,在前面搭建好的集群

《Java安全编码标准》一导读

前 言 在Java编程语言中,关键的安全编码要素是采用良好的文档和强制的编码规范.本书提供了在Java语言中的一系列安全编码规则.这些规则的目标是消除不安全的编码实践,因为这些不安全的因素会导致可利用的漏洞.如果应用这些安全编码标准,可以帮助设计出安全的.可靠的.健壮的.有弹性的.可用性和可维护性高的高质量系统,并且这些安全编码规范还可作为评估源代码质量特性的一个指标(不管使用的是手动的还是自动化的过程).对于使用Java编程语言开发的软件系统,这个编码规范具有广泛的影响. 目 录 第1章 概述