保护REST API/Web服务的最佳实践

在设计REST API或服务时,是否有任何既定的最佳实践来处理安全性(身份验证、授权、身份管理)?

在构建SOAP API时,您将WS-Security作为指南,并且有很多关于该主题的文献。我发现有关保护REST端点的信息较少。

虽然我知道REST故意没有类似于WS-*的规范,但我希望出现最佳实践或推荐模式。

任何讨论或相关文件的链接将不胜感激。如果有关系,我们将使用带有POX/JSON序列化消息的WCF来处理使用. NET Framework v3.5构建的REST API/Services。

314853 次浏览

除了HTTP之外,没有其他REST标准。那里有既定的REST服务。我建议您查看它们并了解它们的工作原理。

例如,我们在开发自己的S3 REST服务时借鉴了很多想法。但我们选择不使用基于请求签名的更高级的安全模型。更简单的方法是基于SSL的HTTP Basic身份验证。你必须决定什么在你的情况下最有效。

此外,我强烈推荐O'reilly的第0本书。它解释了核心概念并提供了一些最佳实践。您通常可以采用他们提供的模型并将其映射到您自己的应用程序。

正如tweft所说,Amazon S3是一个很好的工作模型。他们的请求签名确实有一些功能(例如合并时间戳),有助于防止意外和恶意请求重播。

HTTP Basic的好处是几乎所有的HTTP库都支持它。当然,在这种情况下,您需要SSL,因为通过网络发送明文密码几乎普遍是一件坏事。使用SSL时,Basic比Digest更可取,因为即使调用者已经知道需要凭据,Digest也需要额外的往返来交换随机数值。使用Basic,调用者只需第一次发送凭据即可。

一旦建立了客户端的身份,授权实际上只是一个实现问题。但是,你可以将授权委托给使用现有授权模型的其他组件。Basic的好处再次是,你的服务器最终会得到客户端密码的明文副本,你可以根据需要简单地传递给基础架构中的另一个组件。

感谢您的宝贵建议。我们最终使用自定义HTTP标头将身份令牌从客户端传递到服务,以准备将我们的RESTful API与即将推出的Microsoft Zermatt身份框架集成。我已经描述了问题这里和我们的解决方案这里。我还接受了调整的建议,并购买了RESTful Web服务-如果你正在构建任何类型的RESTful API,这是一本非常好的书。

您可能还想看看OAuth,这是一个新兴的基于令牌的授权开放协议,专门针对超文本传输协议api。

它与flickr记得牛奶“rest”apis所采用的方法非常相似(不一定是restful apis的好例子,而是基于令牌的方法的好例子)。

我见过的关于安全性的最好的帖子之一,因为它与REST有关,已经在1雨滴结束了。MySpace API也使用OAuth来保证安全性,你可以在RESTChess代码中完全访问他们的自定义通道,我做了很多探索。这是在Mix上演示的,你可以找到帖子这里

我使用过几次OAuth,也使用过其他一些方法(BASIC/DIGEST)。我全心全意地建议使用OAuth。以下链接是我见过的使用OAuth的最佳教程:

http://hueniverse.com/oauth/guide/

我有点惊讶还没有提到带有客户端证书的SSL。诚然,这种方法只有在你可以依靠证书识别的用户社区时才真正有用。但是许多政府/公司确实将它们颁发给他们的用户。用户不必担心创建另一个用户名/密码组合,并且身份是在每个连接上建立的,因此与服务器的通信可以完全无状态,不需要用户会话。(并不是暗示提到的任何/所有其他解决方案都需要会话)

我搜索了很多关于restful ws安全的信息,我们还最终使用令牌通过cookie从客户端到服务器来验证请求。我使用Spring Security来授权服务中的请求,因为我必须根据数据库中已经存在的指定安全策略来验证和授权每个请求。

REST本身没有提供安全标准,但是像OAuth和SAML这样的东西正在迅速成为这个领域的标准。然而,身份验证和授权只是你需要考虑的一小部分。许多与Web应用程序相关的已知漏洞非常适用于REST API。你必须考虑输入验证、会话破解、不适当的错误消息、内部员工漏洞等。这是一个很大的主题。

我会推荐OAuth 2/3。您可以在http://oauth.net/2/找到更多信息

这些答案中的每个人都忽略了真正的权限改造/授权。

例如,如果您的REST API/Web服务是关于POSTing/GETing医疗记录的,您可能需要定义权限改造政策,说明谁可以访问数据以及在什么情况下访问数据。例如:

  • 医生可以获得与他们有护理关系的病人的医疗记录
  • 没有人可以在练习时间之外发布医疗数据(例如9到5)
  • 最终用户可以获取他们拥有的医疗记录或他们作为监护人的患者的医疗记录
  • 护士可以更新与护士属于同一单位的患者的病历。

为了定义和实现这些细粒度的授权,您需要使用一种名为XACML的基于属性的权限改造语言,即可扩展访问控制标记语言。

这里的其他标准是针对以下方面的:

  • OAuth:id。联合和授权授权,例如让一个服务代表我在另一个服务上行事(Facebook可以发布到我的Twitter)
  • SAML:身份联合/Web SSO。SAML非常关注用户是谁。
  • WS-Security/WS-*标准:这些标准关注SOAP服务之间的通信。它们特定于应用程序级消息传递格式(SOAP),并处理消息传递的各个方面,例如可靠性、安全性、机密性、完整性、原子性、事件……没有涵盖权限改造,所有这些都是特定于SOAP的。

XACML与技术无关。它可以应用于java应用程序、. NET、Python、Ruby… Web服务、REST API等。

以下是一些有趣的资源:

SOAP世界被安全标准很好地覆盖这一事实并不意味着它在默认情况下是安全的。首先,标准是非常复杂的。复杂性不是安全的好朋友,像XML签名包装攻击这样的实现漏洞在这里很普遍。

至于. NET环境,我不会有太大帮助,但“使用Java构建Web服务”(一个有大约10个作者的砖)确实帮助我很多理解WS-*安全架构,特别是它的怪癖。

OWASP(开放Web应用程序安全项目)有一些涵盖Web应用程序开发各个方面的备忘单。这个项目是一个非常有价值和可靠的信息来源。关于REST服务,您可以检查:https://www.owasp.org/index.php/REST_Security_Cheat_Sheet

我想补充一点(与stinkeymatt一致),最简单的解决方案是将SSL证书添加到您的网站。换句话说,确保您的网址是HTTPS://。这将涵盖您的传输安全性(物有所值)。使用RESTful URL,想法是保持简单(与WS*Security/SAML不同),您可以使用oAuth2/openID连接甚至基本身份验证(在简单情况下)。但您仍然需要SSL/HTTPS。请在此处检查ASP.NETWeb API 2安全性:http://www.asp.net/web-api/overview/security(文章和视频)

正如@Nathan最终得到的那样,这是一个简单的HTTP头,有些人说OAuth2和客户端SSL证书。它的要点是…您的REST API不应该处理安全性,因为这真的应该超出API的范围。

相反,应该在其上放置一个安全层,无论是Web代理后面的HTTP标头(一种常见的方法,如SiteMinder、Zermatt甚至Apache HTTPd),还是像OAuth 2一样复杂。

关键是请求应该在没有任何最终用户交互的情况下工作。所需要的只是确保与REST API的连接经过身份验证。在JavaEE中,我们有userPrincipal的概念,可以在HttpServletRequest上获得。它还在部署描述符中进行管理,URL模式可以是安全的,因此REST API代码不再需要检查。

在WCF世界中,我将使用ServiceSecurityContext.Current来获取当前的安全上下文。您需要将应用程序配置为需要身份验证。

我上面的陈述有一个例外,那就是使用随机数来防止重播(可能是攻击或某人只是提交两次相同的数据)。这部分只能在应用层处理。

对于Web应用程序安全性,您应该看看OWASP(https://www.owasp.org/index.php/Main_Page),它为各种安全攻击提供了备忘单。您可以结合尽可能多的措施来保护您的应用程序。关于API安全(授权、认证、身份管理),前面已经提到了多种方法(Basic、Digest和OAuth)。OAuth1.0中存在循环漏洞,因此您可以使用OAuth1.0a(OAuth2.0由于规范问题没有被广泛采用)

已经有一段时间了,但这个问题仍然相关,尽管答案可能已经改变了一点。

API网关将是一个灵活且高度可配置的解决方案。我测试和使用了香港相当多,真的很喜欢我所看到的。香港提供了一个自己的管理REST API,您可以使用它来管理用户。

Express-gateway.io是最近的,也是一个API网关。

github上找到了一个很棒的清单:

身份验证

  • 不要在身份验证、令牌生成、密码存储中重新发明轮子。使用标准。

  • 在登录中使用Max Retry和监狱功能。

  • 对所有敏感数据使用加密。

JWT(JSON Web Token)

  • 使用随机复杂密钥(JWT秘密)使暴力强制令牌非常困难。

  • 不要从有效负载中提取算法。在后端强制执行算法(HS256或RS256)。

  • 使令牌过期(TTLRTTL)尽可能短。

  • 不要将敏感数据存储在JWT有效载荷中,它可以很容易地解码。

OAuth

  • 始终验证redirect_uri服务器端以仅允许白名单URL。

  • 始终尝试交换代码而不是令牌(不允许response_type=token)。

  • 使用带随机散列的状态参数来防止OAuth身份验证过程中的CSRF

  • 定义默认范围,并验证每个应用程序的范围参数。

访问

  • 限制请求(节流)以避免DDoS/暴力攻击。

  • 在服务器端使用HTTPS来避免MITM(中间人攻击)

  • 使用HSTS标头和SSL以避免SSL条攻击。

输入

  • 根据以下操作使用正确的HTTP方法:GET(读取)、POST(创建)、PUT/PATCH(替换/更新)和DELETE(删除记录),如果请求的方法不适合请求的资源,则使用405 Method Not Allowed响应。

  • 在请求Accept标头(内容协商)上验证Content-type以仅允许您支持的格式(例如application/xmlapplication/json等),如果不匹配,则以406 Not Acceptable响应响应。

  • 在您接受时验证已发布数据的content-type(例如application/x-www-form-urlencodedmultipart/form-dataapplication/json等)。

  • 验证用户输入以避免常见漏洞(例如XSS、SQL注入、远程代码执行等)。

  • 不要在URL中使用任何敏感数据(凭据、密码、安全令牌或API密钥),而是使用标准的Authorization标头。

  • 使用API网关服务启用缓存、Rate Limit策略(例如配额、尖峰停止、并发速率限制)并动态部署API资源。

处理

  • 检查是否所有端点都受到身份验证的保护,以避免身份验证过程中断。

  • 应避免用户自己的资源ID。使用 /me/orders而不是 /user/654321/orders.

  • 不要自动增加ID。使用UUID。

  • 如果要解析XML文件,请确保未启用实体解析以避免XXE(XML外部实体攻击)。

  • 如果您正在解析XML文件,请确保未启用实体扩展,以避免通过指数实体扩展攻击产生Billion Laughs/XML炸弹。

  • 使用CDN进行文件上传。

  • 如果您正在处理大量数据,请使用工作进程和队列在后台尽可能多地处理并快速返回响应以避免HTTP阻塞。

  • 不要忘记关闭DEBUG模式。

产出

  • 发送X-Content-Type-Options: nosniff标题。

  • 发送X-Frame-Options: deny标题。

  • 发送Content-Security-Policy: default-src 'none'标题。

  • 删除指纹标头-X-Powered-ByServerX-AspNet-Version等。

  • 强制content-type为您的响应,如果您返回application/json,则您的响应内容类型为application/json

  • 不要返回敏感数据,如凭据,密码,安全令牌。

  • 根据完成的操作返回正确的状态码。(例如200 OK400 Bad Request401 Unauthorized405 Method Not Allowed等)。