Skip to main content

17. Security Considerations (安全考虑)

本节旨在告知开发人员、信息提供者和用户与HTTP语义及其用于在互联网上传输信息相关的已知安全问题. 与缓存相关的考虑在[CACHING]的第7节中讨论,与HTTP/1.1消息语法和解析相关的考虑在[HTTP/1.1]的第11节中讨论.

下面的考虑列表并非详尽无遗. 与HTTP语义相关的大多数安全问题是关于保护服务器端应用程序(HTTP接口后面的代码)、保护用户代理通过HTTP接收的内容的处理或一般的互联网安全使用,而不是协议本身的安全性. URI的安全考虑是HTTP操作的基础,在[URI]的第7节中讨论. 各种组织维护主题信息和当前Web应用程序安全研究的链接(例如,[OWASP]).

17.1. Establishing Authority (建立权威)

HTTP依赖于"权威响应"的概念: 由目标URI中标识的源服务器确定(或在其指导下)的响应,考虑到响应消息生成时目标资源的状态,是对该请求最合适的响应.

当在权威组件中使用注册名称时,"http" URI方案(第4.2.1节)依赖于用户的本地名称解析服务来确定在哪里可以找到权威响应. 这意味着对用户的网络主机表、缓存名称或名称解析库的任何攻击都成为攻击"http" URI建立权威的途径. 同样,用户对域名服务(DNS)服务器的选择以及从中获得解析结果的服务器层次结构可能会影响地址映射的真实性; DNS安全扩展(DNSSEC,[RFC4033])是提高真实性的一种方法,通过更安全的传输协议发出DNS请求的各种机制也是如此.

此外,在获得IP地址后,为"http" URI建立权威容易受到互联网协议路由攻击.

"https"方案(第4.2.2节)旨在防止(或至少揭示)许多这些建立权威的潜在攻击,前提是协商的连接是安全的,并且客户端正确验证通信服务器的身份与目标URI的权威组件匹配(第4.3.4节). 正确实现此类验证可能很困难(参见[Georgiev]).

给定源服务器的权威可以通过协议扩展委托; 例如,[ALTSVC]. 同样,可以使用像[RFC8336]这样的协议扩展来更改被认为是权威的连接的服务器集.

从非权威来源(例如共享代理缓存)提供响应通常对于提高性能和可用性很有用,但仅限于可以信任该来源或可以安全使用不信任的响应的情况下.

不幸的是,向用户传达权威可能很困难. 例如,"网络钓鱼(phishing)"是对用户权威感知的攻击,通过在超文本中呈现类似的品牌可能会误导该感知,可能通过userinfo混淆权威组件(参见第4.2.1节)来辅助. 用户代理可以通过使用户能够在执行操作之前轻松检查目标URI、在存在时突出区分(或拒绝)userinfo以及在引用文档来自未知或不受信任的来源时不发送存储的凭据和cookie来减少网络钓鱼攻击的影响.

17.2. Risks of Intermediaries (中间件的风险)

HTTP中间件本质上处于路径攻击的位置. 运行中间件的系统的妥协可能导致严重的安全和隐私问题. 中间件可能访问与安全相关的信息、关于个人用户和组织的个人信息以及属于用户和内容提供者的专有信息. 受损的中间件,或者在实现或配置时不考虑安全和隐私的中间件,可能被用于进行广泛的潜在攻击.

包含共享缓存的中间件特别容易受到缓存投毒攻击,如[CACHING]的第7节所述.

实现者需要考虑其设计和编码决策以及他们向操作员提供的配置选项(特别是默认配置)的隐私和安全影响.

中间件的可信度不会超过运行它们的人员和策略; HTTP无法解决这个问题.

17.3. Attacks Based on File and Path Names (基于文件和路径名的攻击)

源服务器经常使用其本地文件系统来管理从目标URI到资源表示的映射. 大多数文件系统不是为了防止恶意文件或路径名而设计的. 因此,源服务器在将目标资源映射到文件、文件夹或目录时需要避免访问对系统有特殊意义的名称.

例如,UNIX、Microsoft Windows和其他操作系统使用".."作为路径组件来指示当前目录之上的目录级别,并且它们使用特别命名的路径或文件名将数据发送到系统设备. 其他类型的存储系统中可能存在类似的命名约定. 同样,本地存储系统在处理无效或意外字符、分解字符的重组以及不区分大小写名称的大小写规范化时,往往更偏好用户友好性而不是安全性.

基于此类特殊名称的攻击往往侧重于拒绝服务(例如,告诉服务器从COM端口读取)或泄露不打算提供服务的配置和源文件.

17.4. Attacks Based on Command, Code, or Query Injection (基于命令、代码或查询注入的攻击)

源服务器经常使用URI中的参数作为识别系统服务、选择数据库条目或选择数据源的手段. 然而,请求中接收的数据不能被信任. 攻击者可以构造任何请求数据元素(方法、目标URI、头部字段或内容)以包含数据,这些数据在通过命令调用、语言解释器或数据库接口传递时可能被误解为命令、代码或查询.

例如,SQL注入是一种常见的攻击,其中在目标URI或头部字段(例如,Host、Referer等)的某些部分中插入额外的查询语言. 如果接收的数据直接在SELECT语句中使用,查询语言可能被解释为数据库命令而不是简单的字符串值. 这种类型的实现漏洞极为常见,尽管很容易防止.

一般来说,资源实现应该避免在作为指令处理或解释的上下文中使用请求数据. 应该将参数与固定字符串进行比较并根据该比较的结果采取行动,而不是通过未准备好处理不受信任数据的接口传递. 不基于固定参数的接收数据应该仔细过滤或编码以避免被误解.

当请求数据被存储并稍后处理时,例如在日志文件、监控工具中,或者当包含在允许嵌入脚本的数据格式中时,类似的考虑也适用.

17.5. Attacks via Protocol Element Length (通过协议元素长度的攻击)

因为HTTP主要使用文本的、字符分隔的字段,解析器通常容易受到基于发送非常长(或非常慢)的数据流的攻击,特别是当实现期望没有预定义长度的协议元素时(第2.3节).

为了促进互操作性,对字段的最小大小限制提出了具体建议(第5.4节). 这些是最小建议,选择它们是为了即使是资源有限的实现也能支持; 预计大多数实现将选择大得多的限制.

服务器可以拒绝具有过长的目标URI(第15.5.15节)或过大的请求内容(第15.5.14节)的消息. HTTP的扩展[RFC6585]定义了与容量限制相关的额外状态码.

接收者应该仔细限制它们处理其他协议元素的程度,包括(但不限于)请求方法、响应状态短语、字段名称、数值和块长度. 未能限制此类处理可能导致由于缓冲区或算术溢出而导致任意代码执行,并增加对拒绝服务攻击的脆弱性.

17.6. Attacks Using Shared-Dictionary Compression (使用共享字典压缩的攻击)

对加密协议的某些攻击使用动态压缩创建的大小差异来泄露机密信息; 例如,[BREACH]. 这些攻击依赖于在攻击者控制的内容和机密信息之间创建冗余,以便使用相同字典对两个内容进行动态压缩算法在攻击者控制的内容与机密内容的部分匹配时将更高效地压缩.

HTTP消息可以通过多种方式压缩,包括使用TLS压缩、内容编码、传输编码以及其他扩展或特定于版本的机制.

这种风险最有效的缓解措施是禁用对敏感数据的压缩,或者严格将敏感数据与攻击者控制的数据分离,以便它们不能共享相同的压缩字典. 通过仔细设计,可以设计出在有限用例中不被认为可利用的压缩方案,例如HPACK([HPACK]).

17.7. Disclosure of Personal Information (个人信息泄露)

客户端通常拥有大量个人信息,包括用户提供的用于与资源交互的信息(例如,用户的姓名、位置、邮件地址、密码、加密密钥等)和关于用户随时间浏览活动的信息(例如,历史记录、书签等). 实现需要防止无意泄露个人信息.

17.8. Privacy of Server Log Information (服务器日志信息的隐私)

服务器处于可以保存关于用户随时间请求的个人数据的位置,这可能识别他们的阅读模式或感兴趣的主题. 特别是,在中间件收集的日志信息通常包含用户代理交互的历史记录,跨越众多站点,可以追溯到个别用户.

HTTP日志信息本质上是机密的; 其处理通常受法律和法规约束. 日志信息需要安全存储并遵循适当的分析指南. 个别条目中个人信息的匿名化有所帮助,但通常不足以防止基于与其他访问特征的相关性重新识别真实的日志跟踪. 因此,即使密钥是假名的,与特定客户端关联的访问跟踪也不安全发布.

为了最小化盗窃或意外发布的风险,日志信息应该在不再需要支持安全、审计或欺诈控制的操作需求后尽快清除可识别个人身份的信息,包括用户标识符、IP地址和用户提供的查询参数.

17.9. Disclosure of Sensitive Information in URIs (URI中敏感信息的泄露)

URI旨在共享,而不是保护,即使它们标识安全资源. URI通常显示在显示器上,在打印页面时添加到模板中,并存储在各种未受保护的书签列表中. 许多服务器、代理和用户代理在可能对第三方可见的位置记录或显示目标URI. 因此,在URI中包含敏感、可识别个人身份或有泄露风险的信息是不明智的.

当应用程序使用客户端机制从用户提供的信息构造目标URI时,例如使用GET的表单的查询字段,可能会提供不适合在URI中披露的潜在敏感数据. 在这种情况下,通常首选POST,因为它通常不构造URI; 相反,表单的POST在请求内容中传输潜在敏感数据. 然而,这妨碍了缓存并对原本是安全请求使用了不安全的方法. 替代解决方案包括在构造URI之前转换用户提供的数据或过滤数据以仅包含不敏感的常见值. 同样,将查询结果重定向到不同的(服务器生成的)URI可以从稍后的链接中删除潜在敏感数据,并为以后重用提供可缓存的响应.

由于Referer头部字段告诉目标站点导致请求的上下文,它有可能泄露关于用户的即时浏览历史和可能在引用资源的URI中找到的任何个人信息的信息. Referer头部字段的限制在第10.1.3节中描述,以解决其一些安全考虑.

17.10. Application Handling of Field Names (应用程序对字段名称的处理)

服务器经常使用非HTTP网关接口和框架来处理接收的请求并生成响应的内容. 由于历史原因,此类接口通常将接收的字段名称作为外部变量名称传递,使用适合环境变量的名称映射.

例如,[RFC3875]的第4.1.18节定义的通用网关接口(CGI)的协议特定元变量映射应用于不对应于CGI标准变量之一的接收头部字段; 该映射包括在每个名称前面添加"HTTP_"并将所有连字符("-")实例更改为下划线("_"). 许多其他应用程序框架继承了这种相同的映射,以简化将应用程序从一个平台移动到另一个平台.

在CGI中,接收的Content-Length字段将作为元变量"CONTENT_LENGTH"传递,其字符串值与接收的字段值匹配. 相反,接收的"Content_Length"头部字段将作为协议特定的元变量"HTTP_CONTENT_LENGTH"传递,如果应用程序错误地读取协议特定的元变量而不是默认的元变量,这可能会导致一些混淆. (这种历史实践是为什么第16.3.2.1节不鼓励创建包含下划线的新字段名称的原因.)

不幸的是,如果映射不完整或模棱两可,将字段名称映射到不同的接口名称可能导致安全漏洞. 例如,如果攻击者发送名为"Transfer_Encoding"的字段,朴素的接口可能将其映射到与"Transfer-Encoding"字段相同的变量名称,导致潜在的请求走私漏洞([HTTP/1.1]的第11.2节).

为了减轻相关风险,建议执行此类映射的实现使映射对于作为名称接收的完整范围的潜在八位字节明确且完整(包括HTTP语法不鼓励或禁止的那些). 例如,具有不寻常名称字符的字段可能导致请求被阻止、特定字段被删除或使用不同前缀传递名称以将其与其他字段区分开来.

17.11. Disclosure of Fragment after Redirects (重定向后片段的泄露)

尽管URI引用中使用的片段标识符不在请求中发送,但实现者应该意识到它们将对用户代理以及由于响应而运行的任何扩展或脚本可见. 特别是,当发生重定向并且原始请求的片段标识符被Location(第10.2.2节)中的新引用继承时,这可能具有将一个站点的片段泄露到另一个站点的效果. 如果第一个站点在片段中使用个人信息,它应该确保对其他站点的重定向包括(可能为空的)片段组件以阻止该继承.

17.12. Disclosure of Product Information (产品信息泄露)

User-Agent(第10.1.5节)、Via(第7.6.3节)和Server(第10.2.4节)头部字段通常泄露关于各自发送者软件系统的信息. 理论上,这可以使攻击者更容易利用已知的安全漏洞; 实际上,攻击者倾向于尝试所有潜在的漏洞,而不管正在使用的明显软件版本.

作为通过网络防火墙的门户的代理应该对可能识别防火墙后面主机的头部信息的传输采取特殊预防措施. Via头部字段允许中间件用假名替换敏感的机器名称.

17.13. Browser Fingerprinting (浏览器指纹识别)

浏览器指纹识别是一组通过其独特特征集随时间识别特定用户代理的技术. 这些特征可能包括与它如何使用底层传输协议、功能能力和脚本环境相关的信息,尽管这里特别感兴趣的是可能通过HTTP传达的独特特征集. 指纹识别被认为是隐私问题,因为它能够随时间跟踪用户代理的行为([Bujlow]),而没有用户可能对其他形式的数据收集(例如,cookie)拥有的相应控制. 许多通用用户代理(即Web浏览器)已采取步骤减少其指纹.

有许多请求头部字段可能向服务器泄露足够独特以启用指纹识别的信息. From头部字段是最明显的,尽管预期From仅在用户希望自我识别时发送. 同样,Cookie头部字段被故意设计为启用重新识别,因此指纹识别问题仅适用于用户代理的配置禁用或限制cookie的情况.

User-Agent头部字段可能包含足够的信息来唯一识别特定设备,通常与其他特征结合时,特别是如果用户代理发送关于用户系统或扩展的过多细节. 然而,用户最不期望的独特信息来源是主动协商(第12.1节),包括Accept、Accept-Charset、Accept-Encoding和Accept-Language头部字段.

除了指纹识别问题外,详细使用Accept-Language头部字段可以泄露用户可能认为是私密性质的信息. 例如,理解给定的语言集可能与特定种族群体的成员身份强相关. 限制此类隐私损失的方法是用户代理除了明确允许的站点外省略发送Accept-Language,也许在检测到指示语言协商可能有用的Vary头部字段后通过交互.

在使用代理来增强隐私的环境中,用户代理在发送主动协商头部字段时应该保守. 提供高度头部字段可配置性的通用用户代理应该告知用户如果提供太多细节可能导致的隐私损失. 作为极端的隐私措施,代理可以在中继请求中过滤主动协商头部字段.

17.14. Validator Retention (验证器保留)

本规范定义的验证器不旨在确保表示的有效性、防范恶意更改或检测路径攻击. 充其量,当所有参与者表现良好时,它们能够实现更高效的缓存更新和乐观的并发写入. 最坏的情况下,条件将失败,客户端将收到的响应不会比没有条件请求的HTTP交换更有害.

实体标签可能以创建隐私风险的方式被滥用. 例如,站点可能故意构造对用户或用户代理唯一的语义无效的实体标签,在具有长新鲜度时间的可缓存响应中发送它,然后在稍后的条件请求中读取该实体标签作为重新识别该用户或用户代理的手段. 这样的识别标签将成为持久标识符,只要用户代理保留原始缓存条目. 缓存表示的用户代理应该确保每当用户执行维护隐私的操作时清除或替换缓存,例如清除存储的cookie或切换到私密浏览模式.

17.15. Denial-of-Service Attacks Using Range (使用范围的拒绝服务攻击)

不受约束的多范围请求容易受到拒绝服务攻击,因为请求相同数据的许多重叠范围所需的努力与尝试以多个部分提供请求的数据所消耗的时间、内存和带宽相比微不足道. 服务器应该忽略、合并或拒绝过分的范围请求,例如对超过两个重叠范围的请求或对单个集合中许多小范围的请求,特别是当范围无明显原因按无序请求时. 多部分范围请求不是为了支持随机访问而设计的.

17.16. Authentication Considerations (认证考虑)

关于HTTP认证主题的一切都是安全考虑,因此下面的考虑列表并非详尽无遗. 此外,它仅限于关于认证框架的安全考虑,一般而言,而不是讨论特定认证方案的所有潜在考虑(这应该在定义这些方案的规范中记录). 各种组织维护主题信息和当前Web应用程序安全研究的链接(例如,[OWASP]),包括实现和使用实践中发现的认证方案的常见陷阱.

17.16.1. Confidentiality of Credentials (凭据的机密性)

HTTP认证框架没有定义维护凭据机密性的单一机制; 相反,每个认证方案定义在传输之前如何编码凭据. 虽然这为开发未来认证方案提供了灵活性,但对于那些本身不提供机密性或不足以防范重放攻击的现有方案的保护是不够的. 此外,如果服务器期望特定于每个个别用户的凭据,这些凭据的交换将具有识别该用户的效果,即使凭据中的内容保持机密.

HTTP依赖于底层传输或会话级连接的安全属性来提供字段的机密传输. 依赖于个人用户认证的服务在交换凭据之前需要安全连接(第4.2.2节).

17.16.2. Credentials and Idle Clients (凭据和空闲客户端)

现有的HTTP客户端和用户代理通常无限期地保留认证信息. HTTP没有为源服务器提供指示客户端丢弃这些缓存凭据的机制,因为协议不知道用户代理如何获取或管理凭据. 用于使凭据过期或撤销的机制可以指定为认证方案定义的一部分.

凭据缓存可能干扰应用程序安全模型的情况包括但不限于:

  • 长时间空闲的客户端,之后服务器可能希望导致客户端重新提示用户输入凭据.

  • 包含会话终止指示(例如页面上的"注销"或"提交"按钮)的应用程序,之后应用程序的服务器端"知道"客户端没有进一步保留凭据的理由.

鼓励缓存凭据的用户代理提供用户控制下的易于访问的机制来丢弃缓存的凭据.

17.16.3. Protection Spaces (保护空间)

仅依赖"realm"机制建立保护空间的认证方案将向源服务器上的所有资源暴露凭据. 已成功对资源进行认证请求的客户端可以对同一源服务器上的其他资源使用相同的认证凭据. 这使得不同的资源可能收集其他资源的认证凭据.

当源服务器在同一源下为多方托管资源时,这尤其令人担忧(第11.5节). 可能的缓解策略包括限制对认证凭据的直接访问(即,不使Authorization请求头部字段的内容可用),以及通过为每一方使用不同的主机名(或端口号)来分离保护空间.

17.16.4. Additional Response Fields (附加响应字段)

向通过未加密连接发送的响应添加信息可能会泄露有关(其他)安全通信的信息. 例如,认证方案的某些扩展使用Authentication-Info或Proxy-Authentication-Info头部字段来提供关于后续请求的信息,例如可用于帮助防范重放攻击的下一个随机数. 如果通过未加密的连接通信,此类信息可能被攻击者观察到,从而降低其有效性.