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

在deviseREST API或服务时,是否存在处理安全性(身份validation,授权,身份pipe理)的最佳实践?

在构buildSOAP API时,您将WS-Security作为指导,有关该主题的文献很多。 我find了有关保护REST端点的更less信息。

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

任何有关文件的讨论或链接将非常感激。 如果重要的话,我们将使用WCF和POX / JSON序列化消息来构build使用.NET Framework v3.5构build的REST API / Services。

正如tweakt所说,Amazon S3是一个很好的合作模式。 他们的请求签名确实有一些function(如合并时间戳),有助于防止意外和恶意请求重放。

HTTP Basic的好处在于几乎所有的HTTP库都支持它。 在这种情况下,您当然需要SSL,因为通过networking发送明文密码几乎是一件坏事。 使用SSL时,基本优于摘要,因为即使调用者已经知道需要凭证,摘要也需要额外的往返来交换随机数值。 使用Basic,呼叫者只需首次发送凭证。

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

除了HTTP之外,没有REST的标准。 在那里build立了REST服务。 我build议你先看看他们,感受他们的工作方式。

例如,我们在开发自己的产品时从亚马逊的S3 REST服务中借鉴了很多想法。 但是我们select不使用基于请求签名的更高级的安全模型。 更简单的方法是基于SSL的HTTP基本身份validation。 你必须决定什么在你的情况下效果最好。

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

您可能还想看看OAuth ,一个新兴的开放协议,专门针对http apis的基于令牌的授权。

这与flickr采取的方法非常相似, 记得牛奶 “rest”apis(不一定是宁静apis的好例子,但是基于令牌的方法的好例子)。

我有点惊讶与客户端证书的SSL尚未提及。 诚然,这种方法只有在可以指望由证书标识的用户社区的时候才是非常有用的。 但是许多政府/公司确实将它们发给用户。 用户不必担心创build另一个用户名/密码组合,并且在每个连接上build立身份,所以与服务器的通信可以是完全无状态的,不需要用户会话。 (并不意味着提及的其他所有解决scheme都需要会话)

这些答案中的每个人都忽略了真正的访问控制/授权。

例如,如果您的REST API / Web服务涉及发布/获取医疗logging,则可能需要定义访问控制策略,以确定谁可以访问数据以及在哪些情况下。 例如:

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

为了定义和实现这些细粒度的授权,您需要使用一种名为XACML(基于属性的访问控制语言)的可扩展访问控制标记语言(eXtensible Access Control Markup Language)。

其他标准如下:

  • OAuth:id。 联邦和授权的授权,例如让服务代表我的另一项服务(Facebook可以发布到我的Twitter)
  • SAML:身份联合/网站SSO。 SAML非常关心用户是谁。
  • WS-Security / WS- *标准:这些标准着重于SOAP服务之间的通信。 它们专用于应用程序级消息传递格式(SOAP),它们处理消息传递的各个方面,例如可靠性,安全性,机密性,完整性,primefaces性,事件等等。没有一个涉及访问控制,都是针对SOAP的。

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

以下是有趣的资源:

  • OASIS XACML 网站
  • NIST ABAC标准

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

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

我曾经遇到过有关安全的最好的post之一,因为它涉及到REST在1 RainDrop结束 。 MySpace API也使用OAuth来提高安全性,您可以在RestChess代码中完全访问他们的自定义渠道,我做了很多探索。 这是在Mix的demo'd,你可以在这里find张贴。

感谢您的优秀build议。 我们最终使用自定义的HTTP头将客户端的身份标记传递给服务,以准备将我们的RESTful API与即将到来的Microsoft Zermatt Identity Framework进行集成。 我在这里描述了这个问题和我们的解决scheme。 我也采取了tweakt的build议,并购买RESTful Web服务 – 一本非常好的书,如果你正在build立一个任何types的RESTful API。

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

我会推荐OAuth 2/3。 你可以在http://oauth.net/2/find更多信息;

我search了很多关于安全性的安全信息,而且我们最终还是通过从客户端到服务器的Cookie使用令牌来validation请求。 我使用spring security来授权服务请求,因为我必须根据已经在数据库中的指定安全策略对每个请求进行authentication和授权。

事实上,SOAP世界很好地覆盖了安全标准,并不意味着默认情况下它是安全的。 首先,标准非常复杂。 复杂性并不是安全性和实施漏洞的很好的朋友,例如XML签名包装攻击在这里是特有的。

至于.NET环境,我没什么帮助,但是“用Java构buildWeb服务” (一个拥有10个作者的砖块)的确帮助我理解了WS- *安全体系结构,尤其是它的怪癖。

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

我想添加(与stinkeymatt一致),最简单的解决scheme是将SSL证书添加到您的网站。 换句话说,请确保您的url是HTTPS://。 这将涵盖您的运输安全(爆炸)。 使用RESTful url的想法是保持简单(不像WS * security / SAML),你可以使用oAuth2 / openID connect甚至是基本身份validation(在简单情况下)。 但是你仍然需要SSL / HTTPS。 请检查ASP.NET Web API 2安全性: http : //www.asp.net/web-api/overview/security (文章和video)

作为@Nathan结束了这是一个简单的HTTP头,有人说OAuth2和客户端SSL证书。 它的要点是…你的REST API不应该处理安全性,因为这实际上超出了API的范围。

相反,安全层应该放在它的顶部,无论它是Web代理(一种常见的方法,如SiteMinder,Zermatt甚至Apache HTTPd)背后的HTTP头,还是像OAuth 2一样复杂。

关键是请求应该没有任何最终用户的交互。 所有需要的是确保与REST API的连接得到authentication。 在Java EE中,我们有一个可以在HttpServletRequest上获得的userPrincipal的概念。 在部署描述符中也可以pipe理URL模式,因此REST API代码不需要再检查。

在WCF世界中,我将使用ServiceSecurityContext.Current来获取当前的安全上下文。 您需要configuration您的应用程序以要求身份validation。

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

对于Web应用程序安全性,您应该查看OWASP( https://www.owasp.org/index.php/Main_Page ),它提供了各种安全攻击的备忘录。 您可以采取尽可能多的措施来保护您的应用程序。 关于API安全(授权,authentication,身份pipe理),已经有多种方式(Basic,Digest和OAuth)。 在OAuth1.0中存在循环漏洞,所以可以使用OAuth1.0a(由于担心规范,OAuth2.0没有被广泛采用)

已经有一段时间了,但问题仍然是相关的,尽pipe答案可能有所改变。

一个API网关将是一个灵活的,高度可configuration的解决scheme。 我testing和使用了很多KONG ,真的很喜欢我所看到的。 KONG提供了自己的pipe理REST API,可以用来pipe理用户。

Express-gateway.io更新,也是一个API网关。

Github上有一个很棒的清单:

authentication

  • 不要使用Basic Auth身份Basic Auth使用标准身份validation(例如JWTOAuth )。

  • 不要在authentication,令牌生成,密码存储中重新发明轮子。 使用标准。

  • 在Login中使用Max Retry和jailfunction。

  • 在所有敏感数据上使用encryption。

JWT(JSON Web令牌)

  • 使用一个随机的复杂的密钥(JWT秘密),使硬币强制令牌很难。

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

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

  • 不要将敏感数据存储在JWT有效载荷中,它可以被轻松解码。

OAuth的

  • 始终validationredirect_uri服务器端是否只允许列入白名单的url。

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

  • 使用状态参数和随机哈希来防止OAuth身份validation过程中的CSRF

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

访问

  • 限制请求(节stream)以避免DDoS /powershell攻击。

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

  • 使用带有SSL的HSTS标头来避免SSL Strip攻击。

input

  • 根据操作使用正确的HTTP方法: GET (读取), POST (创build), PUT/PATCH (replace/更新)和DELETE (删除logging),并且如果请求的方法是不适合请求的资源。

  • 根据请求validation内容typesAccept标头(内容协商),只允许您支持的格式(例如application/xmlapplication/json等),如果不匹配,则回应406 Not Acceptable响应。

  • validation发布数据的content-type (例如application/x-www-form-urlencodedmultipart/form-dataapplication/json等)。

  • validation用户input以避免常见漏洞(例如,XSS,SQL注入,远程代码执行等)。

  • 请勿在URL中使用任何敏感数据(凭据,密码,安全令牌或API密钥),但使用标准Authorization标头。

  • 使用API​​网关服务启用caching, Rate Limit策略(例如配额,秒杀逮捕,并发速率限制)和dynamic部署API资源。

处理

  • 检查所有端点是否在身份validation后受到保护,以避免身份validation过程中断。

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

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

  • 如果您正在parsingXML文件,请确保未启用实体parsing以避免XXE(XML外部实体攻击)。

  • 如果您正在parsingXML文件,请确保实体扩展未启用,以通过指数实体扩展攻击来避免十亿笑/ XML炸弹。

  • 使用CDN进行file upload。

  • 如果您处理的数据量很大,请尽可能在后台使用工作人员和队列进行处理,并快速返回响应以避免HTTP阻止。

  • 不要忘记closuresDEBUG模式。

产量

  • 发送X-Content-Type-Options: nosniff头。

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

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

  • 删除指纹头 – X-Powered-ByServerX-AspNet-Version

  • 为你的响应强制content-type ,如果你返回application/json那么你的响应内容types是application/json

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

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