Table of contents
    blog cover

    Beware of html_safe in Rails !!!

    Software Engineer
    Software Engineer
    Ruby on Rails
    Ruby on Rails
    Modern web frameworks provide a secure way to develop new applications. However, if we do not understand it well, it still leads to security issues.
    html_safe in Rails is an example. It seems "safe", but is it safe?

    Understanding html_safe

    Ref: https://api.rubyonrails.org/classes/String.html#method-i-html_safe

    In Rails, the html_safe method is used to mark a string as safe for HTML output. By default, Rails escapes HTML to prevent injection attacks. When you use html_safe on a string, you are telling Rails that the string is safe to insert into HTML without escaping.

    That DOESN'T mean html_safe will make the parsed HTML safe for Cross-Site Scripting (XSS). It's equivalent to a raw helper in the view

    For example:
    // language: ruby
    <%= "<h1>Hello, World!</h1>".html_safe %>

    This will render as:
    // language: markup
    <h1>Hello, World!</h1>

    Without `html_safe`, the output would be escaped:
    // language: markup
    &lt;h1&gt;Hello, World!&lt;/h1&gt;

    The Danger of html_safe

    The primary risk of using html_safe is that it can inadvertently introduce XSS vulnerabilities. XSS occurs when an attacker can inject malicious scripts into a web page, potentially leading to data theft, session hijacking, or other malicious activities.

    Consider the following scenario: you receive user input and mark it as html_safe:
    // language: ruby
    <%= params[:user_input].html_safe %>

    If an attacker submits the following input:
    // language: markup
    <script>alert('Hacked!');</script>

    The output will be:
    // language: markup
    <script>alert('Hacked!');</script>

    This script will execute in the user's browser, leading to an XSS attack.

    Best Practices and Safer Alternatives

    To avoid the pitfalls of html_safe, consider the following best practices:

    • Avoid Using html_safe on user input: Never mark user-generated content as html_safe. Always assume that user input could be malicious and must be sanitized.
    • Use Built-In Helpers: Rails provides a variety of helpers that handle HTML escaping for you. For instance, content_tag and tag helpers are safe to use and automatically escape content: 
    // language: ruby
    <%= content_tag(:h1, "Hello, World!") %>
    • Sanitize User Input: If you must allow some HTML content from user input, use the sanitize helper to remove potentially dangerous tags and attributes:
    // language: ruby
    <%= sanitize(params[:user_input]) %>
    Rails' sanitizing method allows a whitelist of safe tags and attributes, reducing the risk of XSS attacks.
    • Use Rubocop to follow Rails best practices and Brakeman to find security vulnerabilities. No one can know everything, let these tools help you.

    Happy coding!
    Created at 2024-08-26 19:27:04 +0700

    Related blogs