API级别还是客户端级别应该进行输出编码?

3
我们正在将Web应用程序架构转换为基于微服务的模式。我们内部进行了一场辩论,讨论是否应该在提供内容的REST API(例如JSON格式)中对内容进行编码以使其安全,还是由使用者(例如HTML或其他方式)负责编码以及显示它。这么做的目的是为了防止XSS攻击等问题。
提供方的观点是:“我们无法知道如何为每个人编码,也无法知道您将如何使用内容,因此使用方应该自行编码。”
使用方的观点是:“只有一个提供方和多个使用方,因此在提供API中进行编码比希望每个使用方都能够编码更加安全。”
在这方面是否有任何通常被接受的最佳实践以及原因?

这个问题与安全无关,更适合在 StackOverflow 上提问。 - John Deters
抱歉我没有详细说明,这是为了防止XSS等安全问题。 - Ernest Mueller
3个回答

4
通常情况下,数据在通过“内部”处理过程(无论我们如何理解它)时,应该以任何“内部”格式存储或编码。通常选择的格式旨在最小化编码/解码步骤并防止数据丢失。
然后,在输出时,数据使用适合的输出格式进行编码。防止数据丢失很重要,但适当的转义和格式化也是关键。
例如,在内部API中,二进制格式的数据可能足够。但是,当您输出JSON、HTML、XML或PDF时,必须适当地对数据进行编码和转义以适应输出格式。
这里的重要点是不同的输出格式具有不同的“安全”概念。对于HTML来说,“安全”的内容可能对于JSON来说并不安全,而对于JSON来说“安全”的内容可能对于SQL来说并不安全。数据是在输出时进行编码的,特别是为了您可以使用正确的编码方式完成任务。不能假设这一步已经事先为您完成,也不应将输出函数置于确定是否必须进行编码的位置。如果您坚持遵循规则:“输出函数始终会为安全性进行编码”,那么您就永远不用担心数据注入攻击。

3
我认为有两点非常重要:
  • 提供程序使用的编码必须在参考文档中以极其清晰和精准的方式指定,以便所有消费方实现者都知道该期望什么。
  • 提供程序使用的任何默认编码都必须保留所有所需信息,即仍然可以由希望这样做的任何消费方进行转码。
如果您遵循这两个规则,则可靠性和安全性的工作将完成95%。
至于您具体的问题,良好的实践是一个折衷方案:提供程序“通用”编码是默认情况下跟随,但消费者可以(可选)请求特定编码,提供程序可以应用--这使得提供程序能够支持多个愚笨的轻量级客户端,可能是不同类型的,并且可以稍后使用额外的编码进行扩展而不会破坏API。

3
我坚信在安全领域,消费者和提供者都需要尽力做好自己的本职工作。
作为提供者,我希望确保我的产品是安全的。我不需要知道客户使用我的产品的上下文,我只需要知道如何交付它。如果我的交付方式是JSON,那么我可以利用这个上下文来转义数据并发送它,对于XML、纯文本等也是同样的方法。此外,已经有一些传输方法能够帮助确保安全性。JSONP就是其中一种交付方式,它确保有效载荷被适当地处理。
作为消费者,在我们的环境中,没有人是最终的消费者,我们都是最终用户通过Web浏览器访问的服务提供者。因此,我们也必须保护这端的数据安全。我永远不会相信黑盒API可以替我完成这项工作,我总是会确保有效载荷的安全。有很多工具可用,例如OWASP的ESAPI项目,可以根据上下文协助进行数据清理。请记住,最终你会将这些数据发送给最终用户(浏览器),如果出现问题,你将无法推卸责任。无论漏洞在哪里,你的服务都将被视为易受攻击的。此外,作为消费者,你可能无法总是依赖黑盒提供者及时修复他们的漏洞。如果他们的支持不足或有更高的优先事项,那么这是否意味着你将继续向最终用户提供已知存在漏洞的服务?
安全是分层的,在源头和端点处都有保护措施总是更好的选择。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接