Foreword
Cross-site scripting (XSS) is a type of computer security hole that allows an attacker to insert code into a website. When a user visits the website after the code is embedded, it will be executed in the user’s browser. Since then, an attacker could steal a user’s cookie, or take advantage of an admin to change information on the system, …
Try testing your knowledge of XSS in Rails!
Some questions
Question 1:
Which of the following is safe with XSS?
1 2 3 4 5 6 | <span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span> <span class="token variable">@user</span> <span class="token punctuation">.</span> comment <span class="token delimiter punctuation">%></span></span> <span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span> html_escape <span class="token variable">@user</span> <span class="token punctuation">.</span> comment <span class="token delimiter punctuation">%></span></span> <span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span> sanitize <span class="token variable">@user</span> <span class="token punctuation">.</span> comment <span class="token delimiter punctuation">%></span></span> <span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span> raw <span class="token variable">@user</span> <span class="token punctuation">.</span> comment <span class="token delimiter punctuation">%></span></span> <span class="token erb language-erb"><span class="token delimiter punctuation"><%=</span> <span class="token variable">@user</span> <span class="token punctuation">.</span> comment <span class="token punctuation">.</span> html_safe <span class="token delimiter punctuation">%></span></span> |
The answer is the first 3 options. From Rails 3 onwards, Rails has automatically supported XSS prevention. All strings passed <%= %>
have been automatically escaped . Even, option 2 is redundant when escaping twice
The last 2 options are not safe with XSS. When using raw
or html_safe
, the render @user.comment
will not be escaped. Then, if there is an attacker who embeds the JS code and comments via the <script>
tag, then all the other users will see the comment, the browser will automatically execute the JS code embedded in the attacker. From there, you can steal cookies or borrow admin hand to change information on the system.
Question 2:
Let’s say we want to implement a method like this in the helper:
1 2 3 4 5 6 | <span class="token keyword">module</span> <span class="token constant">ApplicationHelper</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">strong</span></span> <span class="token punctuation">(</span> content <span class="token punctuation">)</span> <span class="token comment"># Các content được truyền vào sẽ được nằm trong tag `strong`</span> <span class="token keyword">end</span> <span class="token keyword">end</span> |
Which of the following implementations is safe with XSS?
1 2 3 4 5 | content_tag <span class="token punctuation">(</span> <span class="token symbol">:strong</span> <span class="token punctuation">,</span> content <span class="token punctuation">)</span> <span class="token string">"<strong> <span class="token interpolation"><span class="token delimiter tag">#{</span> html_escape content <span class="token delimiter tag">}</span></span> </strong>"</span> <span class="token string">"<strong> <span class="token interpolation"><span class="token delimiter tag">#{</span> content <span class="token delimiter tag">}</span></span> </strong>"</span> <span class="token punctuation">.</span> html_safe raw <span class="token punctuation">(</span> <span class="token string">"<strong> <span class="token interpolation"><span class="token delimiter tag">#{</span> content <span class="token delimiter tag">}</span></span> </strong>"</span> <span class="token punctuation">)</span> |
Only option 1 is right! content_tag
(as well as tag
) escape content that is passed in, then include it in the strong
tag.
Option 2 will escape content with html_escape, but it will also escape the strong
tag passed in. So the code will not execute as we want.
The remaining 2 options are similar to question 1.
The last question
A common XSS attack is to take advantage of the href
attribute in tag a
. If it starts with javascript:
or data:
then the code will be executed when the user clicks on the link.
So which of the following is safe for XSS?
1 2 3 4 5 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> a</span> <span class="token attr-name">href</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">'</span> <%= @user.website %> <span class="token punctuation">'</span></span> <span class="token punctuation">></span></span> Personal Website <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> a</span> <span class="token punctuation">></span></span> <%= link_to 'Personal Website', @user.website %> <%= link_to 'Personal Website', sanitize(@user.website) %> <%= sanitize link_to 'Personal Website', @user.website %> |
Only the last option is safe. sanitize
only works with whole HTML tags, not URLs. This means that you should use sanitize
with both the a
tag and not the href
attribute alone.
summary
- Rails has a mechanism for automatically escaping when the code is within <% =%> tags
- Only use
raw
andhtml_safe
when you are sure that you are rendering the html code (for example when taking content from CKEditor ). - Rails will not be able to protect your system if you pass what the user enters tag
a
orlink_to
. In that case, you need to usesanitize
.
To detect XSS vulnerabilities, I recommend you to try brakeman . It will analyze vulnerabilities on your Rails system.
Source of the article
https://revs.runtime-revolution.com/rails-quiz-xss-edition-6ace80dc9515