常见C++安全编程规范

C++编程规范一般的公司都会有,但是涉及到安全相关的则比较少(可能在互联网上公开的少),本文将会介绍常见的安全编程规范,由于C++是一门极其复杂的编程语言,本文无法将所有安全相关的要求描述详尽,后续会不断进行完善更新,本文如有不正确的地方,也请各位读者指正。

2017.03.20

1、代码中不要硬编码明文口令等敏感信息;

说明:在代码中要避免硬编码明文口令、密码、身份证等用户敏感数据;

2、不要通过日志代码打印明文密码等敏感信息;

说明:为了方便的跟踪程序运行过程中的信息,通过日志打印信息是程序员编写代码时常用的一种调试方式,需要避免在日志中打印明文密码等敏感信息。

3、对不安全C++库函数进行重写后再调用;

说明:C++中的字符串相关库函数均为不安全函数,当相关参数可以被外界控制时就会存在溢出漏洞,C++常见的不安全库函数如下:

extern char *strcpy(char *dest,char *src)把从src地址开始且含有NULL结束符的字符串赋值到以dest开始的地址空间,返回dest(地址中存储的为复制后的新值)
char *strncpy(char *dest, char *src, size_tn)
把从src地址开始且含有NULL结束符的字符串赋值到以dest开始的地址空间,返回dest(地址中存储的为复制后的新值)
void *memcpy(void*dest, const void *src, size_t n)src指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内
int printf(const char *format, ...)向标准输出设备按规定格式输出信息
int fprintf(FILE *stream, const char *format, ...)将格式化的数据写入文件
int sprintf(char *str, char * format [, argument, ...])将格式化的数据写入字符串
int vfprintf(FILE *stream, char *format, va_list param)根据参数format字符串来转换并格式化数据,然后将结果输出到参数stream指定的文件中,直到出现字符串结束 (‘/0’)为止
int vsprintf(char *string, char *format, va_list param)送格式化输出到串中
scanf("<格式化字符串>"<地址表>)格式化输入函数,它从标准输入设备(键盘读取输入的信息
int sscanf( string str, string fmt, mixed var1, mixed var2 ... )从固定字符串输入到目标字符串
extern char *strcat(char *dest,char *src)src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')

重写这些函数的核心就是在函数内部检查输入参数的合法性,例如源字符串长度不超过目的字符串长度、最后一个\0的特殊处理等等。

4、定义了指针成员变量、静态成员变量的类必须重写拷贝构造函数;

说明:在C++中,有三种情况需要调用拷贝构造函数:

(1)对象以值传递的方式传递给函数参数;

(2)对象以值传递的方式从函数返回;

(3)对象需要使用另外一个对象进行初始化。

涉及拷贝构造函数的情况,有深拷贝和浅拷贝的情况,详情可以自行百度。

5、定义为基类的类的析构函数必须定义为虚函数;

说明:

Class A{};

Class B : public A{};

A *a = new B();

定义类A的析构函数如果不是虚函数,那么在通过delete a释放存储空间时,派生类的对象的存储空间不会被释放(派生类的析构函数不会被调用)。

相反,如果不需要基类对派生类及对象进行操作,则不能定义虚函数,因为这样会增加内存开销。

参考:http://blog.csdn.net/banbanlin/article/details/39557957

6、线程安全;

说明:在多线程的环境,需要考虑并发、线程同步、互斥锁等相关概念,任何操作都需要考虑有其他线程来竞争你当前拥有的资源。

7、不安全加解密算法检查;

不可逆加密算法:md5sha1RSA(小于1024位);

可逆加密算法:AES(小于128位),DESK1\K2\K3至少有两个相同);

上述加密算法均为不安全算法,要避免使用,同时在不需要还原业务数据的情况下要使用不可逆加密算法,哈希算法使用是最好要加一个盐值。

8、单例模式必须使用双重锁定;

说明:单例模式下类中会有一个全局私有的静态变量,在初始化该变量时必须使用双重锁定机制:

static Singleton *GetInstance()

{

    if (m_Instance == NULL )//第一次check

    {

        Lock(); //C++没有直接的Lock操作,此处仅为了说明

        if (m_Instance == NULL )//第二次check

        {

              m_Instance = new Singleton ();

        }

        UnLock();//C++没有直接的UnLock操作,此处仅为了说明 

    }

       return m_Instance;

 }

9、整数操作安全:有符号整数操作要避免溢出,无符号整数操作要避免反转。

说明:以32位整数为例,有符号数的取值范围是:-231次方到231次方-1有符号数的取值范围是:0232次方-1

对有符号整数、无符号整数进行操作时要提前进行判断操作结果是否会超出合法的范围。

例如对有符号整数num1num2进行相加操作,需要判断:if(num1 > MAX -num2)

如果条件成立则会溢出。

 

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页