摘要
- SEARCH 207 只证明服务器在特定语法、仲裁资源、范围和身份下返回了这些行;它没有证明每个资源都被检查,也没有证明缺失行不满足条件。
- 截断响应可以包含任意一个合格子集。排序约束的是已返回子集的次序,不能自动把它变成完整集合中的全局最高排名。
自动化最喜欢把沉默当成否定
一个清理流程搜索所有满足条件的文件。已知 URI 没有出现在结果里,流程便把登记项标为不存在。这个动作把搜索接口的沉默转换成了对象世界的否定,而 RFC 5323 明确保留了更多可能。
DAV:where 的布尔运算不是二值,而是 TRUE、FALSE、UNKNOWN。只有 TRUE 会进入结果。若某项属性通过 PROPFIND 会得到非 2xx 状态,就按 NULL 处理。NULL 又不同于空字符串:空字符串是已经定义、长度为零的值,NULL 是当前上下文中没有可用值。
权限会直接进入这个判断。客户端无权读取的属性必须像不存在一样参与查询;无权 GET 的内容也要像读取失败一样评估。相同 XML、相同范围,由两个不同 principal 执行,可以合理地得到不同集合。SEARCH 不能成为绕过 GET 或 PROPFIND 权限的侧信道。
因此缺行可能是 FALSE,也可能是 UNKNOWN、无权读取、范围之外、尚未检查、重定向边界、索引滞后或集合刚刚变化。诚实的数据模型不能只留一个“未找到”。
207 成功里可能嵌着不完整性
服务器可以为了限制查询计算或传输开销而截断。此时仍使用 207 Multi-Status,同时为搜索仲裁 URI 给出 507 Insufficient Storage,并应当附带部分结果。这里的 507 不是整个 HTTP 请求失败,而是完整性收据。
规范允许部分结果是完整合格集合中的任意子集,甚至还有大量匹配资源根本没有被检查。如果请求带排序,返回的那部分必须按要求排序。这个规则只能说明可见行的相互次序,不能说明它们是整个集合的真正前若干名。
最危险的转换发生在中间层:XML 适配器保留资源行,却把 507 行丢掉;数据仓库随后看到整齐的 href 列表,就把它当作完整清单。没有任何字段造假,但关键语义已经消失。
客户端还可以发送 DAV:limit,请求限制响应数量或服务器工作量。服务器可以忽略这个限制。若同时要求排序,服务器应返回排序最高的结果,但“应”也不是现场证明。客户端请求的上限、服务器实际执行预算和 507 截断必须分别保存。
接收请求的资源不是被搜索的集合
SEARCH 方法负责运送查询与结果,语义由查询语法定义。Request-URI 指向 search arbiter,即接收和执行请求的资源。RFC 5323 不要求它与搜索范围相同。
DAV:basicsearch 用 DAV:from 指定一个或多个 scope。每个范围包含 href 和 depth。深度 0 只覆盖集合自身,1 加入直接子项,infinity 扩展到所有后代。相对引用以 Request-URI 为基准解析,绝对引用则可指向其他位置,但受服务器支持和策略约束。
多范围支持是可选能力。不支持的服务器必须拒绝,而不能悄悄只执行第一个。重定向引用也不会自动穿越,除非相应行为被请求并受到支持。所以语法里出现 infinity,不等于每条逻辑分支都已访问。
若审计记录只保存 where 条件,没有保存仲裁资源和解析后的范围,它无法重放原问题。若把 Request-URI 误写成 scope,重放时甚至会查询另一批对象。
发现能力不等于证明索引
DASL 响应头和 DAV:supported-query-grammar-set 用来声明支持的查询语法。声明一种语法,只表明服务器认识这种表达方式,不足以构造每个有效查询,也没有证明某次查询已执行。
Query Schema Discovery 可以列出哪些属性可搜索、可选择、可排序,以及支持哪些可选运算符。但 QSD 自身可选,并且结果随 arbiter 和 scope 改变。principal 身份也可能影响可用 schema,而协议不会暴露全部影响因素。
属性被标为 searchable,只意味着服务器愿意检查,不意味着每个资源都定义该属性。语法 URI 也是标识符;应用不应仅因它长得像 HTTP URL 就主动抓取。符号能力、运行行为和结果完整性需要三张不同收据。
相关性 score 同样不具备跨上下文权威。只有同一底层搜索系统对同一集合执行时,两次结果的数值才通常有比较意义。脱离引擎、语料和索引时期,分数只是外形相同的数字。
一行 URI 不必等于一个对象
范围内可能有多个 URI 映射到同一资源,服务器应只报告一个。DAV:resource-id 活属性可帮助识别潜在重复,但它没有保证本次 href 是永久唯一名称。
所以按行数计算对象数可能错,按缺失别名计算丢失对象也可能错。证据应保留 href、resource-id、属性级状态、返回时刻和 arbiter。去重是后续推理,不是 SEARCH 自动完成的事实。
成功结果也不应缓存。集合成员、属性、权限和索引都可能在下一次查询前变化。响应是带时间的观察,不是冻结快照。
可审计搜索需要完整上下文
保存原始 XML、语法标识、Request-URI、解析后的范围 URI、深度、重定向与版本选项、认证 principal、授权上下文、选择属性、条件树、排序和 limit。响应侧保存 HTTP 状态、所有 Multi-Status 行、propstat、href、resource-id、score、507 截断行,以及可得的服务器时间或索引 epoch。
没有额外枚举机制时,不要把结果标为“全部资源”。在 UNKNOWN、权限、范围或截断未排除时,不要把缺行标为 FALSE。不要跨引擎或集合比较 score,也不要把 grammar discovery 当作执行凭证。
监控应关注反复撞到同一行数上限、507 被网关删除、同 principal 和 scope 的 schema 变化、SEARCH 与获授权 PROPFIND 枚举之间的差距、同 resource-id 的多个 href,以及外部 XML 实体。搜索也是计算和解析攻击面,需要预算、超时和不可信输入策略。
RFC 5323 的规则并没有削弱搜索,而是阻止搜索结果冒充比自己更强的东西。返回行是局部肯定证据;缺失行仍然需要解释。
来源
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
