关于安全编程的一些小建议
将依赖于用户输入的数据都看做不安全数据:
1.空指针
2.字符串的长度
3.在限定有输入时的长度 的符号类型
4.输入时候的符号
5.严格判断输入的类型与所处理的数据的类型是否符合
6.禁止格式化输出
一般程序员在编写一个函数的时候,只会注意到函数的实现功能,往往忘记了在函数编写过程当中的一些安全因素
其实这些东西才是一般大型的公司考察一个程序员是否成熟的标志,当然,只是一方面
1:空指针
一般在接受一个参数的时候,如果该参数是一个指针或者字符串,当然这里的字符串是传统的C 的char *string 类型
你是否会考虑到可能传入的是一个空指针,如果函数中应用了一个空指针作为数据,将会导致程序因非法内存访问而终止
所以在查看参数的时候,如果是指针类型或者字符串类型,请先判断
ex:
int Opcheck( char * string )
{
if( NULL == string )
return -1;
}
// 为什么是 NULL == string 而不是使用 string == NULL ,请读者自己想想这样的好处
2:字符串的长度
如果你的输入的参数是一个字符串,那么请注意了,最好做出长度检测,因为这可能是造成缓冲区溢出的一个BUG
特别涉及到如果你的字符串需要拷贝的时候,那么请做好长度检测或者是使用安全的字符串拷贝函数
int Opcheck( char *string )
{
if( NULL == string )
return -1;
enum { BUF_SIZE = 1024 }
char buf[BUF_SIZE]; //作为缓冲区的结构
if ( strlen(string) >= BUF_SIZE )
return -1;
...
}
3:在限定有输入时的长度 的符号类型
如果您的输入是整数或者浮点数类型,请判断你的数据的长度和大小,
整数溢出攻击在某一段时间是黑客垂涎若渴的东西,发现了他,就是你的BUG 了
举个例子
char * Opcheck( int n )
{
char *pbuf = (char *)malloc(n);
return pbuf;
}
这里的程序有两个地方不好,你看出来了么?
1:从软件工程的角度来说,加剧了函数之间的耦合度,当然这里只是随便提一下,因为必须有人要释放你所申请的内存 www.zzzyk.com
空间,必然会有程序员忘记释放,这是必须的
2:请参看 man malloc 或者MSDN 上的malloc()
void*malloc(size_tsize);
这里的malloc 的参数实际上是一个无符号型的整数,如果传入的参数是负数,结果会怎样?
编译器不会报错,有可能是采取这样的操作 n = n %( limit + 1 )
或者直接传入负数,程序会怎样.. 你我都清楚
所以在这里,应该将程序改为
char * Opcheck( int n )
{
if( n <= 0 )
reuturn NULL ;
char *pbuf = (char *)malloc(n);
return pbuf;
}
4.输入时候的符号
跟第三条大同小异,注意输入时的符号
5:严格判断输入的类型与所处理的数据的类型是否符合
将一个负数传递给本来的无符号数的时候会产生一定的后果
如果处理字符串的时候需要的将字符串转变为一个整形的时候
需要判断字符串是否含有不属于数值的值,或者有,就跳过
6:禁止格式化输出:
int Myprint( char *string )
{
return printf(string);
}
这样的函数会按照你的想法打印出你的字符串,但是有没有想过
黑客会精心构造出字符串,然后造成你的缓冲区溢出
比如输入%n 就可以写入字符,而%x可以检查后面的内存,意味着你的函数堆栈将暴露在黑客手上
简单的防御方法就是,不要将你的输出暴露在外面,也即是说,禁止格式化输出,你的printf() 里面的字符串
不应该接受外来的输入
以上是一些经验小结,如果出现错误,请指教
摘自 _Boz From CUG 技术博客
补充:综合编程 , 安全编程 ,