HTTP头部长度限制应设为8KB,默认安全;recv需用固定栈缓冲区并实时检查长度,超限即断连;解析时须对字段名/值单独限长、防越界拷贝,并在接收、结束标记检测、单字段解析三处校验。

必须在解析 HTTP 请求头前就做长度截断,否则 recv 进来的原始字节流直接进解析器,std::string 或 std::vector 会无条件扩容,直到 OOM 或触发 ASLR 保护崩溃。
HTTP 头部长度限制该设多少才合理
HTTP/1.1 协议本身不限制头部大小,但现实服务端必须设硬上限。主流实践是:
-
8KB是较安全的默认值:覆盖绝大多数正常请求(含 JWT、长 Cookie、多级反向代理注入的X-Forwarded-For) -
16KB可用于调试或内网可信场景,但上线前务必压测内存分配行为 - 绝不能依赖
Content-Length判断头部大小——它只管 body,header 完全独立 - Apache 默认
LimitRequestFieldsSize是8190字节,Nginx 的large_client_header_buffers默认4 8k,可作参考
recv 循环中怎么安全累积 header 数据
不能等所有数据收完再解析,也不能无脑 append 到缓冲区。关键动作是:
- 用固定大小栈缓冲区(如
char buf[8192])调用recv,每次最多读sizeof(buf)-1字节 - 每次
recv后立即检查累计长度是否 ≥ 预设上限(如8192),超限立刻关闭连接并记录日志 - 检测到
"\r\n\r\n"结束标记后,立即停止接收 header,剩余字节留给 body 解析逻辑处理 - 避免使用
std::stringstream或std::string::operator+=在循环中拼接——它们可能触发多次堆重分配
解析时怎么防字段名/值越界拷贝
即使 header 总长合规,单个字段也可能异常长(比如伪造的 User-Agent 填满 8KB)。解析逻辑必须:
立即学习“C++免费学习笔记(深入)”;
- 对每个
name和value字段单独设长限制(如 name ≤128字节,value ≤2048字节) - 用
strnlen/memchr替代strlen/strstr,防止扫描越界 - 写入目标
std::string前先reserve(),且 reserve 值不能超过该字段允许最大长度 - 遇到超长字段,不报错继续解析,而是跳过该行(RFC 7230 允许忽略非法字段),但记为可疑请求
最易被忽略的一点:防御不是只做一次校验。header 长度检查要出现在三个位置——recv 累积时、"\r\n\r\n" 检测后、单字段解析时。少任何一环,攻击者都能绕过。


















