最近,我看到了许多这样设计的API:至少在HTTP中不安全。

评论

在URL中传递敏感信息不是一个好习惯。在上述情况下,我确定服务器在收到来自客户端的请求后,必须进行一些其他验证(验证会话cookie等)。

@PiyushSaurabh,它是api,什么饼干?

值得注意的是,使用HTTPS时,主机名(api.somewebsite.com)是以明文形式传递的,但没有完整的URL传递,因此在这种情况下,它不会受到偶然的流量嗅探攻击。
在请求特定路径之前,TLS握手已完成(使用地址的域部分),因此TLS握手已完成-该路径在加密的流量之内-有关详细信息,请参阅security.stackexchange.com/a/20847/89876。 />
您通常不将密码放在URL中的原因是因为它们显示在浏览器历史记录和URL栏中。如果客户端不是浏览器,则这些无关紧要。

#1 楼

简介:功能URL比许多人认为的更安全,但并不适合所有应用程序,并且需要格外小心。


这些类型的URL通常称为功能/机密URL。

没有指定威胁模型就谈论安全性毫无意义。以下是一些注意事项:


1:网络上的被动攻击者(窃听)
2:网络上的主动攻击者(可以随意更改数据包) ,mitm等)
3:肩上的冲浪者

4:可以物理访问您计算机的攻击者/具有特权的用户
5:您计算机的另一个用户(常规特权/远程访问)
6:用户本身(例如保护API密钥)


关于网络攻击(1和2),秘密URL是绝对安全的,只要您正在使用HTTPS(现在是2016年,您不应该再使用HTTP!)。

虽然服务器的主机名是通过网络以纯文本格式发送的,但实际的URL在发送到服务器之前已加密-因为它是GET请求的一部分,仅在TLS握手之后出现。


关于肩膀冲浪(3),具有足够熵的秘密URL在防止偶然攻击方面是相当安全的。例如,我将提供一个Google文档URL: >

https://docs.google.com/document/d/5BPuCpxGkVOxkjTG0QrS-JoaImEE-kNAi0Ma9DP1gy


祝您好运!工人的屏幕!

很明显,如果攻击者拥有摄像头并且可以在不被发现的情况下拍照,那是完全不同的事情-在这种情况下,您不应使用秘密URL。您可以通过从秘密URL进行HTTP重定向来减轻攻击,因此它仅在屏幕上显示几秒钟


对于在您的计算机上具有较高特权的攻击者(4),秘密URL的安全性不亚于长密码或什至是客户端TLS证书的安全-因为所有这些实际上都是完全不安全的,因此您无能为力另一方面,具有常规特权(5)的攻击者也不能学习秘密URL,只要您遵循操作系统的良好安全做法即可。您的文件(尤其是浏览器历史记录)不应被其他用户读取。


为了保护API密钥(这个问题的关键是6),秘密URL也不是-安全性低于其他机制(例如AJAX POST)。使用API​​密钥的任何人都将知道如何使用浏览器调试模式来获取密钥。

给别人发送秘密并希望他们不要看它是不合理的! />

有人问到服务器端的风险。

通过威胁建模来处理服务器端的风险是不合理的。从用户的角度来看,您确实必须将服务器视为受信任的第三方,就像您的对手在服务器端具有内部网络访问权限一样,您实际上无能为力(非常类似于客户端计算机上的特权攻击者,即威胁模型4)。

我将概述无意中秘密暴露的常见风险,而不是建模攻击。

在服务器端使用秘密URL的最常见问题是HTTP服务器和反向代理保留日志,并且经常包含URL。

另一种可能性是,秘密URL可能以可预测的方式生成-由于实施有缺陷,PRNG不安全或在播种时提供的熵不足。

设计使用秘密URL的网站时,还必须考虑许多注意事项。 W3C TAG的本页涵盖了其中的许多内容。

在实践中,对于具有动态内容的网站,很难安全地完成所有工作-如此答案所述,Google和Dropbox过去都曾对其进行过破坏。与其他身份验证方法相比,有两个优点:


它们非常易于使用(只需单击链接,而不是输入您的电子邮件和密码)
它们不要求服务器/服务安全地存储敏感的用户凭据
与共享密码(您可以在其他50个站点上重复使用密码)不同,它们很容易共享而没有风险。

评论


@アレックス包含秘密成分的网址,即:您不希望攻击者知道的网址。在您的示例中,这将是API密钥

– goncalopp
16 Mar 30 '16 at 15:36



这是在公司环境中可能发生的另一种威胁模型:服务器具有其他用户,这些用户对http日志具有只读访问权限。在这种情况下,系统上的任何用户都可以看到服务器提供的每个URL。

–迈克尔
16 Mar 30 '19:49



这些URL在某些地方被称为“功能URL”。可以在这里找到很好的讨论:w3ctag.github.io/capability-urls

–马丁·汤姆森(Martin Thomson)
16 Mar 30 '16 at 23:16

如果要实现这样的事情,请记住,大多数Web服务器都会记录该url,这可能是不希望的。

–约翰内斯·库恩(Johannes Kuhn)
16-3-31的3:58

虽然你有很好的论据。我实际上不同意。 URL会被记录,并且经常与查询一起记录。这意味着API密钥将存储在sys管理员可以访问的文本文件中的某个位置。有人认为内容也可以记录下来。没错,但是默认情况下它并不常见。

–nsn
16-3-31在7:53



#2 楼

这取决于该API的使用方式以及所访问的数据类型。例如,访问Google地图的风险要比访问银行数据的风险低得多。

显然,这样的调用在客户端代码中是不安全的,用户可以轻松地学习您的API密钥。

如果在服务器之间进行API调用,那么问题就不那么严重了。

使用HTTP将使连接保持监听状态,HTTPS消除了该问题。

URL中密钥的另一个问题是完整URL最终存储在日志文件中。这扩大了应用程序的攻击面,因为现在有更多地方可以寻找密钥。

要回答您的问题,并不是说在URL中传递密钥本质上是不安全的,而是它比替代方法安全性低,不是最佳实践。假设API没有访问敏感的东西,连接是通过HTTPS进行的,并且调用是在服务器之间进行的,那么对于低风险服务来说,它应该“足够好”。

评论


您为什么会认为访问Google Maps比访问银行数据没有那么危险?我碰巧认识到一个人,他更喜欢黑客清空他的银行帐户,而不是他的妻子发现他在午餐时间去哪里。关键是,在设计安全系统时,您不能做任何假设。

– dotancohen
16 Mar 30 '16 at 13:06

“显然,这样的调用在客户端代码中是不安全的,用户可以轻松地学习您的API密钥。”用户可以轻松地学习以任何其他方式发送的API密钥-就是他们的计算机。技术上无法从POST请求获取API密钥的用户将不会有太多用处!

– goncalopp
16 Mar 30 '16 at 13:20

@dotancohen(据我所知),Google Maps的API密钥只是为了跟踪您的应用对Maps API的调用次数,因为免费用户有限制。因此,不应存在发现特定位置等安全隐患。但是,我理解您的总体观点,我同意这一点。

– DasBeasto
16 Mar 30 '16 at 13:24

在机器学习时代,将所有数据视为安全很重要。从API排放物和其他传统上被认为是“低风险”的项目中揭示次要细节(例如睡眠时间表)太容易了。

–戴夫
16年3月31日在18:20

我认为,每当我们讨论网络安全时,总是假设参与对话的双方至少在一定程度上相互信任。如果我向您发送加密的消息,则您和我自己都可以知道消息的内容。那里的安全性可以防止第三方访问它。因此,有关服务器上的日志文件或浏览器中的调试控制台等的所有参数均无关紧要;如果服务器是攻击者,则否,这是不安全的。如果我们向客户发送消息,则可以,他可以阅读。

– Stijn de Witt
16年3月31日在18:49

#3 楼

通常,将机密作为GET参数传递不是一个好主意。不久前,我在我的博客上整理了一份有关潜在安全问题的列表:

秘密可能会泄露给其他方,如下所示:

从您的计算机/智能手机中


您的浏览器历史记录
由浏览器创建的缓存文件
应该上网

服务器端



Web服务器日志
诸如SIEM,Elasticsearch,Splunk之类的日志聚合服务
由搜索引擎索引的日志文件(相关的Google dork)
反向代理日志

到Third -parties


代理日志(例如在企业环境中)
通过Referer标头提供异常报告服务,例如Rollbar或Sentry

其他网站
朋友,如果URL是在电子邮件或IM消息中共享的,则
公共云中的同住租户

其中一些不适用于Ajax请求,但是ymmv

#4 楼

我想知道为什么没有人明确提到会话固定和CSRF漏洞的风险。当然,您可以通过添加CSRF令牌并实现安全的会话处理来减轻这些负担,但这意味着您实际上已经控制了相关代码。

由于此问题的标题为A secret in a URL,因此有些人可以得出结论如果他们实施一些缓解措施就足够了,而不是将其视为可以避免的可能的攻击媒介,就足够了。

评论


您能否详细介绍会话固定?

–アレックス
16年7月30日在5:10

我不清楚你在这里的意思。 CSRF攻击(我熟悉的攻击)的工作原理是欺骗浏览器在其他站点上执行操作(需要身份验证的操作)时自动发送用户凭据。之所以可行,是因为机密存储为cookie,并由浏览器自动发送。在这种情况下,我们正在讨论存储在网址(而非Cookie)中的机密信息(例如凭据),因此不会自动发送任何内容。还是您在谈论将秘密存储在Cookie中时CSRF的风险?

–代码
20 Aug 17'0:45