Tools Used in DevSecOps · Burp Suite

Burp Suite

Burp Suite is PortSwigger's intercepting-proxy platform for testing web applications — and unlike most tools on this course's tool list, it wasn't built automation-first. OWASP ZAP starts from "how do I run this unattended, in CI, on every build" and treats its desktop UI as one interface among several. Burp starts from the opposite end: a human sitting at a Proxy tab, reading real traffic, editing a real request by hand, and deciding what to attack next. That design center is exactly why security engineers reach for it once automation stops being enough — a business-logic flaw, an authorization bypass a scanner's heuristics can't see, a multi-step workflow only a person can reason through. This page covers that manual core, then the two very different ways Burp shows up in a pipeline: Dastardly, PortSwigger's free, fixed-scan CI scanner, and a full Burp Suite Professional workflow driven by a person.

☺ Explain it like I'm 10

Imagine every letter you mail has to pass through a special desk first. At that desk, you get to open each envelope, read exactly what it says, cross out a word and write a different one in, and only then decide whether to actually seal it and send it on. That desk is Burp's Proxy tab. Most people never open their own outgoing mail — a security engineer testing an app opens every single one on purpose, to see if changing one word makes the mail room do something it shouldn't. Dastardly, by contrast, is a mailroom robot that already knows twenty tricky rewordings to try on every letter automatically and just tells you which replies looked suspicious — much faster, but it never actually sits down and reads your mail the way the person at the desk does.

🦝Your host for this topic: Rocky the Raccoon — Rocky doesn't wait for a pipeline gate to run itself; hand him a Proxy tab and a target he's authorized to test, and he'll pry at requests by hand until something gives. Same instinct that makes him this course's threat-modeling host, aimed at a live target instead of a diagram.

What Burp Suite is, and the problem it solves

☺ Like you're 10: It's the desk every request stops at on its way out, so a person can read it, change it, and send it again — as many times as it takes.

Burp Suite is an intercepting proxy platform from PortSwigger, built by Dafydd Stuttard and shipping in one form or another since the early 2000s — one of the oldest tools still in daily professional use in this entire course. It comes in three editions with sharply different purposes: Community Edition is free forever but manual-only — no automated Scanner, a deliberately rate-limited Intruder, and no ability to save and resume a project; Professional is the paid, single-user desktop tool that adds the full active/passive Scanner, unlimited Intruder speed, the Collaborator client for out-of-band detection, and saved projects; Enterprise Edition is a server-based product built for scheduled, agent-driven scanning across many applications rather than one pentester's desktop session. Verify current editions and pricing on PortSwigger's own site before budgeting — licensing details shift more often than the tool's core mechanics do.

The gap Burp fills sits right next to OWASP ZAP, and the honest way to describe it is a difference in center of gravity rather than raw capability. ZAP was built to be automated — its baseline and full-scan scripts, its YAML-driven Automation Framework, and its Docker images are the primary way most teams meet it, with the desktop UI as one option among several. Burp Professional's automation surfaces (a REST API, Dastardly) exist and are genuinely useful, but they were added around a tool whose primary interface is still a person driving a GUI. That's not a limitation to apologize for — it's the reason Burp remains the default choice for manual and semi-automated penetration testing specifically, the work a fully unattended scanner structurally can't do: chaining a business-logic flaw across three unrelated requests, noticing an authorization check that's present on one endpoint and silently missing on its near-identical sibling, or replaying a multi-step checkout flow with one field deliberately wrong. See SAST, DAST & SCA for where DAST sits among the three scan categories generally, and Dynamic Analysis in Practice for the hands-on ZAP workflow this page assumes as background.

◆ Key idea

Every tool covered so far in this course — Semgrep, a linter, a CLI scanner — is designed to run the same way with nobody watching. Burp inverts that: its entire tool surface (Repeater, Intruder, Scanner) is built around a human making judgment calls on live traffic. Automating it (Dastardly, the REST API) is the exception bolted on afterward, not the design center. Keep that inversion in mind for the rest of this page — it's the single fact that explains almost every difference from the tools you've already met.

Architecture: one shared history, every tool reads and writes it

☺ Like you're 10: Every tool in Burp is really just a different way of looking at, or replaying, the exact same pile of requests — nothing has its own separate copy.

Mechanically, Burp's Proxy listens on a local port (127.0.0.1:8080 by default) and sits between your browser and the target as a classic man-in-the-middle. For plain HTTP that's nothing special; for HTTPS it only works because Burp generates its own self-signed Certificate Authority and your browser is configured to trust it — install and trust that CA certificate (from http://burp while the proxy is running) and Burp can decrypt, show you, and re-encrypt TLS traffic in transit. Burp also ships an embedded Chromium-based browser that trusts this CA automatically, which is why most walkthroughs route through it rather than fighting a system certificate store. Every request and response that passes through the Proxy lands in one shared HTTP history, and that history is the actual architecture: Target's site map, Repeater's tabs, Intruder's attack configs, and Scanner's audit queue are all just different views onto — or replays from — that one growing log. There's no separate compiled model to keep in sync, unlike CodeQL's database or a headless scanner's isolated run; right-click any request anywhere in Burp and "Send to Repeater" or "Send to Intruder" is a real, immediate action on the same underlying object.

Manual / semi-automated workflow — one shared HTTP history Your browser, or Burp's Chromium Burp Proxy — 127.0.0.1:8080 TLS MITM via Burp's own CA cert every request passes through here Target application Shared HTTP history every tool below reads and writes it Target / site map Repeater manual resend + edit Intruder automated fuzzing Scanner · Sequencer Decoder Scanner: Pro / Enterprise One shared state, one running app — every manual tool above assumes both. The CI path — Dastardly skips this model entirely CI pipeline on PR merge Dastardly container fixed crawl, no proxy UI Target (staging) JUnit XML report

The manual workflow: scope, Proxy, Repeater, Intruder — what you actually configure

☺ Like you're 10: First you draw a fence around exactly what you're allowed to touch, then you read one request carefully, then you set up a machine to try a hundred versions of it while you get coffee.

The very first thing that happens in any real engagement isn't an attack — it's drawing the scope. Burp's Target tab lets you define included and excluded hosts/paths by hostname and regex, and once "Advanced scope control" is on, everything outside that boundary is filtered out of the site map and, critically, out of what Scanner and Intruder are willing to touch. Since Burp 2021, scope and every other setting can be exported and version-controlled through the Configuration Library (Settings → Configuration library) as JSON rather than living only inside a binary .burp project file — the shape below is representative of that export; treat the exact key names as something to confirm against your installed version rather than copy verbatim into a script:

{
  "target": {
    "scope": {
      "advanced_mode": true,
      "include": [
        { "enabled": true, "protocol": "https", "host": "^staging\\.acme\\.internal$" }
      ],
      "exclude": [
        { "enabled": true, "host": ".*\\.doubleclick\\.net$" },
        { "enabled": true, "host": ".*\\.google-analytics\\.com$" }
      ]
    }
  }
}

With scope set, the day-to-day loop is: browse the app through the Proxy (or let the embedded browser do it), find an interesting request in the Proxy history, right-click Send to Repeater, and edit it by hand — change a parameter, drop a header, resend, read the response, repeat. Repeater is deliberately the least automated tool in Burp; it exists precisely for the judgment calls a scanner can't make, like noticing that changing an order ID from your own to a sequential neighbor's returns a full 200 response instead of the 404 it should.

Once a request is worth fuzzing rather than reading by hand, Send to Intruder marks the same request for automation. Intruder needs two things: payload positions, marked with §…§ around whatever should vary, and an attack type that decides how positions and payload lists combine:

POST /api/login HTTP/1.1
Host: staging.acme.internal
Content-Type: application/x-www-form-urlencoded
Content-Length: 33

username=§admin§&password=§Pa$sw0rd1§
Attack typeWhat it doesTypical use
SniperOne payload set, cycled through each position in turn, one position varying at a timeFuzzing a single parameter across many positions — the default first pass
Battering ramOne payload set, the same value inserted into every position simultaneouslyA token or username that must match identically in two places (e.g. a header and a body field)
PitchforkMultiple payload sets, one per position, advancing in lockstep — position 1 gets payload-list-1[i], position 2 gets payload-list-2[i]Testing matched username/password pairs from a credential list, index-aligned
Cluster bombMultiple payload sets, every combination of every list against every other listAn exhaustive credential-stuffing style test across two independent lists — expensive, use narrow lists

The other config surface that decides whether any of this actually works is session handling rules (Project options → Sessions): a recorded macro — a saved sequence of requests, typically the login flow — paired with a rule that says which tools should run it, and when. Configure a rule to run the login macro whenever a response fails a "logged in" check, and Intruder or Scanner can survive a session timeout mid-run instead of quietly attacking an unauthenticated redirect page for the rest of the attack. Skip this, exactly as with ZAP's loggedInRegex covered in Dynamic Analysis in Practice, and a long-running Intruder attack can silently spend its last three hundred requests against a login page and report a clean result that means nothing.

Extending it: the BApp Store and the Montoya API

☺ Like you're 10: If Burp's built-in tools don't do exactly what you need, you can write a small add-on that watches or edits every request the same way the built-in tools do.

Burp's BApp Store (Extensions → BApp Store) is a catalogue of community and PortSwigger-authored extensions installed with one click. Two are already load-bearing elsewhere in this course: Autorize replays every request that passes through the Proxy under a second, lower-privileged session and flags any pair whose responses come back suspiciously identical — the fast, exploratory way to surface a BOLA candidate, covered in API Security in Depth; InQL walks a GraphQL endpoint's introspected schema and auto-generates queries and mutations to test against it, also covered there. Turbo Intruder and Logger++ are two more in everyday use — the first for attacks that need raw throughput Intruder's UI wasn't built for, the second for structured, filterable logging across a long engagement.

Writing your own extension used to mean the legacy IBurpExtender interface, callable from Java, Python (via Jython), or Ruby (via JRuby). PortSwigger's current, actively developed surface is the Montoya API — pure Java, and the one to reach for on any extension started today, since the legacy API is being phased toward deprecation. A minimal passive check hooked into the same request/response stream every built-in tool shares:

package com.acme.burp;

import burp.api.montoya.BurpExtension;
import burp.api.montoya.MontoyaApi;
import burp.api.montoya.http.handler.*;

public class MissingFrameOptionsCheck implements BurpExtension {

    @Override
    public void initialize(MontoyaApi api) {
        api.extension().setName("Acme: flag missing X-Frame-Options");

        api.http().registerHttpHandler(new HttpHandler() {
            @Override
            public RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent req) {
                return RequestToBeSentAction.continueWith(req);   // pass through unmodified
            }

            @Override
            public ResponseReceivedAction handleHttpResponseReceived(HttpResponseReceived resp) {
                boolean hasHeader = resp.headers().stream()
                    .anyMatch(h -> h.name().equalsIgnoreCase("X-Frame-Options"));
                if (resp.statusCode() == 200 && !hasHeader) {
                    api.logging().logToOutput(
                        "Missing X-Frame-Options: " + resp.initiatingRequest().url());
                }
                return ResponseReceivedAction.continueWith(resp);
            }
        });
    }
}

The point of writing one isn't usually a header check that simple — real Scanner-augmenting rules and organization-specific request rewriting are the common case — but the shape is the same one Semgrep's custom-rule pattern teaches: an off-the-shelf check knows the general case, and your own extension is where you teach the tool about your own application's specific quirks.

Dastardly: the free, CI-focused scanner

☺ Like you're 10: This is the mailroom robot from the analogy above — fast, free, and it never sits down to actually read anything the way a person does.

Dastardly is PortSwigger's free DAST scanner built specifically to live in a pipeline: a single Docker container, no license, no GUI, and a fixed, non-tunable scan — a fast crawl plus a curated set of high-confidence checks — that emits results as JUnit XML instead of a standalone HTML report. JUnit output is the deliberate design choice: a Dastardly finding shows up next to your unit test failures in whatever CI test-results UI you already use, instead of living in a separate DAST dashboard nobody opens on a normal day.

docker run --rm \
  -e BURP_START_URL="https://staging.internal.example.com" \
  -e BURP_REPORT_FILE_PATH="/dastardly/dastardly-report.xml" \
  -v "$(pwd)":/dastardly \
  public.ecr.aws/portswigger/dastardly:latest

Wired into a GitHub Actions job, the JUnit file becomes a first-class check right alongside the rest of the test suite:

name: dastardly-dast
on: [pull_request]
jobs:
  dastardly:
    runs-on: ubuntu-latest
    steps:
      - name: Run Dastardly against staging
        run: |
          docker run --rm \
            -e BURP_START_URL="https://staging.internal.example.com" \
            -e BURP_REPORT_FILE_PATH="/dastardly/dastardly-report.xml" \
            -v "$(pwd)":/dastardly \
            public.ecr.aws/portswigger/dastardly:latest
      - name: Publish results
        uses: EnricoMi/publish-unit-test-result-action@v2
        if: always()
        with:
          files: dastardly-report.xml

Verify that image path against PortSwigger's own current docs before wiring it into a real pipeline — registry locations move, and the exact set of environment variables Dastardly reads has grown since its first release. What doesn't move is the positioning: Dastardly is explicitly a lightweight complement, not a replacement, for a full Burp Suite Professional or ZAP active scan. It has no authentication-configuration surface at all — no macros, no session handling rules — so it's genuinely useful only against a public-facing surface, or paired with a scan that's already authenticated. See Dynamic Analysis in Practice for Dastardly run side by side with a ZAP baseline and full scan against the same target, and Vulnerability Management & Triage for how its JUnit findings get parsed and deduplicated once more than one scanner is reporting into the same backlog.

Gotchas and failure modes

☺ Like you're 10: Most surprises here come from Burp being a person's tool first — it trusts you to remember the fence, the certificate, and the login macro, because normally a person would.

⚠ Active testing is attacking, not observing

Whether it's Repeater, Intruder, Scanner, or Dastardly doing the sending, every one of them can send a real, malicious-shaped payload that creates test data, trips an on-call alert nobody expected, or knocks over a fragile endpoint. Only ever point any of this at a target you're explicitly authorized to test — staging, a dedicated test environment, or a deliberately vulnerable practice app like OWASP Juice Shop or DVWA. Never production without a documented, agreed authorization window, and never a system that isn't yours to test at all.

Burp Suite Professional vs. Dastardly vs. OWASP ZAP

☺ Like you're 10: Three different tools, three different jobs — a scanner that runs itself on every build, a scanner that runs itself but knows fewer tricks, and a toolkit for a person who wants to try something no scanner would think of.

These aren't really competitors so much as three answers to three different questions, and a mature program tends to run more than one.

ToolModelBest whenCosts you
Burp Suite ProfessionalGUI-first intercepting proxy driven by a person, with automation (REST API, extensions) bolted on topManual and semi-automated pentesting — business logic, authorization edge cases, anything a scanner's heuristics structurally can't reason aboutA paid single-user license; genuinely requires a skilled person's time, not just a scheduled job
Burp Suite DastardlyFree, fixed, zero-config CI container — fast crawl plus a curated check setA lightweight, always-on DAST pass on every pull request, with results sitting next to your other test failuresNo authentication config, no tunability, and meaningfully less thorough than either a full active scan or a manual pass
OWASP ZAPFree, open-source, automation-first — YAML-driven Automation Framework, Docker images, a full scriptable API, with a desktop UI as one option among severalA tunable, fully authenticated, scheduled or PR-blocking DAST scan you want to own without a license costA steeper setup for genuinely deep authenticated coverage than Dastardly's zero-config path; still shallower than a skilled person driving Burp by hand

The practical pattern most teams land on: Dastardly or a ZAP baseline scan on every pull request because both are cheap enough to run constantly; a full ZAP active scan, authenticated, on a schedule against staging; and Burp Suite Professional reserved for what none of the automated passes can do — a person, working through the app the way an attacker actually would, on a cadence a real budget can sustain rather than on every commit. See Offensive Security for DevSecOps for how that manual-testing discipline extends past what any CDP challenge requires.

🎬 At the Shift-Left Squad
🐢

Timmy the Turtle: Dastardly ran clean on the checkout service again this week. Same as ZAP's baseline. Gate's green.

🦝

Rocky the Raccoon: I spent an hour in Repeater on that same service yesterday. Cancel an order you don't own — no auth check on the endpoint at all. Green gate, real bug.

🦊

Foxy: How did a fixed CI scan miss an authorization bug that badly?

🦝

Rocky the Raccoon: It never tried to. Dastardly and a baseline scan don't reason about who's allowed to hit an endpoint — that needs a second logged-in identity and a human deciding the response looks wrong. I used Autorize to replay it under a second account and watched the response come back identical.

🐢

Timmy the Turtle: Which is exactly why the gate stays on every commit anyway — it catches the cheap stuff constantly, so Rocky's hour goes to the bug a scanner was never going to find, not to headers I already automated away.

🦊

Foxy: And you were authorized to be poking at checkout like that?

🦝

Rocky the Raccoon: Staging, documented test window, my own test account on both sides. Always. That's not optional just because I found something real.

✓ Checkpoint

1. What does it mean that Burp's tools all share "one HTTP history," and how is that different from a stateless CLI scanner? 2. You have a request with a username and password you want to test against a list of known-matched credential pairs, index-aligned. Which Intruder attack type, and why not Cluster bomb? 3. What does Dastardly trade away compared to a full Burp Suite Professional or ZAP active scan, and what does it get in return? 4. Name one gotcha that comes specifically from Burp being designed around a person driving it, rather than a scheduled job. 5. Why did Rocky's manual Repeater session in the toon scene find something Dastardly's CI run didn't?

Check your answers
  1. Every tool — Target's site map, Repeater, Intruder, Scanner — reads from and writes to the same shared log of requests and responses; there's no separate database or isolated run to keep in sync, so "send this request to Repeater" is an instant action on an object that already exists. A stateless CLI scanner instead runs once, produces one report, and has no ongoing shared state another tool could reach into.
  2. Pitchfork — it advances multiple payload lists in lockstep, so position 1 gets list-1's i-th value and position 2 gets list-2's i-th value at the same time, which is exactly "matched pairs." Cluster bomb would instead try every combination of every list against every other list — correct for an exhaustive test across independent lists, but wrong (and far more expensive) when the values are already paired.
  3. It trades away tunability and authentication configuration entirely — no macros, no session handling, no way to loosen or deepen a check — and a meaningfully smaller check set than a full active scan. In return it gets zero setup, minutes-not-hours runtime, and JUnit XML output that plugs directly into existing CI test reporting.
  4. Any one of: an untrusted CA certificate breaking every HTTPS site until it's installed and trusted by hand; scope not being inferred, so an unconfigured Proxy will happily let Intruder or Scanner fire at third-party resources nobody authorized; Community Edition's deliberate Intruder throttling; or a session handling macro that silently stops working and keeps producing output describing an unauthenticated session.
  5. Because it required a human judgment call a scanner's heuristics can't make — noticing that cancelling an order you don't own returns a success response instead of an authorization error. Dastardly and a baseline scan don't reason about who's allowed to hit an endpoint; that specific check needed a second, lower-privileged identity and a person (helped by the Autorize extension) deciding the matching response looked wrong.