如果我考虑到用户的故意错误行为,我是否会过度设计?


12

如果我添加了针对用户的故意不当行为的保护措施(轻描淡写),如果用户可能遭受的伤害与我的代码无关,是否过度设计?

为了澄清,我将公开一个简单的JSON RESTful服务,如下所示:

GET /items - to retrieve list of user's items
PUT /items/id - to modify an item
POST /items - to add a new item

该服务本身并不旨在通过浏览器使用,而只能从由用户控制的第三方应用程序(例如电话应用程序,桌面应用程序等)中使用。同样,服务本身应该是无状态的(即无会话的)。

身份验证通过SSL上的基本身份验证完成。

我说的是这样一种可能的“有害”行为:

用户在浏览器中输入GET网址(没有理由,但是...)。浏览器要求基本身份验证,对其进行处理,并为当前浏览会话存储身份验证。用户无需关闭浏览器即可访问恶意网站,该网站具有恶意CSRF / XSRF javascript,可对我们的服务进行POST。

上述情况极不可能发生,并且我知道从业务角度来看,我不必担心太多。但是为了改善这种情况,您是否认为如果JSON POST数据中也需要用户名/密码,这会有所帮助吗?

还是应该完全放弃基本身份验证,放弃GET,只使用其中包含授权信息的POST / PUT?由于通过GET检索信息也是敏感的。

另一方面,使用自定义标头是否考虑过纯REST实现?我可以删除基本身份验证,并使用自定义标头。这样,至少可以避免来自浏览器的CSRF攻击,并且使用该服务的应用程序将在自定义heather中设置用户名/密码。这种方法的缺点是,现在无法从浏览器使用该服务。


3
以及与我的回答,我也想离开这个说法,我认为这可能会更好的SO或保安回答
杰夫Langemeier

1
我认为您已按照RFC 2616(tools.ietf.org/html/rfc2616#section-9.5)的定义切换了PUT和POST 。
Svante

Answers:


6

工程过度?一点也不。反XSRF措施是任何安全Web应用程序或服务的必要组成部分。某人会选择攻击您,这可能(也可能不是)“非常不可能”,但这并不会减少您软件的不安全感。

系统通常受到使用XSRF的攻击,尽管结果立即性不及SQL注入或XSS明显差,但它们足以破坏所有用户可交互功能。

这确实意味着您不能拥有“纯” RESTful接口,其中唯一的参数是调用本身的属性。您必须在请求中包含攻击者无法猜到的内容。那可能是用户名-密码对,但这远非唯一可能的选择。您可能拥有用户名以及从密码的盐化哈希值生成的令牌。您可以在身份验证时由服务本身发行令牌(可以在会话中记住令牌,也可以通过密码验证令牌)。

我应该摆脱GET

不,GET请求用于没有活动写入操作(它们是“幂等”)的读取请求。只有需要XSRF保护的写操作。


如果GET请求可以显示敏感信息怎么办?
阳光明媚,时间

@Sunny:您在考虑敏感数据吗?
克里斯,

2
克里斯,如果我偏执狂,那么每个数据都是敏感的,如果它是由“错误的”用户收到的:)。它的理论。

请检查我添加的问题中的更改。

1
响应(无论是GET还是其他方法)只包含用户应该看到的数据就可以了。XSRF攻击仅允许攻击者使用户发出特定请求,而不允许他们读取从该请求返回的响应。除非目标脚本以特殊方式构造,以允许第三方页面<script>有意(“ JSONP”)或无意(未受保护的JSON)从标记读取它。
bobince 2011年

32

永远不要相信任何东西。每个请求都是攻击。每个用户都是黑客。如果您以这种思维方式进行开发,则您的应用程序将更加安全,稳定,并且不太可能被恶意用户劫持。只需要一个聪明的人就可以找到一种解决安全问题的方法,以使您的数据(您最宝贵的资源之一遭受严重麻烦

如果您在应用程序中发现了安全漏洞,请执行您认为需要做的所有事情以填补漏洞。尤其是您的API,应该是现有的最不信任的软件。我将需要凭据并接受Post请求。


4
是的,偏执狂!你有敌人!(对于每个请求 +1 都是攻击
2011年

0

如果建立并维护了代码,则应根据具体情况查看和处理边缘案例。

解决我的部分错误:

GET应该仍然用作适当的RESTful服务的一部分,无论如何都需要进行身份验证。我试图推测的是,出于安全性目的,GET与POST大致相同,但是post所做的工作没有将信息放在地址栏中,这往往是巨大的安全性差异(也是为什么我不喜欢GET的原因),但是由@Lee发布,

GET requests are used to retrieve resources, and PUT/POST are used to add/update 
resources so it would be completely against expectations for a RESTful API to use
PUT/POST to get data. 

由于第三方应用程序将使用此方法,因此应遵循RESTful服务的良好做法,以免最终实现者对此感到困惑。


3
GET在安全性上与POST有何不同?两者都是通过传输(HTTP或HTTPS)以纯格式发送的,唯一的区别是GET查询字符串在地址栏中可见。
tdammers

1
@Sunny:在这方面,POST与GET一样公开。如果您不相信我,请启动telnet并与Web服务器对话。
tdammers 2011年

1
@Jeff:之所以使用telnet(或curl,wget或老式的嗅探器),是因为它允许您查看完整的数据流。是的,HTTPS对窃听者隐藏了此信息,但是SSL连接两端的任何人都可以确切地看到telnet看到的内容。
tdammers

1
@Jeremy:POST在地址栏中没有显示参数,但是由于数据在实际的HTTP流中是可见的,因此总体而言您是正确的。
tdammers 2011年

7
GET请求用于检索资源,而PUT / POST用于添加/更新资源,因此使用PUT / POST来获取数据的RESTful API完全不符合预期。
李,

0

您应该考虑所有可能发生的事件,包括用户受到恶意攻击以及(成功)对任何“隐蔽的安全性”障碍进行反向工程。

但是同时,您应该评估成功入侵的影响以及尝试进行攻击的可能性。例如:

  • 受公用防火墙保护的内部服务比公共Internet上的服务受攻击的可能性较小。

  • 某人在客户讨论论坛上失败的影响小于他们窃取客户信用卡的影响。


我的观点是,“全面安全”是“无限昂贵”的……实际上是无法实现的。理想情况下,您应该基于全面的成本效益分析来决定在哪里划界。


谢谢。问题不在于保护用户免受其“侵害”,而是在于保护用户自己(如果他们不负责任地采取行动)。但是您的回答没有什么好处。
阳光明媚,时间
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.