热门问题
时间线
聊天
视角
安全程式码撰写
来自维基百科,自由的百科全书
Remove ads
安全程式码撰写(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。
Remove ads
避免格式字串攻击
格式字串攻击是恶意用户在输入一些会提供给格式设定函式(如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.
Remove ads