Welcome back to “Programming Thursdays”! In a
\[previous week\](/posts/2023/02/ruby-programming-language-the-red-teamers-elegant-powerhouse/), we explored the world of Ruby programming and its basic concepts. This week, we’re diving deeper into the world of web development with Rails, a robust framework built on Ruby. In this article, we’ll uncover Rails’ best practices and tips for efficient web development, while focusing on the specific areas where developers make mistakes—giving us a significant edge when identifying and exploiting weaknesses.
Rails is famous for its “convention over configuration” philosophy. For a red teamer, “convention” means predictable file paths, standard behavior, and common pitfalls, which is a goldmine for reconnaissance and exploitation.
1. The MVC Pattern: The Skeleton of the App
Rails follows the Model-View-Controller (MVC) pattern. Understanding this is key to efficient auditing.
- Model (
app/models): The data and business logic. This is where you look for weak validation or SQL injection in custom scopes (e.g.,User.where("name like '#{params[:name]}'")). - View (
app/views): The user interface. This is where you look for XSS viaraw,html_safe, or improper usage oflink_toleading tojavascript:execution. - Controller (
app/controllers): The intermediary. This is where you look for authorization bypasses (missingbefore_action), insecure direct object references (IDOR), and mass assignment.
2. Mass Assignment and Strong Parameters
In the old days of Rails, you could update a user object by passing a whole hash of parameters. This led to Mass Assignment vulnerabilities where an attacker could inject user[admin]=true into a POST request.
The Fix: Strong Parameters
Modern Rails uses the permit method in the controller to whitelist allowed fields.
| |
Red Team Tip: Look for controllers where permit! (with an exclamation mark) is used. This is the “lazy developer” switch that allows all parameters to be passed, effectively re-introducing the mass assignment vulnerability. If you see params.permit!, try changing sensitive attributes immediately.
3. The Keys to the Kingdom: SECRET_KEY_BASE and Deserialization
Every Rails app has a SECRET_KEY_BASE (and historically secret_token). This key is used to sign (and sometimes encrypt) session cookies.
- The Risk: If you can find this key (often leaked in
.envfiles, GitHub, or via local file inclusionconfig/secrets.yml), you can craft your own session cookies. - The Payoff: This often leads directly to Remote Code Execution (RCE). Rails often uses
Marshal.loadfor session deserialization (using ActiveSupport::MessageVerifier). If you can sign a malicious serialized Ruby object (gadget chain), the server will execute it upon deserialization.
Tools: Use rails-cookie-decryptor or Metasploit’s rails_secret_deserialization exploit.
4. Dangerous Bypasses: raw and html_safe
Rails automatically escapes all output in the view to prevent XSS. However, developers sometimes use these methods to display “legitimate” HTML (like blog posts or comments):
| |
Always search the codebase (grep -r "html_safe" app/views) for these keywords during a white-box assessment. If user input flows into them, you have XSS.
5. Insecure Direct Object References (IDOR)
Rails makes it easy to find records, sometimes too easy.
Vulnerable Code:
| |
Secure Code:
| |
As a tester, always try changing the ID in the URL (/documents/1 -> /documents/2). If you see someone else’s data, the developer missed the scope.
6. Automated Security Tools for Rails
Before you go manual, use the tools that the pros use:
- Brakeman: A static analysis security scanner for Rails. It parses the source code and finds everything from SQLi to XSS and insecure redirects.
1 2gem install brakeman brakeman -A - Bundler-audit: Checks your
Gemfile.lockfor dependencies with known CVEs.1 2gem install bundler-audit bundle audit check --update
Conclusion
Ruby on Rails is a beautiful, powerful framework that makes web development a joy. But like any complex system, it relies on the developer to use its safety features correctly. By understanding the standard conventions of Rails, mastering the nuances of strong parameters, and knowing where to look for hidden secrets and deserialization gadgets, you become a formidable web infiltrator.
Stay curious, audit your code, and never stop breaking things.
Happy hacking!