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

Nat*_*han 828 security rest wcf authorization rest-security

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

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

虽然我理解REST故意没有规格类似于WS-*我希望最佳做法或建议的模式已经出现.

任何讨论或相关文件的链接将非常感谢.如果它的事项,我们将使用WCF与我们的REST API的/服务POX/JSON序列信息使用.NET Framework V3.5的建立.

Gre*_*ill 298

正如tweakt所说,亚马逊S3是一个很好的模型.他们的请求签名确实具有一些功能(例如合并时间戳),有助于防止意外和恶意请求重放.

HTTP Basic的优点是几乎所有HTTP库都支持它.当然,在这种情况下,您需要使用SSL,因为通过网络发送明文密码几乎是一件坏事.使用SSL时,Basic优于Digest,因为即使调用者已经知道需要凭据,Digest也需要额外的往返来交换nonce值.使用Basic,呼叫者只需在第一次发送凭据.

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

  • @NormanH:你的论点似是而非,因为如果有人可以看到我用来发布到Twitter的整个交易,那么他们就可以冒充我并以我的名义发布他们自己的消息. (36认同)
  • "通过网络发送明文密码几乎普遍是一件坏事"` - 你能详细说明"几乎"吗?什么时候不是坏主意? (5认同)
  • SSL是安全性的重要组成部分,但并非所有应用程序都需要该级别的加密.如果有人在途中窃取您要在Twitter上公开发布的内容,这是一个如此重大的缺点吗?对于大多数API而言,SSL加密将是首选.SSL的基础结构要求略高于明文,并且没有中间(在此处读取基于边缘的)高速缓存服务器可以参与重复访问的内容的高速缓存.请注意,如果您绝对需要提供加密,则可扩展性可能会受到影响. (3认同)
  • 从维基百科上引用摘要式身份验证,"摘要式访问身份验证是Web服务器可以用来与用户的Web浏览器协商凭据的商定方法之一.它在通过网络发送密码之前将密码函数应用于密码,这是比发送明文的基本访问认证更安全." 这将是完成我上面提到的一种标准方式.(详见http://en.wikipedia.org/wiki/Digest_access_authentication) (3认同)
  • @GregHewgill即使在专用网络中,我也不希望我的用户能够拦截彼此的密码。我能想到的唯一可以通过网络发送密码的情况是用户独自在网络中时。这样的事情在其他地方发生的事实,几乎不是允许它发生的理由。 (2认同)
  • 如果您使用ssl,则无需关心重放攻击.请参阅:http://security.stackexchange.com/questions/20105/are-ssl-encrypted-requests-vulnerable-to-replay-attacks (2认同)
  • @nflash请提供详细信息.你的引语"SSL本身不是很安全"非常模糊.你怎么解密原始邮件?我不明白为什么你说这不是那么难. (2认同)
  • @NormanH:是的,在发布之前看到某人的推文没什么大不了的,但是没有加密保护,攻击者也可以修改它们.这是一个大问题. (2认同)

Mar*_*ouf 115

除HTTP之外,没有REST标准.那里有成熟的REST服务.我建议你看看他们,并了解他们的工作方式.

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

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

  • HTTP不是REST的要求. (20认同)
  • RESTful Web Services绝对是一本好书.必须阅读这方面的内容.这是彻头彻尾的启发. (6认同)
  • 考虑到(1)没有REST规范和(2)关于架构风格的Fielding论文和基于网络的软件体系结构的设计明确提到REST,@aehlke如何收到这么多评论的评论?和6.3中的HTTP:REST应用于HTTP. (6认同)
  • RESTful Web Services 书籍可从其网站免费获取:https://www.crummy.com/writing/RESTful-Web-Services/ (3认同)

小智 72

您可能还想了解OAuth,这是一种新兴的基于令牌授权的开放式协议,专门针对http apis.

它与flickr采用的方法非常相似,并记住牛奶 "休息"api(不一定是restful apis的好例子,但是基于令牌的方法的好例子).

  • OAuth是关于授权的授权,即我是信息/帐户的所有者,服务A与我在服务B上的数据交互(例如,我让Twitter在我的Facebook上写).从广义上讲,它不是授权用户可以对资源(数据,信息,服务......)进行控制.这是XACML介入的地方.XACML允许您定义有关谁可以执行哪些操作的授权策略. (4认同)
  • 但似乎我认为这里需要的双腿oAuth并不像三条腿那样覆盖(缺乏信息). (3认同)

And*_*ejs 60

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

认证

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

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

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

JWT(JSON Web令牌)

  • 使用随机复杂的密钥(JWT Secret)来强制执行令牌非常困难.

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

  • 使令牌过期(TTL,RTTL)尽可能短.

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

OAuth的

  • 始终验证redirect_uri服务器端以仅允许列入白名单的URL.

  • 总是尝试交换代码而不是代币(不允许response_type=token).

  • 使用状态参数与随机哈希值,以防止CSRFOAuth认证过程.

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

访问

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

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

  • 使用HSTS带SSL的标头可以避免SSL Strip攻击.

输入

  • 根据操作使用正确的HTTP方法:( GET读取),POST(创建),PUT/PATCH(替换/更新)和DELETE(删除记录),并405 Method Not Allowed在请求的方法不适合所请求的资源时进行响应.

  • 验证要求内容类型Accept头(内容协商),只允许你支持的格式(例如application/xml,application/json等),并与响应406 Not Acceptable,如果没有匹配的响应.

  • 验证content-type的发布的数据,你接受(例如application/x-www-form-urlencoded,multipart/form-data,application/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进行文件上传.

  • 如果您正在处理大量数据,请使用Workers和Queues在后台尽可能多地处理并快速返回响应以避免HTTP阻塞.

  • 不要忘记关闭DEBUG模式.

产量

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

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

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

  • 删除指纹头- ,,X-Powered-By 等.ServerX-AspNet-Version

  • 强制content-type您的回复,如果您返回,application/json那么您的回复内容类型是application/json.

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

  • 根据完成的操作返回正确的状态代码.(例如200 OK,400 Bad Request,401 Unauthorized,405 Method Not Allowed,等等).


sti*_*att 43

我对客户端证书尚未提及SSL感到惊讶.当然,只有依靠证书识别的用户社区,这种方法才真正有用.但是许多政府/公司确实向用户发布了这些政府/公司.用户不必担心创建另一个用户名/密码组合,并且在每个连接上建立身份,因此与服务器的通信可以完全无状态,不需要用户会话.(并不意味着所提到的任何/所有其他解决方案都需要会话)

  • 哦,你可以做到....你可以让负载均衡器转发TCP流量,但你不能,例如,负载均衡器是SSL的终止点. (4认同)
  • @fiXedd - 与我对客户证书的体验相反,因为他们是真正无国籍的.客户端证书认证连接可以使用哑负载平衡器进行负载平衡,而不考虑连接粘性,因为它们要求客户端和服务器之间绝对零共享状态. (2认同)

Dav*_*ard 38

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

例如,如果您的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等.

以下是有趣的资源:

  • 我不明白为什么你不能只实现将获得用户和他的权限的令牌系统,这将基本上是相同的东西? (2认同)
  • 作为旁注,"9到5"对安全有什么贡献?好像攻击者只在晚上活动?更不用说严重的使用影响,好像医生只能工作"9到5". (2认同)

小智 25

我已经使用了OAuth几次,还使用了其他一些方法(BASIC/DIGEST).我全心全意地建议OAuth.以下链接是我在使用OAuth时看到的最佳教程:

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

  • 链接似乎已损坏,仅供参考。 (2认同)

deg*_*ome 17

我曾经遇到过关于安全性的最好的帖子之一,因为它与REST相关,已经超过了1个RainDrop.MySpace API也使用OAuth来保证安全性,并且您可以完全访问RestChess代码中的自定义通道,我对此进行了大量探索.这是在Mix上演示的,你可以在这里找到帖子.


Nat*_*han 15

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

  • 那是错的.HTTPS保护一切.它是:TCP握手... TLS握手...... <加密> GET/foo 200 OK ...拆解</ ENCRYPTED>. (51认同)
  • Wayback Machine是一件美丽的事:[问题描述](http://web.archive.org/web/20110525082448/http://www.thefreakparade.com/2008/09/flowing-identity-from-a-client -to-a-service-when-using-restful-wcf-part-1-the-problem /)和[解决方案](http://web.archive.org/web/20110525082818/http://www.thefreakparade的.com/2008/09 /流入身份从-A-客户机到一服务-时-使用的RESTful的WCF部分-2-A-溶液/) (11认同)
  • 嗯......不确定你是对的.我相信除了需要了解需要哪种加密所需的少数标头之外,所有其他标头都是加密的. (2认同)

小智 14

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


Abh*_*wad 7

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

  • 注意详细说明为什么在大致不完整的情况下你会推荐第2版?恕我直言,版本1.0a仍然是大多数应用程序的可靠解决方案. (8认同)

小智 6

我搜索了很多关于restful ws安全性的信息,我们最终还是使用了令牌从客户端到服务器来验证请求.我使用spring security来授权服务中的请求,因为我必须根据已经在DB中的指定安全策略对每个请求进行身份验证和授权.


kra*_*etz 6

SOAP世界很好地涵盖了安全标准这一事实并不意味着默认情况下它是安全的.首先,标准非常复杂.复杂性不是安全性的好朋友,而XML签名包装攻击等实现漏洞在这里很常见.

而对于.NET环境我也不会有多大效果,但"与Java构建Web服务"(与〜10名作者砖)也帮助我很多理解WS-*安全架构,特别是它的怪癖.


Rob*_*hel 5

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


Man*_*ain 5

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