curl `--proto` 协议白名单全解析:用三个修饰符精准管控传输协议
curl--proto协议白名单全解析用三个修饰符精准管控传输协议【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl本篇指南围绕 curl 命令行工具的--proto选项展开讲解如何通过、-、三种修饰符以从左到右的顺序表达式精准限制允许使用的传输协议并延伸介绍配套的--proto-redir重定向协议限制与--proto-default缺失 scheme 时的默认协议。读者读完将掌握协议白名单的完整语法、安全最佳实践并能理解该选项从命令行解析到 libcurl 底层位掩码的全链路实现原理。--proto是什么curl 是一个支持 DICT、FILE、FTP(S)、GOPHER(S)、HTTP(S)、IMAP(S)、LDAP(S)、MQTT、POP3(S)、RTSP、SCP、SFTP、SMB(S)、SMTP(S)、TELNET、TFTP、WS(S) 等众多协议的命令行传输工具。协议越多攻击面越大一个意外构造的 URL 可能让 curl 尝试访问你并不打算使用的协议例如从 HTTP 页面跳转到file://或smb://。--proto正是用来对本次传输“允许使用哪些协议”做白名单收口的关键选项。该选项的元信息见 docs/cmdline-opts/proto.md如下长选项名--proto参数protocols协议列表功能Enable/disable PROTOCOLS启用/禁用协议引入版本7.21.0分类connection curl重复使用仅一次Multi: single但多个协议可写在一个逗号分隔列表中--proto的值由逗号分隔的若干“协议条目”组成每个条目是一个协议名或特殊关键字all前面可以加一个修饰符。整条规则从左到右顺序求值后出现的条目基于前一个条目的结果继续修改这与很多配置文件的“覆盖式”语义不同理解这一点是用好它的前提。三个修饰符、-、根据 docs/cmdline-opts/proto.md 的定义每个协议条目可带三种修饰符修饰符语义说明允许在已允许的协议集合中追加该协议不加修饰符时的默认行为就是-拒绝从已允许的协议集合中移除该协议仅允许忽略此前已允许的协议集合只允许该协议但后续条目仍可继续修改结果三个修饰符的语义可以概括为是“加白名单项”-是“减白名单项”是“重置为只含此项”。由于规则从左到右求值之后出现的-或依然有效。原文档中的三个示例文档给出了三个可以立即上手的例子# 使用默认协议集合但禁用 ftps curl --proto -ftps https://example.com # 只启用 http 和 https写法一先用 -all 清空再用 http 追加 curl --proto -all,https,http $URL # 只启用 http 和 https写法二直接用 http,https 重置 curl --proto http,https $URL第一个例子说明-是在默认集合上做减法第二、三个例子殊途同归——-all配合与直接使用最终都只放行 http 和 https。注意-all本身是一个完整的协议条目修饰符- 关键字all。all关键字与空集合all表示“所有协议”可搭配修饰符使用-all清空允许集合从“全部允许”变为“全部拒绝”等价于一个空的协议集合all或all允许全部协议。若你的 curl 构建中某个协议未被编译进去或协议名拼写有误--proto会输出一条警告unrecognized protocol而不是直接失败。这一设计让脚本可以放心地“尝试禁用危险的协议”——即使该协议在构建时根本不存在也不会因为报错而中断脚本执行详见 src/tool_paramhlp.c 中未知协议的处理逻辑。重复使用选项--proto可以在一条命令行中重复出现多次效果等同于把所有条目拼接成一个逗号分隔列表。例如# 下面两条命令等价 curl --proto http,https --proto -https $URL curl --proto http,https,-https $URL协议名参考curl 支持哪些协议--proto中的协议名与 URL scheme 对应大小写不敏感。仓库中的 docs/cmdline-opts/_PROTOCOLS.md 系统列出了 curl 支持的协议及其用途整理如下协议用途dict使用在线词典查词file读写本地文件不支持远程file://Windows 下原生 UNC 方式可用仅绝对路径ftp/ftps文件传输协议可选 TLS 加密gopher/gophers获取文件http/httpsHTTP 协议依据构建选项与命令行参数可讲 0.9、1.0、1.1、2、3 版本imap/imaps邮件读取协议可下载邮件可选 TLSldap/ldaps目录查询可选 TLSmqttMQTT 3 版下载即订阅主题上传即发布主题MQTT over TLS 尚未支持pop3/pop3s从 POP3 服务器下载邮件可选 TLSrtspRTSP 1.0 下载scpSSH 2 版 scp 传输sftp基于 SSH 2 的 SFTPdraft 5smb/smbsSMB 1 版上传与下载smtp/smtps向 SMTP 服务器上传内容即发送邮件可选 TLStelnet交互式会话把 stdin 内容发给服务器并回显服务器输出tftpTFTP 下载与上传ws/wss基于 HTTP/1 的 WebSocketwss意味着走 HTTPS需要强调的是你本机 curl 构建实际支持的协议集合不一定包含全部。用curl --version输出中的Protocols:行可以查看当前构建真正内置了哪些协议见 src/tool_help.c 的实现该列表来自 libcurl 运行时的curl_version_info()返回的协议数组见 src/tool_libinfo.c。安全实践为什么以及怎么限制协议在自动化脚本、定时任务或任何处理不可信 URL 的场景中建议用--proto把允许集合收紧到业务必需的最小集通常就是# 脚本只允许 HTTP/HTTPS curl --proto http,https $URL # 需要允许重定向跟随时配合 --proto-redir 双保险见下文 curl --proto http,https --proto-redir http,https --location $URL这样做的好处是即使 URL 被篡改成了file:///etc/passwd、smb://...或ftp://...curl 也会直接拒绝发起对应协议的请求从源头阻断一类协议走私protocol smuggling与 SSRF 风险。配套选项--proto-redir与--proto-default--proto只约束初始请求的协议不会自动约束跟随重定向--location时跳转过去的协议。为此 curl 提供了两个紧密相关的选项它们与原文档See-also一节相互引用。--proto-redir限制重定向协议见 docs/cmdline-opts/proto-redir.md。语法与--proto完全相同同样的逗号分隔、修饰符、all关键字但作用于重定向目标 URL。关键行为--proto中明确拒绝的协议不会被--proto-redir重新放行——两条规则取交集--proto的约束优先级更高默认情况下7.65.2 起重定向只允许HTTP、HTTPS、FTP、FTPS显式写出all或all会放开全部协议官方文档明确警告这对安全不利。官方示例# 只允许 http 和 https 作为重定向目标 curl --proto-redir -all,http,https --follow http://example.com # 更推荐的写法用 直接重置 curl --proto-redir http,https --location http://example.com--proto-default为缺失 scheme 的 URL 指定默认协议见 docs/cmdline-opts/proto-default.md。当 URL 没有写协议前缀时curl 默认会根据主机名猜测例如不加协议时通常猜 http而--proto-default protocol可以显式指定curl --proto-default https ftp.example.com # 把 ftp.example.com 当作 https://ftp.example.com注意事项均为文档原述协议名大小写不敏感若指定了未知或不支持的协议会得到CURLE_UNSUPPORTED_PROTOCOL错误该选项不改变默认代理协议代理仍默认走 http默认协议不能设置为ipfs或ipns这两个 scheme 必须显式写在 URL 中。源码级原理从命令行到 libcurl 位掩码--proto的完整链路可以用仓库源码逐层还原这有助于理解其行为边界。第一层参数解析与集合运算curl 工具在启动时调用get_libcurl_info()通过curl_version_info()拿到当前 libcurl 实际支持的协议名数组并记录协议数量src/tool_libinfo.c。随后proto_token()把协议名字符串“归一化”为指向该数组内部字符串的稳定指针从而可以用指针比较代替字符串比较src/tool_libinfo.c。--proto的参数解析入口位于 src/tool_getparam.c调用proto2num()实现在 src/tool_paramhlp.c。proto2num的核心逻辑如下用默认协议集合初始化一个集合数组protoset逐个解析逗号分隔的条目根据首字符识别修饰符对应set动作、-对应deny、或无修饰符对应allow遇到alldeny时清空集合protoset[0] NULLallow/set时把built_in_protos整体拷入集合遇到具体协议名deny从集合移除、set先清空再放入、allow直接放入未知协议会打印unrecognized protocol并返回PARAM_BAD_USE解析完成后按字母序排序保证输出稳定源码注释明确说明这是为满足 CI 测试的稳定输出要求。注意proto2num中set动作的实现protoset[0] NULL之后以FALLTHROUGH落到allow分支再放入协议——这正是“重置集合、后续条目可继续修改”这一文档语义的代码级证据。第二层传递到 libcurl解析得到的协议字符串存入config-proto_strsrc/tool_cfgable.h。在 src/config2setopts.c 中proto_str被映射为CURLOPT_PROTOCOLS_STRproto_redir_str被映射为CURLOPT_REDIR_PROTOCOLS_STR交给 libcurl 处理。第三层libcurl 内部位掩码在 libcurl 的选项处理中lib/setopt.cCURLOPT_PROTOCOLS_STR通过protocol2num()把字符串转成curl_prot_t位掩码存入s-allowed_protocols传入NULL时重置为默认值CURLPROTO_64ALL即全部协议CURLOPT_REDIR_PROTOCOLS_STR同理存入s-redir_protocols默认值为CURLPROTO_REDIR——这与前文“重定向默认只允许 HTTP/HTTPS/FTP/FTPS”的文档描述对应。传输执行时libcurl 会先校验目标 URL 的协议是否在allowed_protocols位掩码内重定向场景则校验redir_protocols不在白名单内即拒绝发起连接从而把限制落到实处。与编程 API 的对应--proto系列在 libcurl 编程接口中也有等价物方便你在自己的程序里实现同样的约束curl 命令行libcurl 选项--protoCURLOPT_PROTOCOLS/CURLOPT_PROTOCOLS_STR--proto-redirCURLOPT_REDIR_PROTOCOLS/CURLOPT_REDIR_PROTOCOLS_STR--proto-defaultCURLOPT_DEFAULT_PROTOCOL字符串版本选项的 setopt 处理均位于 lib/setopt.c。常见用法速查与注意事项# 只允许 http、https最常用适合脚本与 SSRF 防护 curl --proto http,https $URL # 默认集合减去某个协议 curl --proto -ftps $URL # 只允许 http、https 且重定向也受限 curl --proto http,https --proto-redir http,https -L $URL # 缺失 scheme 时按 https 处理 curl --proto-default https host.example.com # 组合使用先清空再逐项添加 curl --proto -all,https,http $URL要点回顾顺序敏感规则从左到右求值之后仍可用/-微调大小写不敏感协议名可写http或HTTP未知协议只警告不失败便于脚本安全地禁用未构建的协议--proto与--proto-redir取交集前者拒绝的协议不会被后者放行默认行为不指定--proto时允许全部已构建协议不指定--proto-redir时重定向仅允许 HTTP/HTTPS/FTP/FTPS7.65.2 起。--proto的完整权威定义位于仓库 docs/cmdline-opts/proto.md配套协议清单见 docs/cmdline-opts/_PROTOCOLS.md参数解析实现见 src/tool_paramhlp.clibcurl 侧位掩码处理见 lib/setopt.c。需要更细粒度控制时可将这三者与--proto-redir、--proto-default组合使用构建一套完整的协议级访问控制策略。【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考