Dual-equal sign = in ruby
When I was writing code two days ago, I suddenly received a warning that the project code had an XSS vulnerability, So I immediately checked the Page code based on the reported URL, although it was fixed soon, in addition, the discussion on the same issue came into being two years ago. Generally, more experienced students should know this point, but they still feel it is necessary to write it out and remind other friends again to avoid pitfalls.
Root Cause
Among the vulnerabilities found, there are slim code similar to the following:
input class='xxx' value==params[:account]
The problem lies in the dual equal sign =, because in the slim and ERB templates (Other templates such as HAML are unclear), the dual equal sign is actually the abbreviation of the helper method of Rails raw.
To insert something verbatim use the raw helper rather than calling html_safe:
<%= raw @cms.current_template %> <%# inserts @cms.current_template as is %>
or, equivalently, use <%==:
<%== @cms.current_template %> <%# inserts @cms.current_template as is %>
That is to say, the above Code is equivalent:
input class='xxx' value=raw(params[:account])
Here, the raw method is interpreted as follows in the Rails document:
This method outputs without escaping a string. Since escaping tags is now default, this can be used when you don't want Rails to automatically escape tags. This is not recommended if the data is coming from the user's input.
This method skips the tag filtering and other processing of input strings, and directly outputs the strings to HTML.
So now the reason is clear, because I accidentally added an equal sign to the code and changed it to a double equal sign, as a result, the user's input will be directly output to the HTML to be rendered, leaving the XSS vulnerability unknown. Therefore, the repair solution only needs to remove an equal sign:
input class='xxx' value=params[:account]
In this way, Rails can continue to automatically filter the input: account parameters and automatically filter malicious content.
Raw, String # html_safe, and <% ==%>
When viewing the raw method documentation, I checked its source code, which is extremely simple, with only one line:
# File actionview/lib/action_view/helpers/output_safety_helper.rb, line 16
def raw(stringish)
stringish.to_s.html_safe
end
Raw is just to ensure that the stringish parameter is converted to a String and then the String # html_safe method is called. In addition, in the String # html_safe document, we also repeatedly emphasize the careful use of these two methods:
It will be inserted into HTML with no additional escaping performed. It is your responsibilty to ensure that the string contains no malicious content. This method is equivalent to the raw helper in views.
To sum up, the code written in the following three statements is equivalent and insecure:
input class='xxx' value==params[:account]
input class='xxx' value=raw(params[:account])
input class='xxx' value=params[:account].html_safe
How can we ensure security when we need to output HTML content such as the content edited by the rich text editor?
The solution is simple. You only need to use the sanitize helper method recommended in the document:
It is recommended that you use sanitize instead of this method(html_safe).(#sanitize)Sanitizes HTML input, stripping all tags and attributes that aren't whitelisted.
Or use other third-party gems for filtering.
Summary
- Do not use the equal-and-double-digit abbreviation to avoid abuse by others (such as new Rails beginners in projects) if they do not understand it;
- Try not to use the raw helper or String # html_safe method, and try to use # sanitize;
- Multiple tools are used for automatic scanning, such as brakeman, to quickly and efficiently detect various security risks, including XSS vulnerabilities.
Articles you may be interested in:
- How to view the function source code in the command line in Ruby
- Methods (functions) IN Ruby
- Examples of commonly used string processing functions in Ruby
- Four comparison functions in Ruby (equal ?, Eql ?, ==,==)