# How Zurp works Three independent data planes share one `HttpHandler`. They were built years apart and differ noticeably in maturity. ``` ┌──────────────── Burp Suite JVM ────────────────┐ │ │ │ Proxy · Repeater · Intruder · Scanner │ │ │ ▲ │ │ │ requests │ responses │ │ ▼ │ │ │ ┌──────────────────────────────────────┐ │ │ │ ZURP (extension) │ │ │ │ │ │ │ │ HttpHandler ── Editor tabs ── Suite │ │ │ │ │ │ tab │ │ │ │ ┌────┼────┐ ┌────┴─────┐ │ │ │ │ │ CSRF │ │ Enrich │ FBDL │ │ │ │ │ plane │ │ plane │ plane │ │ │ │ │(in-mem) │ │(persist) │ (persist) │ │ │ │ └─────────┘ └────┬─────┘───┬───────┘ │ │ └────────────────────┼─────────┼───────────────┘ └───────────────────────┼─────────┼───────────────┘ │ │ │ ▼ ▼ ▼ facebook.com api.facebook.com/ meta.com Authorization: Bearer … (researcher's (Zurp's own live session) side-channel) ``` ## Package map ``` burp.zurp ── lifecycle & policy Zurp .................. BurpExtension entry point; holds the public statics (preferences, extensionData, logger, http, requester, organizer, 4 fetchers + the list of them, csrfTokenStore) = the service locator MetaHttpHandler ....... the single HttpHandler; every plane hangs off it ZurpTabComponent ...... the suite tab: Settings / SPARTA / FBDL ZurpUtils ............. isMetaUrl() + preference reads w/ defaults ZurpPrefEnum .......... every preference key originates here (by convention) ZurpLog ............... the only route to Burp's log; NONE by default, DEBUG keeps stack traces and raises Burp events ZurpEnv ............... seeds any preference from -Dzurp.* or ZURP_*, snapshotted once; the tab still wins SpartaTargetExtractor . request → the target a lead is keyed on ZurpUnloadingHandler .. teardown burp.csrf ── plane A CsrfScraper ........... pulls fb_dtsg / fb_dtsg_ag / lsd + SprinkleConfig out of ServerJS payloads, keyed by name not position CsrfTokenStore ........ per-host and per-account, in-memory only CsrfRewriter .......... {{placeholder}} substitution + auto-refresh SprinkleChecksum ...... mirrors the server's sprinkle hash burp.fetcher ── plane B ZurpDataFetcher ....... abstract: queue + worker pool + periodic scheduler, each one individually switchable off in the tab ├ MetaObjectInfoFetcher .... FBID → ent_or_node asset + vanity ├ MetaUrlInfoFetcher ....... URL → xcontroller asset ├ SpartaFindingFetcher ..... target → leads disclosed to me └ FbdlRunFetcher ........... periodic sweep of my own FBDL runs AssetResolver ......... /bug_bounty/assets for the first two; one instance for the extension, so one budget and one 403 latch GraphApiRequester ..... API calls via Burp's own HTTP stack (api.http()) HourlyCallBudget ...... per-endpoint self-throttle SpartaPocRequest ...... lead → the GraphQL call its PoC describes SpartaFindingOrganizer hands each one to Burp's Organizer, once ever SpartaFindingStore / FbdlRunStore .... the persisted shape of each burp.fbdl ── plane C FbdlContextMenuProvider "Pin FBDL run…" in Repeater and Intruder FbdlRewriter ......... {{fbdl..