问题描述
我在 Symfony2 (2.2)上的 ESI 遇到安全问题:
I'm facing a security problem with ESI on Symfony2 (2.2) :
例如,我的应用程序的某些ESI不需要登录并且是公共的,但是其他ESI则要求用户登录并具有ROLE_USER角色.
Some ESI of my application don't require to be logged and are public, but other ESI required the user to be logged and have the role ROLE_USER, for example.
问题在于,每个人都可以通过在导航器的地址栏中写入其URL来显示ESI ...,以便一个人可以访问ESI(在需要管理员角色的操作中称为ESI),甚至没有记录!
The problem is that every guy can display an ESI, by writing its URL in the address bar of the navigator... So a man can access to a ESI (that is called inside an action which requires an admin role), even none logged !
例如,可以在以下URL上读取我的ESI"SybioWebsiteBundle:Controller:showEsiAction": http://mywebsiteurl.com/_proxy?_path=id%3D1%26slug%3Dlorem%26locale%3Dfr%26ranks%3D1-2-3-5-6-7%26page%3D1%26isPhotograph%3D1%26_format%3Dhtml%26_controller%3DSybioWebsiteBundle%253AAlbum%253AshowEsi
For example, my ESI "SybioWebsiteBundle:Controller:showEsiAction" can be read at this URL :http://mywebsiteurl.com/_proxy?_path=id%3D1%26slug%3Dlorem%26locale%3Dfr%26ranks%3D1-2-3-5-6-7%26page%3D1%26isPhotograph%3D1%26_format%3Dhtml%26_controller%3DSybioWebsiteBundle%253AAlbum%253AshowEsi
只有登录的用户才能看到此ESI:他们进入showAction,在Twig模板中,该ESI被称为...但是所有人都可以通过此问题"来作弊和阅读!
This ESI should only be visible by logged users : they go to showAction, and inside the Twig template, this ESI is called... But all people can cheat and read thanks to this "issue" !
我搜索了解决方案,但发现一个非常丑陋:检查用户是否已登录ESI操作...可以,但是我正在使用 HTTP缓存验证优化我的网站加载(和内存).因此,如果选择此解决方案,则需要添加一个附加的ETag来测试用户角色,每次无用户访问ESI时都要清除ESI缓存,并显示一个空响应,如果已登录,则将其清除.再次显示普通视图,等等...
I searched solutions, I got one really ugly :check if the user is logged in the ESI action... it's OK, but I'm using HTTP Cache validation to optimize my site loading (and memory). So if I choose this solution, I need to add an additionnal ETag that test the user role, to clear the ESI cache each time a none user access to the ESI, and display an empty response, and after if one is logged, clear it again and display the normal view, etc...
我现在想作弊的人很少见,所以这可能是一个令人满意的解决方案...幸运的是,从理论上讲,不会因为他们而经常清除缓存!
I now that people who want to cheat will be uncommon, so it could be a satifying solution... In theory, the cache won't be constantly cleared because of them, luckily !
但是我想知道您是否还有其他解决方案?谢谢!
But I want to know if you have another solution ? Thanks !
推荐答案
在< = 2.1
版本中,ESI URL来自导入internal.xml路由文件,该文件公开了常规的Symfony路由能够渲染任何控制器.
In <=2.1
versions, the ESI URL came from importing the internal.xml routing file, which exposed a regular Symfony route that was capable of rendering any controller.
如果普通用户可以访问它,则他们可以在系统中使用任何参数来呈现任何控制器,这是您当前面临的问题.
If a normal user had access to this, they could render any controller with any arguments in your system, which is the issue you are currently facing.
在> = 2.2
中,internal.xml路由文件消失了.现在,您在 config.yml
中有一个片段密钥.代替路由,这将激活一个侦听器,该侦听器监视以/_ proxy
开头的任何请求,这是ESI标签现在呈现为的URL.
In >=2.2
, the internal.xml routing file is gone. You now have a fragments key in config.yml
. Instead of a route, this activates a listener that watches for any requests that start with /_proxy
, which is the URL that the ESI tags now render as.
除了侦听器在内部使用一些技巧外,仅此一项并不会提高安全性.
This alone doesn’t help security, except that the listener uses a few tricks internally.
那么,是什么阻止了邪恶的用户利用此URL来渲染具有任何参数的系统中的任何控制器呢?从 2.2
开始,内置了两种保护措施:受信任的代理和签名的URL.
So what prevents an evil user from exploiting this URL to render any controller in our system with any parameters? Since 2.2
, there are two built in protections: trusted proxies and signed URLs.
处理所有这些魔术的类称为 FragmentListener
.在开始从您的应用程序提供任何服务之前,它首先检查请求的人是否受信任".
The class that handles all this magic is called FragmentListener
. Before it starts serving anything from your application, it first checks to see if the person requesting is "trusted".
如果您使用的是Varnish之类的反向代理,则需要将其IP地址或超级极客的CIDR IP地址范围添加到您的config.yml文件中:
If you’re using a reverse proxy like Varnish, then you’ll want to add its IP address or - CIDR IP address range for the super-geeks - to your config.yml file:
framework
trusted_proxies:
- 192.168.12.0
如果请求来自此IP或范围,则允许它.而且,如果它来自本地地址,则也允许它.换句话说,如果您信任的人是可以的.
If the request comes from this IP or range, it allows it. And, if it comes from a local address, it also allows it. In other words, if it’s someone you trust, then it’s ok.
这篇关于symfony2的安全ESI问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!