14 安全性
代码的安全漏洞大都是由代码缺陷导致,但不是所有代码缺陷都有安全风险。理解安全漏洞产生的原理和如何进行安全编码是减少软件安全问题最直接有效的办法。
原则13.1 对用户输入进行检查。
用户输入通常需要经过检验以保证安全,特别是以下场景:
用户输入作为循环条件
用户输入作为数组下标
用户输入作为内存分配的尺寸参数
用户输入作为格式化字符串
用户输入作为业务数据(如作为命令执行参数、拼装sql语句、以特定格式持久化)
这些情况下如果不对用户数据做合法性验证,很可能导致DOS、内存越界、格式化字符串漏洞、命令注入、SQL注入、缓冲区溢出、数据破坏等问题。
可采取以下措施对用户输入检查:
用户输入作为数值的,做数值范围检查
用户输入是字符串的,检查字符串长度
用户输入作为格式化字符串的,检查关键字“%”
用户输入作为业务数据,对关键字进行检查、转义
14.1 字符串操作安全
规则13.1 确保所有字符串是以NULL结束。
C语言中‟\0‟作为字符串的结束符,即NULL结束符。标准字符串处理函数(如strcpy()、strlen())依赖NULL结束符来确定字符串的长度。没有正确使用NULL结束字符串会导致缓冲区溢出和其它未定义的行为。
为了避免缓冲区溢出,常常会用相对安全的限制字符数量的字符串操作函数代替一些危险函数。如:
用strncpy()代替strcpy()
用strncat()代替strcat()
用snprintf()代替sprintf()
用fgets()代替gets()
这些函数会截断超出指定限制的字符串,但是要注意它们