Posting on Anyone's Timeline — JavaScript Bug Hunt

Modelled on Khalil Shreateh's Facebook report of August 2013.

  • Language: JavaScript
  • Layer: Backend
  • Difficulty: Easy
  • Concepts: Security, Auth
  • Modelled on: Facebook · 2013
  • Visible tests: the owner posts on their own wall; a stranger cannot post on someone's wall
  • Reward: 50 XP for a complete fix

Briefing

Modelled on Khalil Shreateh's Facebook report of August 2013. The security researcher found he could post to the timeline of any Facebook user, including people who were not his friends. When his report to the bug-bounty programme was dismissed, he demonstrated it by posting on Mark Zuckerberg's own timeline. Facebook then fixed the flaw (and declined to pay a bounty, since the demonstration broke its rules).

This reconstruction's wall.js checks that both accounts exist and then posts. It never asks whether the actor is allowed to write on that wall.

Fix postToWall so it enforces the wall owner's audience setting.

Bug report

BUG-WALL · Priority: Critical · Reported by: external researcher

postToWall(g, actorId, ownerId, text) returns { ok, error }:

  • unknown owner -> { ok: false, error: "not_found" }
  • unknown actor -> { ok: false, error: "unauthenticated" }
  • the owner may always post on their own wall
  • audience "friends": a friend of the owner (graph.areFriends) may post
  • audience "only_me": nobody but the owner
  • anyone else -> { ok: false, error: "forbidden" } and the wall is unchanged
  • an allowed post appends { from: actorId, text } and returns { ok: true, error: null }

Observed: a stranger's post appeared on the CEO's timeline.

Logs

[wall] khalil -> mark: "..." (not friends) ok=true

The code as shipped

src/social/wall.js (editable)

var graph = require("./graph");

exports.postToWall = function (g, actorId, ownerId, text) {
  var owner = g.users[ownerId];
  if (!owner) return { ok: false, error: "not_found" };
  if (!g.users[actorId]) return { ok: false, error: "unauthenticated" };
  owner.wall.push({ from: actorId, text: text });
  return { ok: true, error: null };
};

Read-only context: src/social/graph.js.

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