热门问题
时间线
聊天
视角

安全程式码撰写

来自维基百科,自由的百科全书

安全程式碼撰寫
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

避免格式字串攻击

格式字串攻击英语Format string attacks是恶意用户在输入一些会提供给格式设定函式(如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注入也是类似情境下的攻击)。

相关条目

参考资料

参考书目

Loading content...
Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads