简体   繁体   English

服务器端urllib2.urlopen和用户的url的安全注意事项

[英]Security considerations with server side urllib2.urlopen with url from user

I'd like users to be able to upload images from the web by providing a URL. 我希望用户能够通过提供URL从网络上载图像。 I don't think I can get the client to fetch the image and upload it due to possible CORS issues and hotlink prevention, so I'm getting the server to do it. 由于可能的CORS问题和防止热链接,我不认为我可以让客户端来获取图像并上传它,所以我要让服务器来做。

The biggest concern is the user simply entering file:///home/user/secret_image.jpg . 最大的问题是用户只需输入file:///home/user/secret_image.jpg This URL gets sent to the server and django happily fetches it, a local server side file, hosting it for the world to see. 该URL被发送到服务器,django高兴地获取它,它是一个本地服务器端文件,将其托管给全世界查看。 Is there a way to limit requests to external resources? 有没有一种方法可以限制对外部资源的请求? How can this approach be made safe (at least -ish)? 如何使这种方法安全(至少-ish)?

Some other concerns may be the user providing a hostname that resolves to a local address or providing a public URL redirect to a local address. 其他一些问题可能是用户提供了可以解析为本地地址的主机名,或者是提供了重定向到本地地址的公共URL。 Even other devices on the LAN which wouldn't normally be accessible. 甚至LAN上通常无法访问的其他设备。

Filtering the URL text is not an option. 过滤URL文本不是一种选择。 I could perhaps check that the IP gets routed to a gateway and the destination is outside my subnet before allowing urllib to continue. 在允许urllib继续之前,我也许可以检查IP是否路由到网关并且目标是否在我的子网之外。 I could block any redirects, but this may be a useful feature in some cases, so I could write a redirect handler to re-check the IP. 我可以阻止任何重定向,但是在某些情况下这可能是有用的功能,因此我可以编写重定向处理程序以重新检查IP。 Now this is starting to feel like a patch job and not a nice robust takes-care-of-all-cases solution. 现在,这开始感觉像是一项修补工作,而不是一个很好的健壮的“万事俱备”的解决方案。

I'm also doing basic stuff like read(max_size) in case the file is huuge, using python-magic to check the mimetype and pick an extension, using django-ratelimit and setting a timeout on the call to urlopen() . 我也正在做一些基本的事情,例如read(max_size) ,以防文件过大,使用python-magic检查mimetype并选择扩展名,使用django-ratelimit并设置对urlopen()的调用超时。

EDIT: related answer 编辑: 相关答案

Give that this can involve significant network I/O, I'd move the work to a "file download worker", eg with Celery , but any other solution even homegrown will do for this part 鉴于这可能涉及大量的网络I / O,因此我将工作移到了“文件下载工作者”,例如使用Celery ,但是即使是本地出产的任何其他解决方案也都可以做到这一点

Filesystem 文件系统

Next part is, once you separate the main Django deployment from its workers, you can use a different and unprivileged OS user to run the worker, which you can be ran inside a chroot or another jail equivalent. 下一部分是,一旦您将主要的Django部署与其工作人员分开,则可以使用另一个没有特权的OS用户来运行该工作人员,您可以在chroot或其他监狱环境中运行该工作人员。 This should limit what the worker can see on its filesystem. 这将限制工作人员在其文件系统上看到的内容。

Network Interfaces 网络接口

As for the network interfaces, you can setting firewall rules, eg I believe on a Linux OS, iptables can set rules per user and per network interface. 至于网络接口,您可以设置防火墙规则,例如,我相信在Linux OS上, iptables可以为每个用户和每个网络接口设置规则。 So that should allow you to limit what the worker's user can do on its network. 这样一来,您就可以限制工作人员的用户可以在其网络上执行的操作。

Bottom Line 底线

Bottom line is, I'd move the task into a separate worker, with unprivileged and restricted access to the computer resources, instead of inheriting the permissions of the main Django app. 最重要的是,我将任务转移到一个单独的工作程序中,该工作程序具有对计算机资源的无特权和受限访问权限,而不是继承主Django应用程序的权限。 The only privilege given to the worker will be to reach out to the internet, grab some files, write it back to disk, nothing more. 赋予工作人员的唯一特权是可以访问Internet,获取一些文件,将其写回到磁盘,仅此而已。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM