【发布时间】:2010-12-27 18:11:43
【问题描述】:
作为休息服务的 CouchDB 访问似乎不安全。一旦暴露,任何人都可以访问数据库并删除/添加文档。
有什么策略可以保护 CouchDB?
【问题讨论】:
-
这个问题有什么更新吗?我敢肯定 2 年内发生了很大变化......
标签: security couchdb restful-authentication
作为休息服务的 CouchDB 访问似乎不安全。一旦暴露,任何人都可以访问数据库并删除/添加文档。
有什么策略可以保护 CouchDB?
【问题讨论】:
标签: security couchdb restful-authentication
自 2009 年以来发生了很多变化,所以我将在这里给出一个答案。这个答案来自this page on the wiki。
CouchDB 有一个_users 数据库,用于定义用户。以下是直接来自 wiki 的要点:
然后,对于任何给定的数据库,您可以按名称或角色定义权限。实现身份验证的方式是通过_session 数据库。向 _session DB 发送一个有效的用户名和密码会返回一个身份验证 cookie。这是 CouchDB 身份验证的几个选项之一。还有更多选择:
此外,根据您可能使用的托管服务,您可以选择通过 SSL 限制对沙发的访问。
在 Node、Couch 和各种其他可有效横向扩展的技术(添加更多服务器)之间,开发人员面临着一种有趣的压力或激励,以使应用程序能够以这种方式很好地扩展。但这是一个单独的问题。
【讨论】:
目前唯一真正有效的安全方面是您的 CouchDB 配置中的类似内容。
[couch_httpd_auth]
require_valid_user=true
[admins]
admin = sekrit
这会将基本的 HTTP 身份验证放在所有 CouchDB 上。即使这在客户端库中也不是很好的支持。对于 python 例如你需要a patched library。
第二种方法是在CouchDB前面放一个代理,让代理做认证和授权工作。由于 CouchDB 的 RESTful 设计,这很容易。
到目前为止,所有其他方法都必须被认为是高度实验性的。
【讨论】:
这可能与您原来的问题略有不同。如果您的 couchdb 只是完整服务器应用程序的后端存储,您可以创建一个特殊帐户供服务器应用程序使用,并要求这些凭据才能访问 couchdb。
另一方面,人们直接通过 javascript 客户端访问的纯沙发应用程序需要非常小心才能确保安全。
使用重写不是可选的。您需要一个 vhosts 配置,通过重写来强制向您的域发出请求。
将路由 */_all_docs 和 /*/_design/* 重写为 404 页面。否则,用户可以列出每个文档或获取您的整个应用程序。
重写通用对象访问,即 /dbname/:id 为一个可以拒绝访问的节目,如果不允许用户查看文档。不幸的是,对于基于文档的附件访问控制没有等效的解决方法。
我们使用 haproxy 过滤 _users 上的 GET 请求。外部人员没有正当理由获取用户记录或列出您的所有用户。我们希望用户能够注册,因此我们需要写入权限。目前沙发不能阻止对数据库的读取访问并同时允许写入。这是一个错误。使用 haproxy 之类的过滤是我们目前最好的解决方法。
使用您自己的数据库来保存除 _users 提供的信息之外的联系信息。这允许对访问进行更多控制。
validate_doc_update 应谨慎拒绝任何不应被允许的写入。
在每种情况下,您都需要想象了解系统的人可以做什么来颠覆它并锁定这些攻击途径。
【讨论】:
CouchDB 可以很好地处理 cookie、SSL、oauth 和多用户:
下面是一些实际的python代码:
from couchdb import Server
s = Server("https://user:password@example.com:6984")
请求cookie:当然是上下编码的url
您必须输入两次凭据才能开始使用第一个 cookie 在 Server() 构造函数以及 _session POST 正文中
code, message, obj = s.resource.post('_session',headers={'Content-Type' : 'application/x-www-form-urlencoded'}, body="name=user&password=password")
assert(code == 200)
现在你已经收到了一个cookie,提取它
cookie = message["Set-Cookie"].split(";", 1)[0].strip()
现在,退出 python 并重新启动
接下来,请求一个服务器对象,但这次没有用户名和密码
s = Server("https://example.com:6984")
s.resource.headers["Cookie"] = cookie
是的,没有密码,尝试访问数据库:
db = s["database"]
可选择在服务器端设置“持久”cookie 选项以使 cookie 持续更长时间。
【讨论】:
您是否阅读过 CouchDB 文档 http://couchdb.apache.org/docs/overview.html?它有一个“安全和验证”部分,可以解决您的一些问题。
【讨论】: