fix: validate HTTP dates IPv6 URLs and parser errors
CSS quality / css-quality (push) Has been cancelled
CSS quality / css-quality (push) Has been cancelled
This commit is contained in:
@@ -398,6 +398,8 @@ headers["Idempotency-Key"] = "sms-order-20260914-0001"
|
||||
|
||||
查询代码没有额外强制“只查最近 N 天”,但历史查询能否返回数据取决于实际留存、当前应用归属和筛选条件。startTime 必须不晚于 endTime,当前时间边界两端均包含。跨窗口同步可按上行 id 去重,避免公共边界重复计入。
|
||||
|
||||
时间接受 `YYYY-MM-DD`(按UTC零点)或带 `Z` / `±HH:mm` 时区的ISO 8601时间;秒可省略,小数秒最多三位。日期必须在日历上真实存在,不接受2月30日、24:00、无时区日期时间或本地化日期格式;空字符串也不是省略参数。游标中的时间执行同样校验。
|
||||
|
||||
### 7.1 列表与筛选
|
||||
|
||||
第一页、空数据及下一页的完整报文见第 11.4~11.5 节。
|
||||
@@ -609,6 +611,8 @@ def verify_callback(headers, raw_body, webhook_secret, now=None,
|
||||
| 400 | `MOBILE_INVALID` / `CONTENT_REQUIRED` | 检查单个手机号和正文 |
|
||||
| 400 | `IDEMPOTENCY_KEY_INVALID` | 补齐有效幂等键,检查长度与字符 |
|
||||
| 400 | `TIME_RANGE_INVALID` / `TIME_RANGE_TOO_LARGE` | 检查时间格式、先后顺序和跨度 |
|
||||
| 413 | `PAYLOAD_TOO_LARGE` | JSON请求体超过2 MiB限制,减少内容后再提交 |
|
||||
| 415 | `UNSUPPORTED_MEDIA_TYPE` | 检查请求体编码及字符集,使用UTF-8 JSON |
|
||||
| 400 | `CURSOR_INVALID` | 使用平台返回的 cursor,保持筛选条件一致 |
|
||||
| 401 | `AUTH_HEADERS_MISSING` | 补齐四个鉴权头 |
|
||||
| 401 | `CREDENTIAL_INVALID` | 核对应用、Access Key、有效期和吊销状态 |
|
||||
|
||||
@@ -2283,3 +2283,8 @@
|
||||
### 2026-09-14 HTTP回调传输兼容验收补充
|
||||
|
||||
Webhook需在当前受支持Node运行时通过真实HTTPS投递;SSRF校验后的固定DNS地址必须同时符合lookup单地址和all-address回调契约,不得通过重新解析或取消私网限制解决投递问题。完整模拟链路验收及限制见 [HTTP全量验收](http-api-full-acceptance-20260914.md)。
|
||||
|
||||
|
||||
### HTTP公共参数错误边界补充(2026-09-14)
|
||||
|
||||
上行日期须为有效ISO8601日历日期/带时区时间,query与cursor一致;IPv6和IPv4-mapped地址继续执行私网限制;畸形/超限/不支持编码的公开HTTP请求体返回稳定400/413/415及关联ID,不回显输入。详见HTTP整改方案最新修复节。
|
||||
|
||||
@@ -291,3 +291,10 @@ R03不能仅通过“增加重试”关闭。后续详细设计至少说明:
|
||||
## 2026-09-14 真实HTTP全量验收发现的Webhook DNS缺陷
|
||||
|
||||
测试环境 f0e8434 上,专用模拟应用已产生真实送达回执,但5个Webhook事件均在2次尝试后失败,lastError为 `Invalid IP address: undefined`,受控HTTPS接收端无请求。Node自动地址族选择以 `all=true` 调用自定义lookup,旧实现仍返回单地址三参数,违反回调契约。保留原SSRF解析、私网拒绝及地址固定,只按all选项返回固定地址数组或原单地址。未改变重试、计费、发送与租户规则。真实Node HTTPS连接旧实现失败/修正实现200,本地真实HTTP连接回归及API全量73套783项、类型构建通过;线上修复与Webhook全场景验收尚待标准发布完成。用户已另行授权本修复提交、推送及测试发布,不涉及预生产。完整结果将登记 [HTTP全量验收](http-api-full-acceptance-20260914.md)。
|
||||
|
||||
|
||||
## 2026-09-14 HTTP全量验收后续修复与授权
|
||||
|
||||
用户已授权本轮全部已发现Bug的修复、复测、提交/推送、测试部署,以及仅测试机专用回调域名的临时hosts映射;映射有30分钟独立精确移除timer,验收结束主动移除。无默认网关/DNS服务/OpenWrt或预生产变更。12个既有本轮回调已真实HTTPS送达;200/204成功、400/302终止、429/503/超时重试、持续503上限及人工重试保护均通过,HMAC、eventId与60秒退避一致。
|
||||
|
||||
HTTP-FULL-B02:去除URL IPv6方括号后区分IP字面量与DNS,DNS失败转稳定400;同时规范化IPv4-mapped IPv6后复用私网校验,避免修复引入私网绕过。B03:先校验ISO8601年月日/闰年/时分秒/时区,拒绝Date自动归一化;覆盖query与cursor,不改变查询跨度和归属。B04:只对/api/openapi/v1/sms的body-parser已知错误输出统一problem+json和X-Request-Id,400/413/415正文固定,不泄露原始输入;非公开路径和未知错误继续原处理链。无迁移、短信链路、计费或权限规则变更。线上边界复测及最终收尾待新候选发布。
|
||||
|
||||
@@ -1,11 +1,50 @@
|
||||
# HTTP接口全量真实模拟验收(2026-09-14)
|
||||
|
||||
状态:执行中,不表示全部通过。环境test,初始应用版本f0e843436c715010d3eaec72a5e0c81816a6e5bd;本轮专用标签bdd774bf。
|
||||
更新:2026-09-14T06:36:14.050Z。状态:**Webhook真实成功及异常重试已通过;三个参数边界修复正在回归和发布,最终收尾未完成。**
|
||||
|
||||
已覆盖正常短信三网、长短信、UTF8转义、鉴权/参数错误、上行分页筛选与字段投影、同租户跨应用/跨租户隔离、同键并发只产生一次Submit。测试证据位于 `%TEMP%/cmpp-http-full-20260914/`,不含鉴权秘密。
|
||||
## 环境与交付
|
||||
|
||||
真实缺陷:Webhook在Node自动地址族选择时因lookup回调格式错误,未到HTTP接收端就报Invalid IP address: undefined。最小修复保持SSRF地址校验不变;API 73套783项及构建通过,已授权提交/推送/测试发布,发布及回调复验未完成。
|
||||
测试环境100.93.204.60:12026;初始版本f0e843436c715010d3eaec72a5e0c81816a6e5bd,当前部署及实际Git远端为92b112cc6e29a14d842e040a9d469fd717a95f96。仅测试环境,无预生产操作。现有metrics、发布工具、其他文档草稿保留,提交只含本轮代码/工具及文档精确追加。
|
||||
|
||||
共享模拟接入号造成3条上行ambiguous,公开接口正确隐藏;独立接入号后的3条上行已正确匹配。首条正常请求因缺少批准模板返回422,配置测试模板后新请求送达;首个过期凭据受本机/服务器约4秒时差影响,超过服务器期限重测401。保留原结果,不计为服务端缺陷。
|
||||
## 已执行
|
||||
|
||||
待完成:标准发布、Webhook成功和失败重试/超时、最终PG/Redis/计费对账、测试设施收尾;错误JSON的统一问题响应和未知字段处理须按契约单列评估。未触碰预生产、真实通道、原客户配置、余额或历史短信重投。
|
||||
共记录140项HTTP请求/业务断言,含失败原记录和测试前置问题,不将140当全部通过数。覆盖鉴权、nonce、过期/撤销、IP、开关、QPS、正文及查询边界、并发幂等、重复客户编号、三网、长短信、UTF8转义、上行筛选/分页/投影、歧义隔离、同企业跨应用/跨企业隔离和Webhook URL校验。
|
||||
|
||||
- 9条真实业务短信:8送达、1失败;成功10计费单位,净扣3250内部金额单位,余额1848101→1844851。失败短信在2条LGST模拟通道尝试后退款;冻结/解冻及最终扣退账相符。12个实际CMPP Submit报文(含长短信分段和失败短信的备用模拟路由),未连接真实运营商。
|
||||
- 6条真实CMPP上行:共享接入号3条ambiguous正确隐藏;独立接入号3条matched,可分页/查询/筛选,详情无通道/供应商/内部匹配字段,真实下游ACK后delivered。
|
||||
- 9条HTTP发送待办dispatched、10条Gateway待办published;未直接修改Redis、余额或历史短信。
|
||||
- 本地工作区API73套783项/构建通过;精确发布候选73套782项、类型、格式、lint通过。数量差来自其他会话受保护的metrics测试,不夹带。无前端/Gateway修改,未重复无关门禁。
|
||||
|
||||
## 真实问题
|
||||
|
||||
| 编号 | 结果 | 状态 |
|
||||
|---|---|---|
|
||||
| HTTP-FULL-B01 | Node all=true lookup旧回调格式导致Invalid IP address: undefined,初始11个Webhook在2次后失败且收件端无请求 | 最小修复已提交/推送/标准部署;保留SSRF检查,真实本机连接回归通过;公网业务成功仍受下述DNS路径阻塞 |
|
||||
| HTTP-FULL-B02 | https://[::1]/hook配置返回500,旧配置未改变;URL.hostname含方括号进入DNS lookup | 待修,未绕过私网保护 |
|
||||
| HTTP-FULL-B03 | 2026-02-30被Date自动换算,查询返回200 | 待修:应严格验证日历日期 |
|
||||
| HTTP-FULL-B04 | 畸形JSON/非对象JSON在全局body-parser阶段返回普通400,无公开problem code/X-Request-Id | 待修:统一入口错误契约 |
|
||||
|
||||
未知channelId字段的400预期与现有未禁止附加字段的契约不一致,send关闭时实际403且无发送,登记为契约观察而非确认缺陷。首条正常请求422是缺少批准模板的测试前置问题;首个到期凭据200受本机/服务器约4秒时差影响,超过服务器期限后重测401。原结果全部保留。
|
||||
|
||||
## Webhook网络阻塞与待完成
|
||||
|
||||
实际12个本轮回调事件(9回执、3上行)。修复后仅重试本轮11个旧失败事件,首次2秒超时;单事件10秒诊断随后报TLS建连前断开。测试机DNS把临时Cloudflare地址解析为198.18.1.78,备用webhook.site解析为198.18.1.79,两者普通HTTPS均约5秒后TLS断开。本机同域名正常200;测试机只读探针固定到本机解析的104.16.231.132/104.16.230.132且保留原TLS主机校验,分别2232/313ms返回200。不能把网络失败继续归因于已修复lookup格式,也不能宣称回调业务验收通过。
|
||||
|
||||
已提出待确认方案:只在测试机/etc/hosts临时加入104.16.230.132与本轮唯一域名映射,30分钟独立自动移除,测试后精确移除;**目前未授权、未执行**。默认网关、系统DNS及OpenWrt保持不变。备用WebHook.site一小时过期收件端已创建后删除(204),未收到业务事件。服务操作参考[官方Token文档](https://docs.webhook.site/api/tokens.html)。
|
||||
|
||||
待验证:真实收件HMAC/eventId、200/204 ACK、400终止、429/503/超时自动退避/上限、302不跟随、人工重试及完成后的专用测试设施停用。全共享环境的DB/Redis停机及进程崩溃注入未执行;不以隔离测试代替。暂保留本轮应用/凭据和模拟接收进程用于继续验收,未删除任何历史记录。
|
||||
|
||||
## 标准发布与容量
|
||||
|
||||
计划20260914T060412-92b112cc6e29-35305dbd;preflight、prepare、deploy含verify通过,verificationWarnings为空。独立恢复点 `/var/backups/cmpp-platform/20260914T060412-92b112cc6e29-35305dbd-attempt-1789366449273005177`,PG/Redis/配置/应用归档摘要与可读性通过,未做恢复演练。候选准备40.3秒、备份35.0秒、停止2.8秒、启动5.5秒、验证4.1秒;本地候选测试146.085秒(依赖安装另计),业务验收及网络/等待时间不算停机。
|
||||
|
||||
测试机无独立数据盘,当前应用、发布目录、备份均落/dev/sda2。可用22,837,911,552→21,341,405,184字节;发布目录新增994,070,528字节,备份新增496,861,184字节,当前应用新增36,864字节。当前版本92b112c,上一有效f0e8434及本次previous-api-dist/previous-api-node_modules/previous-source在本次/前次发布目录保留;逐目录清单见capacity-before/after.json。缓存/日志独立盘点,未擅自清理历史资产,容量治理未完成。
|
||||
|
||||
## 证据
|
||||
|
||||
本机 `%TEMP%/cmpp-http-full-20260914/`:results.json、cases.md、baseline.json、pre-fix-reconcile.json、negative-reconcile.json、mo-audit.json、remote-https.json、fallback-network.json、public-ip-probe.json、capacity-before/after.json、lookup-tests.log/api-full.log/api-build.log。发布证据 `.local-data/releases/20260914T060412-92b112cc6e29-35305dbd/`。不保存凭据、Cookie、回调密钥;对话工具中的受控密码提示不写入Git。
|
||||
|
||||
|
||||
## 后续进展(2026-09-14T07:11:33.208Z)
|
||||
|
||||
用户已授权并执行唯一域名hosts临时映射,精确移除兜底timer已启用;上文网络阻塞/未授权描述是原阶段记录,现已解除。12个本轮历史失败回调真实送达,200/204、400/302、429/503/超时、持续503上限,以及人工重试成功/拒绝已成功重试/跨应用404均通过。HMAC、eventId、原始体摘要和至少60秒退避一致。B02/B03/B04最小修复及55项定向回归已通过,等待精确候选全量门禁与测试环境复验。
|
||||
|
||||
@@ -5467,3 +5467,10 @@ TC-CHANNEL-WORD测试部署验收:应用8e4bc5a;新Tab/API200真实空词库
|
||||
- TC-HTTP-FULL-CLOSE:新测试凭据停用、专用应用停止测试、本轮receiver/tunnel/simulator关闭;原配置和历史记录保留,不手工修改余额或清队列。
|
||||
|
||||
执行结果与限制见 [HTTP全量验收](http-api-full-acceptance-20260914.md),用例存在不表示全部通过。
|
||||
|
||||
|
||||
## 2026-09-14 HTTP全量验收后续修复与授权
|
||||
|
||||
用户已授权本轮全部已发现Bug的修复、复测、提交/推送、测试部署,以及仅测试机专用回调域名的临时hosts映射;映射有30分钟独立精确移除timer,验收结束主动移除。无默认网关/DNS服务/OpenWrt或预生产变更。12个既有本轮回调已真实HTTPS送达;200/204成功、400/302终止、429/503/超时重试、持续503上限及人工重试保护均通过,HMAC、eventId与60秒退避一致。
|
||||
|
||||
HTTP-FULL-B02:去除URL IPv6方括号后区分IP字面量与DNS,DNS失败转稳定400;同时规范化IPv4-mapped IPv6后复用私网校验,避免修复引入私网绕过。B03:先校验ISO8601年月日/闰年/时分秒/时区,拒绝Date自动归一化;覆盖query与cursor,不改变查询跨度和归属。B04:只对/api/openapi/v1/sms的body-parser已知错误输出统一problem+json和X-Request-Id,400/413/415正文固定,不泄露原始输入;非公开路径和未知错误继续原处理链。无迁移、短信链路、计费或权限规则变更。线上边界复测及最终收尾待新候选发布。
|
||||
|
||||
@@ -4941,3 +4941,10 @@ git diff --check
|
||||
## 2026-09-14 真实HTTP全量验收发现的Webhook DNS缺陷
|
||||
|
||||
测试环境 f0e8434 上,专用模拟应用已产生真实送达回执,但5个Webhook事件均在2次尝试后失败,lastError为 `Invalid IP address: undefined`,受控HTTPS接收端无请求。Node自动地址族选择以 `all=true` 调用自定义lookup,旧实现仍返回单地址三参数,违反回调契约。保留原SSRF解析、私网拒绝及地址固定,只按all选项返回固定地址数组或原单地址。未改变重试、计费、发送与租户规则。真实Node HTTPS连接旧实现失败/修正实现200,本地真实HTTP连接回归及API全量73套783项、类型构建通过;线上修复与Webhook全场景验收尚待标准发布完成。用户已另行授权本修复提交、推送及测试发布,不涉及预生产。完整结果将登记 [HTTP全量验收](http-api-full-acceptance-20260914.md)。
|
||||
|
||||
|
||||
## 2026-09-14 HTTP全量验收后续修复与授权
|
||||
|
||||
用户已授权本轮全部已发现Bug的修复、复测、提交/推送、测试部署,以及仅测试机专用回调域名的临时hosts映射;映射有30分钟独立精确移除timer,验收结束主动移除。无默认网关/DNS服务/OpenWrt或预生产变更。12个既有本轮回调已真实HTTPS送达;200/204成功、400/302终止、429/503/超时重试、持续503上限及人工重试保护均通过,HMAC、eventId与60秒退避一致。
|
||||
|
||||
HTTP-FULL-B02:去除URL IPv6方括号后区分IP字面量与DNS,DNS失败转稳定400;同时规范化IPv4-mapped IPv6后复用私网校验,避免修复引入私网绕过。B03:先校验ISO8601年月日/闰年/时分秒/时区,拒绝Date自动归一化;覆盖query与cursor,不改变查询跨度和归属。B04:只对/api/openapi/v1/sms的body-parser已知错误输出统一problem+json和X-Request-Id,400/413/415正文固定,不泄露原始输入;非公开路径和未知错误继续原处理链。无迁移、短信链路、计费或权限规则变更。线上边界复测及最终收尾待新候选发布。
|
||||
|
||||
Reference in New Issue
Block a user