Task 1 of 3

How a Hacker Became a GitHub Org Owner with One Request

In 2012, a security researcher named Egor Homakov discovered a critical vulnerability in GitHub — one of the most important code hosting platforms in the world. He was able to add his SSH key to any GitHub repository, including Ruby on Rails' own repository, without authorization.

The vulnerability was mass assignment. GitHub's Rails application used a feature called attr_accessible to control which model attributes could be set via user input. The problem: the developers hadn't properly configured it on certain models. Homakov sent a carefully crafted request that included hidden fields — fields the app never intended users to set — and Rails dutifully saved them to the database.

THE GITHUB EXPLOIT — SIMPLIFIED
POST /github/repos/rails/rails/keys
Content-Type: application/x-www-form-urlencoded

# Normal: add your key to YOUR repo
public_key[key]=ssh-rsa+AAAA...

# Exploit: add your key to the RAILS repo by including the repo owner field
public_key[key]=ssh-rsa+AAAA...&public_key[user_id]=4223
The user_id field was never meant to be user-controlled — but the Rails model blindly accepted all parameters in the request body.

GitHub suspended Homakov's account (then apologized and reinstated it). Rails shipped a fix. The vulnerability became one of the most famous examples of mass assignment in modern web security.

What is mass assignment?

Mass assignment happens when a web framework automatically maps all fields in an HTTP request body directly to a database model or object — without filtering which fields should be user-controllable.

// ✅ SAFE — explicit allowlist
const { username, email } = req.body;
user.username = username;
user.email = email;

// ❌ VULNERABLE — spread entire body
Object.assign(user, req.body);       // Node.js
User.update(params)                   // Rails (without strong params)
user.__dict__.update(request.json())  // Python/Flask
1

What is the root cause of mass assignment vulnerabilities?

Answer all 1 question to continue