A sensitive-action page in the Ravens panel sets no header preventing it from being placed in a frame, so the attacker builds a page that frames the target and overlays a decoy; the victim clicks thinking they click something else.
An attacker page on the Falcon site where you enter the target path and deliver it to the victim; it shows the framing headers the target returns and whether it could be framed and the click stolen.
Frame the action page and steal the victim click.
You framed the target and stole the click.
Why the solution worked
Missing X-Frame-Options and CSP frame-ancestors lets any site frame the page and overlay a layer to steal clicks. The fix is a CSP frame-ancestors none or self, or X-Frame-Options DENY.
The root cause
No header prevents the page being framed. The root is a missing frame-ancestors policy.
How the code is fixed
Enforce CSP frame-ancestors none or self on every sensitive page, plus X-Frame-Options DENY.
Vulnerable code
// No framing headers at all.
app.get('/action', (req, res) => res.send(actionPage));
Safe code
app.get('/action', (req, res) => {
res.setHeader('Content-Security-Policy', "frame-ancestors 'none'");
res.setHeader('X-Frame-Options', 'DENY');
res.send(actionPage);
});
Impact in the real world
Clickjacking tricks users into sensitive actions — transfers, settings changes, granting permissions — without their knowledge.
How defenders detect it
Defenders enforce frame-ancestors on every sensitive page and audit for pages with no framing policy.