Drill or Live, Same Prompt — JavaScript Bug Hunt

Modelled on the Hawaii false missile alert of 13 January 2018.

  • Language: JavaScript
  • Layer: Frontend
  • Difficulty: Hard
  • Concepts: UX, Validation, State
  • Modelled on: Hawaii EMA · 2018
  • Visible tests: a drill goes out on yes; a live alert gets its own prompt and needs an approver
  • Reward: 50 XP for a complete fix

Briefing

Modelled on the Hawaii false missile alert of 13 January 2018. During a shift-change drill at the Hawaii Emergency Management Agency, a live ballistic missile alert was sent to phones, TV and radio across the state; a correction took 38 minutes. The FCC's investigation found, among other failures, that the alert software offered drill and live templates side by side and asked the same confirmation question for both, and that nothing required a second person before a live alert went out.

This reconstruction's alert console asks one generic question for every template and sends a live alert on the same "yes" as a drill.

Fix prepare and send so a live alert has its own confirmation and a second approver.

Bug report

BUG-HI-EMA · Priority: Critical · Reported by: agency review

prepare(templateId, operator) -> { templateId, operator, prompt, requiresApprover }; an unknown templateId throws.

  • drill template (live: false): prompt = PROMPTS.DRILL, requiresApprover = false
  • live template (live: true): prompt = PROMPTS.LIVE, requiresApprover = true

send(pending, input), input = { typed, approver }; returns { sent, channel } — decided from the TEMPLATE's live flag, never trusting fields of pending other than templateId and operator:

  • drill: sent when typed === "yes" -> { sent: true, channel: "drill" }
  • live: sent ONLY when typed === "LIVE" AND approver is a non-empty string different from pending.operator -> { sent: true, channel: "public" }
  • anything else -> { sent: false, channel: null }

Observed: the live template showed the same "Are you sure…" prompt as the drill, and "yes" from a single operator broadcast it to the public.

Logs

[console] op=E1 selected PACOM-CDW prompt="Are you sure that you want to send this Alert?"
[console] op=E1 confirmed "yes" -> channel=public
[console] correction issued +38m

The code as shipped

src/alerts/console.js (editable)

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

function findTemplate(id) {
  for (var i = 0; i < templates.TEMPLATES.length; i++) {
    if (templates.TEMPLATES[i].id === id) return templates.TEMPLATES[i];
  }
  throw new Error("unknown template " + id);
}

// Step 1: the operator picks a template from the menu.
exports.prepare = function (templateId, operator) {
  var t = findTemplate(templateId);
  return {
    templateId: t.id,
    operator: operator,
    prompt: "Are you sure that you want to send this Alert?",
    requiresApprover: false
  };
};

// Step 2: the operator answers the prompt.
exports.send = function (pending, input) {
  var t = findTemplate(pending.templateId);
  if (input.typed !== "yes") return { sent: false, channel: null };
  return { sent: true, channel: t.live ? "public" : "drill" };
};

Read-only context: src/alerts/templates.js.

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