Ruby-on-rails Rails:csrf_meta_tag 是如何工作的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9996665/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails: How Does csrf_meta_tag Work?
提问by Nick
I'm a PHP developer learning Ruby on Rails by reading Michael Hartl's tutorial. Here is a quote from the book, referring to csrf_meta_tag:
我是一名 PHP 开发人员,通过阅读Michael Hartl 的教程来学习 Ruby on Rails 。这是书中引用的一段话,指的是csrf_meta_tag:
...the Rails method
csrf_meta_tag[prevents] cross-site request forgery (CSRF), a type of malicious web attack. Don't worry about the details (I don't); just know that Rails is working hard to keep your application secure.
...Rails 方法
csrf_meta_tag[防止] 跨站点请求伪造 (CSRF),这是一种恶意 Web 攻击。不要担心细节(我不担心);只需知道 Rails 正在努力确保您的应用程序安全。
The thing is, I'm genuinely curious. How does inserting csrf-paramand csrf-tokenmeta tags prevent CSRF? I tried Googling, but couldn't find anything.
问题是,我真的很好奇。插入csrf-param和csrf-token元标记如何防止 CSRF?我试过谷歌搜索,但找不到任何东西。
回答by Frederick Cheung
csrf_meta_tagis basically fulfilling the same thing as hidden form fields but is there to give javascript requests that aren't tied to a form an easy way of getting the token.
csrf_meta_tag基本上实现与隐藏表单字段相同的事情,但是否可以为不绑定到表单的 javascript 请求提供一种获取令牌的简单方法。
If you use the jquery-ujslibrary the content of that meta tag is automatically added (as a request header) to any ajax requests made.
如果您使用jquery-ujs库,该元标记的内容会自动添加(作为请求标头)到任何 ajax 请求。
回答by jefflunt
The csrf_meta_taginserts what is essentially a digitial signature into the page, acting as verification that requests coming into the application server are, in fact, from properly logged in users. This helps prevent cross-site scripting (a script on a completely unrelated page firing requests off to say, GMail, while you're logged into your GMail in another tab).
该csrf_meta_tag刀片本质上是digitial签名到页面,作为核实进入应用服务器的请求,事实上,从正常登录的用户。这有助于防止跨站点脚本(当您在另一个选项卡中登录 GMail 时,完全不相关的页面上的脚本会触发请求说 GMail)。
I guess to clarify, the csrf_meta_tagitself doesn't prevent an unrelated page from firing off requests to your GMail (or any other service that is the target of the attack), but the "digital signature" in the csrf_meta_tagis used to verify the validity of said requests. Invalid requests (i.e. from cross-site scripting attempts) should fail validation, and are therefore discarded.
我想澄清一下,csrf_meta_tag它本身并不能阻止不相关的页面向您的 GMail(或作为攻击目标的任何其他服务)发出请求,但是 中的“数字签名”csrf_meta_tag用于验证说的要求。无效的请求(即来自跨站点脚本尝试)应该无法通过验证,因此被丢弃。
To say it another way, from the attacker's point of view:
换句话说,从攻击者的角度来看:
Before csrf_meta_tagsexisted (they aren't exclusive to Rails by any means), successful cross-site scripting attacks allowed a malicious site to submit data to a web app in a way that makes the request appear as if it's being done on the user's behalf. So, let's say you're an admin on a web service, and in one browser tab you're logged into the admin panel for that service. If a malicious site open in another tab targeted your service for an attack, the malicious site might be able to run scripts that make admin requests, such as dumping list of users from the database, stealing other sensitive data, or potentially harming, damaging, or destroying data contained in the service, all while appearing (from the server's standpoint) to be valid requests from the admin themselves. The csrf_meta_tagis a way to sign requests, and help thwart such attempts from being successful.
在csrf_meta_tags存在之前(无论如何它们都不是 Rails 独有的),成功的跨站点脚本攻击允许恶意站点以某种方式向 Web 应用程序提交数据,使请求看起来好像是代表用户完成的。因此,假设您是 Web 服务的管理员,并且在一个浏览器选项卡中您登录到该服务的管理面板。如果在另一个选项卡中打开的恶意站点以您的服务为目标进行攻击,则该恶意站点可能会运行发出管理员请求的脚本,例如从数据库中转储用户列表、窃取其他敏感数据或可能造成伤害、破坏、或破坏服务中包含的数据,同时(从服务器的角度来看)似乎是来自管理员自己的有效请求。这csrf_meta_tag是一种签署请求的方式,并有助于阻止此类尝试成功。
There's a much more detailed explanation available here.
还有一个更详细的解释可以在这里找到。
It would also be educational to do a "view source" on one of your Rails-generated pages, and you'll see what the CSRF tag looks like.
在您的 Rails 生成的页面之一上执行“查看源代码”也很有教育意义,您将看到 CSRF 标签的样子。
回答by AMIC MING
In Rails it will work like this way
在 Rails 中,它会像这样工作
def csrf_meta_tags
if protect_against_forgery?
[
tag('meta', :name => 'csrf-param', :content => request_forgery_protection_token),
tag('meta', :name => 'csrf-token', :content => form_authenticity_token)
].join("\n").html_safe
end
end
You also need to check Ruby On Rails Security Guide
您还需要查看Ruby On Rails 安全指南
here is the nice blog
这是不错的博客
BUT - I prefere National Vulnerability Database, here is the good explanation
但是 - 我更喜欢国家漏洞数据库,这是很好的解释
CWE-352: Cross-Site Request Forgery (CSRF)
CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
回答by praveenag
csrf_meta_tagsare indications for ajax requests to use these as one of the form parameters to make a request to the server. Rails expects the csrf as part of your form body (params) to process your requests. Using these meta tags you can construct the form body or the csrf header to suit your needs. I hope this answer helps your question.
csrf_meta_tags是 ajax 请求使用这些作为表单参数之一向服务器发出请求的指示。Rails 期望 csrf 作为表单主体(参数)的一部分来处理您的请求。使用这些元标记,您可以构建表单正文或 csrf 标题以满足您的需要。我希望这个答案对你的问题有所帮助。
回答by artamonovdev
Output of the helper csrf_meta_tags:
助手csrf_meta_tags 的输出:
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="J/gw2ePXHS9Z1SUSSeUQgMmPhsPEFlFbMrLTLFHLfKjeWh7g4uyOnBlfKnlZlmCBiALDWdDWCSo1z0tybGVtfA==" />
This token can be included in ajax request. Exapmle (jquery-ujs):
此令牌可以包含在 ajax 请求中。示例(jquery-ujs):
https://github.com/rails/jquery-ujs/blob/4b6e30f68ff1244fc0c790641d3408c2695a29bd/src/rails.js#L70
https://github.com/rails/jquery-ujs/blob/4b6e30f68ff1244fc0c790641d3408c2695a29bd/src/rails.js#L70
csrfToken: function() {
return $('meta[name=csrf-token]').attr('content');
},
// URL param that must contain the CSRF token
csrfParam: function() {
return $('meta[name=csrf-param]').attr('content');
},
// Make sure that every Ajax request sends the CSRF token
CSRFProtection: function(xhr) {
var token = rails.csrfToken();
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
},

