C 代码安全漏洞分析:format_url_for_hs 函数缓冲区溢出风险
这段代码实现了一个函数 format_url_for_hs,用于将一个字符串格式化为一个用于匹配的正则表达式。代码的逻辑看起来没有问题,但是存在一个潜在的缓冲区溢出风险。
在函数中,使用了 alloca 函数动态分配了一个大小为 total 的缓冲区,用于存储格式化后的字符串。但是,在最后一行代码中,使用了 strlcpy 函数将格式化后的字符串拷贝到了 xfmt 这个由调用者传入的缓冲区中,而没有对拷贝的长度进行检查。如果 dst 字符串的长度超过了 xfmt_len,就会导致缓冲区溢出。
因此,需要在拷贝之前先检查 dst 字符串的长度,如果超过了 xfmt_len,则需要返回错误码。可以使用 strlen 函数获取 dst 字符串的长度,然后和 xfmt_len 进行比较。如果 dst 字符串的长度超过了 xfmt_len,就返回一个错误码。
以下是对代码的修改建议:
static int format_url_for_hs(const char *str, int len, char *xfmt,
int xfmt_len, int match_method)
{
unsigned int i = 0;
unsigned int total;
const char *now = str;
char *to, *dst = NULL;
if (!len)
return -1;
total = 2 * len + 4;
dst = alloca(total);
if (dst == NULL) {
strlcpy(xfmt, str, xfmt_len);
WAF_DBG("alloca len %u failed\n", total);
return 0;
}
to = dst;
if (str[0] != '*' && match_method == MATCH_ACCURATE) {
*to = '^';
to++;
} else {
i = 1;
now++;
}
for (; i < len; i++) {
if (is_metachar(*now)) {
*to = '\';
to++;
} else if (i && *now == '*') {
*to = '.';
to++;
}
*to++ = *now++;
}
if (str[len-1] != '*' && match_method == MATCH_ACCURATE) {
*to = '$';
to++;
}
*to = '\0';
assert(to < (dst + total));
// 检查 dst 字符串长度
if (strlen(dst) >= xfmt_len) {
return -1; // 返回错误码
}
strlcpy(xfmt, dst, xfmt_len);
return 0;
}
通过添加长度检查,可以有效避免缓冲区溢出风险,提高代码安全性。
原文地址: https://www.cveoy.top/t/topic/mikw 著作权归作者所有。请勿转载和采集!