JSONP — a third-party callback as your implant

Content-Security-Policy
this page's policy (also verbatim in the response headers)
Content-Security-Policy: script-src 'self' https://cdn.stuxnet.pro https://www.google.com https://www.youtube.com; object-src 'none'; img-src 'self' data:
what JSONP is, in one breath

JSON with padding — a server hands you JSON wrapped in a function you name via a callback query parameter: callback=test → test({"…":…}). It predates CORS as the way a site retrieves third-party data through a script tag; the response arrives as JavaScript, and that's the whole problem. The wrapper is a mechanism, not a decoration: alert(1)({"…":…}) is a function call that executes your named code before the data is even touched.

the video-archive feature, lab-local service

Feeds the same "archive every bug-bounty video" story: give it a video URL, get title / author / link JSON back. It is a JSONP provider — its callback parameter is echoed raw.

Same URL + &callback=test: test({…}) — valid JavaScript. + &callback=alert(1): alert(1)({…}) — the named function executes. Open both; that contrast is the lesson.

Method — turn allowed domains into code sources
  1. Baseline: inline → dead, console names script-src. Self/CDN/google/youtube are the only doors.
  2. For each allowed origin, the question changes from "what payload passes this filter?" to "can I make this domain serve my JavaScript?" — files, uploads, open redirects, changelogs, user-CD content, JSONP.
  3. JSONP is the classic: if an allowed domain echoes your callback parameter into a JS-shaped response, then callback=alert(1) turns the feed into yourImplant + its harmless JSON as arguments. The archive feature above does exactly this.
  4. Then borrow the name of an allowed host for the tag: . The CSP checks the URL; the browser happily executes whatever comes back — the wrapper's JavaScript-ness is the mechanism.
  5. Recon homework on real targets: google the allowed domain + "CSP bypass" (hacktricks keeps a per-domain gadget index; reCAPTCHA on google.com is the famous one), and hunt the domain itself for JSONP/OAuth endpoints — a callback= or redirect_uri= echo anywhere in an allowed scope is a gadget candidate.
  6. The general recipe never rots: allowed origin → find a way it echoes your input as JS → point an allowed script tag at it. Only specific gadgets retire.
Spoiler — the lab's payload (lab-local service)

The script tag's src is on self (allowed), so the loader is fine — and the implantee the loader fetches is your callback: the response alert(1)({…}) executes. A relative src works here because the service speaks JSONP; on real targets the src points at each allowed origin.

Spoiler — the lesson's original gadget (dead, for reference)

Gadget rot, checked live while building this lab: YouTube's oembed honors callback= no longer — responses today are bare JSON, which loads as syntax error, not code. Keep the tag pattern in your pocket anyway: allowed origin → echoable callback → point a script tag at it. Where google.com is allowed, scan its famous gadgets (reCAPTCHA payloads, accounts.google.com OAuth callbacks); where OAuth exists, callback=/redirect_uri= echoes are the first thing to try. When one third-party door closes, the recipe re-finds the next.