--
分类: C/C++
2014-01-14 15:27:00
第二章 内存安全
字符串、数组、整数。
1、缓冲区溢出问题 这里主要针对动态缓冲区溢出:字符串拷贝、数组越界、字符串格式化//
Char buffer[10] , strcpy(buffer, str); 如果长度超过16就发生了缓冲区溢出,严重的会改变程序流程。
Strcat(),sprintf()检查缓冲区对于输入数据是否足够长很困难,目标缓冲区结束不是NULL则发生溢出,sprintf(),gest()没有边界最好使用fgets(),scanf()都具有安全隐患。Memcpy()目标缓冲区必须足够大,否则会发生缓冲区溢出。拷贝执行字符使用_memccpy()...
因此(1)需要进行有效的边界检查工作,开发者进行边界检查,或是使用带边界检查的编译器。(2)不适用有安全隐患的API,(3)程序指针的检查。
2、整数溢出
整数有固定的大小,大于可以表达的数就会产生溢出。
因此,编程之前需要详细的预测,充分考虑数据的取值范围,选取合适数据类型
3、数组越界
4、字符串格式化不当
例如printf(str)会出现隐患
程序代码区:制度数据和代码
静态存储区:初始化和为初始化数据,编译时分配,程序结束才回收
动态存储区:程序运行时需要才分配,是缓冲区溢出发生地
第三章 线程/进程安全
1、线程同步安全
多个线程之间可能会共享进程的内存资源,CPU时间片分配给哪个线程不被用户控制
Synchronized(同步锁对象this){........}
2、线程写作安全
3、线程死锁
4、线程控制
第四章 输入安全
输入字符串hello,ls;则会打印当前目录下文件,所以很危险,
总是会有没考虑到的情况,正确方法是确定输入的一个安全的格式是什么样子的,拒绝所有不符合这种格式的所有输入。
1、数字输入安全
格式:整数、小数;精度:保留位数;范围;
一般情况下可以使用正则化表达式进行验证字符串是否是数字。
(1)负数的验证,最好不通过符号位来确定概述是不是负数,输入过大整数溢出变为负数,需要进行底层的判断。特别注意数值溢出问题。
2、字符串输入安全
最简单的是使用正则化表达式。
常规特殊字符,一般在ASCII码表内,但是由于有时候会用来表达特定含义,如$、%、@、*、\0、\n等;攻击者可能用数字代替这个字符来进行输入,达到攻击的目的;
不在ASCII码表内,字符值大于127的国际化的字符,也可能会有许多可能的含义。例如,UTF-8 编码的字符,用两个字节进行编码,有些特殊字符也可以在该字符集里面进行表达,尽量不要使用;
和某些特定应用有关的字符或者字符串。如shell中的命令名称,如(rm、ls、mount)、SQL中的关键词或者关键字符(如select、注释符号--、单引号、exec)等。
在程序中有特定含义的字符。如某些系统中,将系统的配置信息用“#”隔开之后保存在配置文件内,这不是一个规定,但是可由软件的开发者在程序中自行确定;又如,在XML和HTML中用“<”和“>”表示节点,这些字符都不应该在合法范围之内。
3、环境变量安全
4、文件名安全
尽量减少用户输入文件名,而是默认,以免输入不合法文件名。若文件名-rf,则rm -rf则会出现安全隐患。不要使用物理设备名例如COM1
第五章
安全编码的建议
1、验证输入
2、注意编译器警告
3、采用安全策略的架构与设计
4、保持简单
5、默认拒绝
6、最小权限原则
7、清洁发送给其他系统的数据
8、纵深防御
9、使用有效的质量保证技术 渗透测试、Fuzz测试、源代码审计
10、采用安全标准 CERT C语言安全编码标准