安全代码撰写
来自维基百科,自由的百科全书
安全代码撰写(Secure coding)是依照安全指引开发电脑软件,避免引入漏洞的软件开发实务。设计缺陷、程序错误及逻辑谬误是最常被利用软件漏洞的主要原因[1]。若识别出这些不安全的代码撰写实务,教育程序员改用较安全的软件写法,组织可以有主动的措施,在程序布置之前就消除或大幅减少软件漏洞[2]。
![]() |
有些研究者建议,为了有效的面对网络安全相关的威胁,应该在代码撰写时加入适当的安全性。若在软件设计时就已考虑安全性,这可以避免内部人士的攻击,也减少和应用程序安全有关的威胁[3]。
避免缓冲区溢出
缓冲区溢出是常见的软件安全漏洞,若程序要在固定长度的缓冲器存储超过其大小的资料,就会出现此一问题。例如,有8个位置可以存储资料,但程序却试着要存储9个资料,就会出现问题。缓冲区溢出会改写到邻近位置的存储器,造成安全漏洞(栈缓冲器溢出)或是程序中止执行(例如出现存储器区段错误)[1]
以下是一个容易出现缓冲区溢出的C语言程序例子
:
int vulnerable_function(char * large_user_input) {
char dst[SMALL];
strcpy(dst, large_user_input);
}
若用户输入的资料比缓冲器的大小要大,就会出现缓冲区溢出。
若要修正此一问题,可以用strncpy来避免缓冲区溢出
int secure_function(char * user_input) {
char dst[BUF_SIZE];
// copy a maximum of BUF_SIZE bytes
strncpy(dst, user_input, BUF_SIZE);
}
另一种作法是用malloc指令,在heap里动态分配存储器
char * secure_copy(char * src) {
size_t len = strlen(src);
char * dst = (char *) malloc(len + 1);
if (dst != NULL) {
strncpy(dst, src, len);
// append null terminator
dst[len] = '\0';
}
return dst;
}
在上述的程序片段里,程序设法将src的内容复制到dst,不过也会检查malloc的传回值,确定有足够的存储器可以分配存储器给dst。
避免格式字符串攻击
格式字符串攻击是恶意用户在输入一些会提供给格式设置函数(如printf())的资料时,输入特殊的内容,让函数的动作异常。此攻击会破坏性的读取或写入调用堆栈。
C语言的printf函数会将输出写到stdout。若其引数的格式有误时,会造成一些严重的安全错误。以下是一个格式字符串攻击的例子。
int vulnerable_print(char * malicious_input) {
printf(malicious_input);
}
像是"%s%s%s%s%s%s%s"就属于恶意输入,会因为不正确的存储器读取而让程序崩溃。
避免整数溢出
整数溢出会出现在整数运算的结果太大,用规划的存储器空间无法正确表示的情形。若程序没有检查整数运算的结果,设法避免整数溢出,可能会造成软件错误或是漏洞。
以下是C++的函数,原始目的是要确认x和y相加的结果小于等于已定义好的数值MAX:
bool sumIsValid_flawed(unsigned int x, unsigned int y) {
unsigned int sum = x + y;
return sum <= MAX;
}
这段程序的问题是在进行整数的加法之后才进行检查。若x和y的和大于unsigned int
可以表示的最大值,在进行加法之后就已出现溢出,因此虽然x和y的和大于MAX,但是其溢出后的结果可能会小于MAX。
以下也是检查溢出的程序,加上了检查x和y的和是否有大于等于x,y二个数值的判断,因为x和y是无号数整数,二者的和不会小于其中的任一数字。若是若计算出来的和小于任一数字,就代表已经溢出了。
bool sumIsValid_secure(unsigned int x, unsigned int y) {
unsigned int sum = x + y;
return sum >= x && sum >= y && sum <= MAX;
}
避免目录遍历
目录遍历是由不可靠来源提供的路径产生的漏洞,该路径造成了未授权的服务器目录或是文件访问。
例如,考虑一个接受文件名称,读取文章的脚本,脚本会读文件名称输入,之后进行处理。这样脚本可能会用类似以下的的URL 来找有关dog food的文章。
https://www.example.net/cgi-bin/article.sh?name=dogfood.html
若此脚本没有输入检查,相信用户输入的文件都是有效的,恶意用户可能会产生以下的URL来获取网站服务器的配置:
https://www.example.net/cgi-bin/article.sh?name=../../../../../etc/passwd
若是在类Unix系统中,这可能会泄漏/etc/passwd档,其中包括了用户ID、用户名称、家目录路径等。(SQL注入也是类似情境下的攻击)。
相关条目
参考资料
参考书目
Wikiwand - on
Seamless Wikipedia browsing. On steroids.