The Key That Joined the Wrong Repository — JavaScript Bug Hunt

Modelled on GitHub, March 2012: Egor Homakov showed that a Rails mass assignment weakness let him submit an extra attribute in a public-key update form and…

  • Language: JavaScript
  • Layer: Backend
  • Difficulty: Easy
  • Concepts: Security, Validation
  • Modelled on: GitHub · 2012
  • Visible tests: the owner can rename a key; ownerId in the request is ignored
  • Reward: 50 XP for a complete fix

Briefing

Modelled on GitHub, March 2012: Egor Homakov showed that a Rails mass assignment weakness let him submit an extra attribute in a public-key update form and attach his SSH key to the Rails organisation, then pushed a commit to the rails/rails repository to prove it. GitHub patched the endpoint the same day, and the incident pushed Rails towards strong parameters.

This project is a reconstruction. update.js edits an SSH key record by copying every submitted field onto it — including the field that says who owns it.

Fix updateKey so only the fields a user may edit are applied.

Bug report

BUG-MASSASSIGN · Priority: Critical · Reported by: a user, publicly

updateKey(store, currentUser, keyId, params):

  • returns null (and changes nothing) when the key does not exist or is not owned by currentUser
  • otherwise applies ONLY params.title and params.key when present — every other submitted field (ownerId, id, anything unknown) is ignored and never added to the record — and returns the record

Observed: a request carrying ownerId moved a key to another account.

Logs

[keys] PUT /keys/1 params={"title":"laptop","ownerId":"rails"} by egor
[keys] key 1 owner egor -> rails

The code as shipped

src/keys/update.js (editable)

// PUT /keys/:id — edit an SSH key the caller owns.
exports.updateKey = function (store, currentUser, keyId, params) {
  var record = store.find(keyId);
  if (!record || record.ownerId !== currentUser) return null;
  Object.keys(params).forEach(function (field) {
    record[field] = params[field];
  });
  return record;
};

Read-only context: src/keys/store.js.

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More JavaScript bug hunts.