DELIGHTCYBERSECURITY STUDENT WORKBOOK
Ethical Hacking · Bug Bounty Series

Bug BountyHunting

A 37-lab, fully hands-on curriculum covering reconnaissance, the OWASP Top 10, advanced vulnerability classes, mobile and source-assisted hunting, and the career path from first report to working hunter — practiced entirely on legal, intentionally vulnerable targets before you ever touch a real program.

37 Hands-On Labs 100% Legal Practice Targets OWASP Top 10 Coverage Burp Suite · Juice Shop · PortSwigger Academy

⚖️ Read This Before Lab 0.1 — The Rules That Keep You Legal

Bug bounty hunting is testing software with permission. The exact same actions, done without permission, are computer crime in most countries. Every lab in this workbook is built around that line. Internalize these five rules before you open a single tool.

This is general training guidance, not legal advice. Laws vary by country (e.g. the U.S. Computer Fraud and Abuse Act, UK Computer Misuse Act) — know the rules where you and your target are located.

🗺️ How To Use This Workbook

Assumed BackgroundComfortable with a command line and basic HTTP. No prior security experience required — every lab teaches the concept it tests before asking you to use it.
Estimated Time≈35–45 hours across all 9 modules, at a pace of roughly 2 labs per study session.
Core Path (Do In Order)Modules 0–4 — orientation through your first written report. This is the complete loop; finishing it means you're ready to test a real program.
Specializations (Any Order)Modules 5–7 — advanced bug classes, mobile, and source-assisted hunting. Pick whichever matches where you want to go deeper. Module 8 can be read any time.

🐉 Optimized For Kali Linux (Running In VMware)

Every command in this workbook assumes Kali. If you're on Kali in a VMware VM, a few one-time settings save real friction later.

VMware VM Settings

SettingRecommendation
Network AdapterBridged, not NAT — gives the VM a real IP on your network, avoids double-NAT headaches with Docker port mapping, and is needed for some Module 1 recon practice
RAM8 GB minimum. Bump to 12 GB+ once Docker (Juice Shop/MobSF), Burp, and any decompiling are running at the same time
CPU Cores4 if your host can spare them — Docker, Burp, and jadx/apktool all benefit
VMware ToolsInstall open-vm-tools (usually preinstalled on Kali's official VMware image) for clipboard sharing and proper display scaling
SnapshotsTake one right after setup, and again before Module 2 — labs that change app state are trivial to revert this way

One-Time Setup Command

Burp Suite Community is already on Kali by default (just run burpsuite) — skip Lab 0.3's manual download. Everything else this workbook uses across all 9 modules, in one idempotent block:

# safe to run even if some of these are already installed
sudo apt update && sudo apt full-upgrade -y
sudo apt install -y jadx apktool gitleaks ffuf gobuster amass \
  docker.io android-tools-adb nodejs npm python3-pip

# Python-based tools not in apt
pip install --user frida-tools objection semgrep pip-audit
⚠️
Module 6 needs one decision before you start: Android's own developer docs confirm a hardware-accelerated emulator cannot run inside another VM — so Android Studio's emulator will be unusably slow or simply fail inside this Kali guest. Either (a) connect a real Android device via VMware's VM → Removable Devices menu and pass it through to Kali, then run every Module 6 lab exactly as written, or (b) use the Windows companion setup below.

🪟 Windows Companion Environment (Optional — Module 6 Only)

Only needed if you don't have a spare Android device to pass through to the VM. The idea: run the emulator on the Windows host, where it has real hardware acceleration, and point its traffic at Burp running inside Kali.

  1. Install Android Studio (or Genymotion) on Windows itself

    Not inside the VM — directly on the host, so the emulator gets real hardware acceleration.

  2. Find your Kali VM's IP

    Run ip a inside Kali and note the address on the bridged interface.

  3. Open Burp's proxy to the network

    In Burp's Proxy → Options, change the listener from 127.0.0.1 to all interfaces so it accepts connections from outside the VM.

  4. Point the Windows emulator at Kali

    Set its proxy to <kali-vm-ip>:8080 — same as configuring any other device against Burp.

  5. Install Burp's CA cert on the emulator

    Same process as Lab 0.3, just reachable now since the listener is open to the network.

  6. Run Module 6 exactly as written

    Just physically split: the target app runs on Windows, your tools run in Kali. For Frida/Objection specifically, install them on the Windows host too (pip install frida-tools objection — no WSL required) so you can attach to the Windows-side emulator directly.

📑 Table of Contents

Module 0 – Orientation & Lab Setup
Module 1 – Reconnaissance & Scoping
Module 2 – OWASP Top 10 Hands-On
Module 3 – Advanced Hunting Techniques
Module 4 – Reporting & Going Pro
Module 5 – Advanced Vulnerability Classes
Module 6 – Mobile App Testing
Module 7 – Source-Assisted Hunting
Module 8 – Career & Portfolio
Appendix A – Quick Reference
Appendix B – Glossary
🧭

Module 0 – Orientation & Lab Setup

3 labs · How the bug bounty world works, the rules that govern it, and the tools you'll use all workbook long
0.1
What Is Bug Bounty Hunting?Industry overview · Platforms · Reward models
ObjectiveUnderstand what bug bounty hunting actually is, how programs and platforms work, and how hunters get paid — before you touch a single tool.

A bug bounty program is a standing invitation from an organization: "test our systems, within these rules, and we'll pay you for valid vulnerability reports." It flips the economics of security — instead of paying a fixed fee for a one-time pentest, a company pays per confirmed finding, drawing on thousands of researchers with different specialties instead of one consulting team. A Vulnerability Disclosure Program (VDP) is the unpaid cousin of this: "you can test us and report issues, we just won't pay a bounty" — these are where almost every hunter builds their first reputation.

PlatformKnown ForGood First Stop?
HackerOneLargest researcher base; huge public Hacktivity feed of disclosed reportsYes — read before you hunt
BugcrowdStrong VDP focus; free "Bugcrowd University" trainingYes — free structured lessons
IntigritiEU-heavy program listYes, for EU-based hunters
YesWeHackEU/Asia-Pacific programsYes
SynackInvite-only, vetted researcher poolNo — apply once you have a track record
💡
Most hunters' first real "win" isn't a paid bounty — it's a single accepted report on a no-pay VDP. That's the credibility you spend later to get into better programs.
  1. Create accounts

    Sign up for free researcher accounts on HackerOne and Bugcrowd.

  2. Read five real reports

    Open HackerOne's public Hacktivity feed and read five disclosed web-app reports. Note the structure: title, summary, steps to reproduce, impact.

  3. Bookmark one VDP

    Find one Vulnerability Disclosure Program you could realistically test once you finish this workbook. Bookmark its policy page. Do not test it yet — that comes after Module 4.

0.2
Legal & Ethical FoundationsReading scope correctly · Responsible disclosure
ObjectiveLearn to read a scope and disclosure policy correctly, and understand the full responsible-disclosure lifecycle from discovery to public write-up.
ElementWhat To Check
In-scope assetsThe exact domains, subdomains, IP ranges, or apps listed — nothing else
Out-of-scopeAnything explicitly excluded, even if it looks related to the company
Eligible vulnerability classesThe bug types the program will actually reward or accept
Disqualified / "won't fix"Commonly excluded: missing security headers alone, self-XSS, clickjacking on non-sensitive pages, logout CSRF, software version disclosure
Safe harbor clauseLanguage protecting you from legal action — but only for in-scope, policy-compliant testing
Disclosure timelineHow long you must wait before any public write-up, and whether public disclosure is allowed at all
  1. Discover & verify privately

    Confirm the issue is real and reproducible before reporting — don't report a hunch.

  2. Report through the official channel only

    Use the program's designated submission form or security@ address. Never DM employees or post on social media.

  3. Wait for triage

    Don't re-test aggressively or escalate publicly while the team investigates. One clean follow-up question is fine; daily pings are not.

  4. Cooperate during remediation

    Provide extra reproduction detail or a quick re-test if asked — this is what separates a one-off reporter from a trusted hunter.

  5. Disclose publicly only with explicit permission

    And only after the agreed embargo period. Many programs never permit public write-ups — check before you assume.

0.3
Build Your Testing LabBurp Suite · Proxy setup · OWASP Juice Shop
ObjectiveInstall and configure the intercepting proxy and the always-available, 100% legal practice target you'll use for the rest of this workbook.Burp SuiteJuice Shop
  1. Install Burp Suite Community Edition

    Download it from PortSwigger's site and install it for your OS. The free Community Edition covers everything in this workbook. On Kali, it's already there — just run burpsuite.

  2. Route your browser through Burp

    Install the FoxyProxy extension and add a profile pointing to 127.0.0.1:8080 (Burp's default proxy listener). Switch it on only while testing.

  3. Install Burp's CA certificate

    With the proxy on, visit http://burp in your browser, download cacert.der, and import it as a trusted root certificate so HTTPS traffic decrypts cleanly instead of throwing warnings.

  4. Install Docker

    Install Docker Desktop if you don't already have it — this is how you'll run your practice target locally, on your own machine, fully under your control.

  5. Pull and run OWASP Juice Shop

    Run the command below, then open http://localhost:3000. Juice Shop is an official OWASP project built specifically to be hacked — there is no target you could pick that is more legal to attack.

  6. Confirm interception works

    Browse Juice Shop with the proxy switched on and watch requests appear live in Burp's HTTP history tab.

# pull & run OWASP Juice Shop locally — your practice target for Modules 2 & 3
docker run --rm -p 3000:3000 bkimminich/juice-shop
CheckExpected Result
localhost:3000Juice Shop storefront homepage loads
Burp HTTP historyRequests to localhost:3000 appear as you browse
HTTPS sites, proxy onLoad with no certificate warning (CA installed correctly)
💡
Keep Juice Shop running in its own terminal tab — Modules 2 and 3 use it directly, lab after lab.
🔭

Module 1 – Reconnaissance & Scoping

3 labs · Mapping an attack surface before you ever send a malicious payload
1.1
Passive Recon & Subdomain EnumerationCertificate transparency · subfinder · Google dorking
ObjectiveLearn passive and lightweight active recon techniques for mapping an attack surface — practiced against infrastructure you own or control.CLI ToolsYour Own Domain
  1. Install a recon tool

    Install subfinder or amass — both aggregate subdomains from dozens of public sources without sending traffic to the target itself.

  2. Search Certificate Transparency logs

    Visit crt.sh and search a domain you own. Every TLS certificate ever issued for it is public record — and often reveals subdomains that were never meant to be found.

  3. Run subfinder against your domain

    Aggregate findings from dozens of sources in one pass.

  4. Cross-check with a Google dork

    Search site:yourdomain.com -www to surface indexed subdomains and pages search engines have crawled.

  5. Start a recon notes file

    Target, subdomain list, dates, notes. Build this habit now — every future engagement starts the same way.

# passive subdomain enumeration
subfinder -d yourdomain.com -silent

# certificate-transparency lookup via crt.sh
curl -s "https://crt.sh/?q=%25.yourdomain.com&output=json" | jq -r '.[].name_value' | sort -u
TechniqueWhat It Reveals
crt.shSubdomains that ever had a TLS certificate issued
subfinder / amassSubdomains aggregated from dozens of public sources
site: dorkPages and parameters search engines have indexed
web.archive.orgOld endpoints/parameters no longer linked anywhere live
⚠️
This lab stays passive and on infrastructure you own. Active port scanning (e.g. nmap) against anything else — including a company you merely admire — is out of bounds until it's explicitly in scope.
1.2
Technology FingerprintingHeaders · Wappalyzer · error pages
ObjectiveIdentify the frameworks, servers, and libraries a target runs, so you know which vulnerability classes are worth your time first.Juice Shop
  1. Read response headers

    Use Burp's HTTP history (or curl -I) to inspect Server and X-Powered-By headers on your local Juice Shop instance.

  2. Install Wappalyzer

    Browse Juice Shop with the extension active and note the detected stack — frontend framework, backend hints, analytics, everything.

  3. Trigger a verbose error

    Request a malformed or nonexistent route and see whether the response leaks a stack trace, file path, or framework version.

  4. Check old JS bundles

    On a domain you own, search the Wayback Machine for old JavaScript bundle names or API paths that might still be live but no longer linked anywhere.

# quick header fingerprint
curl -I http://localhost:3000
SignalWhat It Tells You
Server / X-Powered-ByWeb server, and sometimes the backend framework
Cookie namesBackend framework hints (e.g. Express session naming)
JS bundle file namesFrontend framework (Angular/React build artifacts)
Verbose error / stack traceExact framework + version, sometimes file paths
💡
Wappalyzer plus a careful read of cookie names correctly fingerprints most stacks you'll meet — save deeper digging for when it actually changes your testing plan.
1.3
Content & Endpoint Discoveryffuf / gobuster · hidden routes · API mapping
ObjectiveDiscover pages, admin panels, and API routes that aren't linked anywhere in the visible UI.ffufJuice Shop
  1. Install ffuf

    Or gobuster — either works for this lab.

  2. Grab a wordlist

    SecLists' common.txt is a solid, widely-used starting point.

  3. Run content discovery against Juice Shop

    Fuzz for real paths against your local instance only.

  4. Investigate every non-404

    Open each 200/301/403 manually and note what it actually is.

  5. Map the REST API directly

    Juice Shop exposes /rest/ and /api/ routes. Browse normally with Burp's proxy on, then review the HTTP history to map real calls the app makes.

# directory & endpoint discovery against your local Juice Shop instance
ffuf -w /path/to/common.txt -u http://localhost:3000/FUZZ -mc 200,301,302,403
Result CodeWhat It Usually Means
200Page/endpoint exists and returned content — investigate it
301 / 302Redirect — follow it, may reveal an auth-gated route
403Exists but you're not authorized — worth a closer look
404Not found — expected for nearly every guess
⚠️
Even at default thread counts, fuzzing can look like an attack to a real security team. Check a program's policy for allowed scan speed before pointing this at anything but your own lab.
🧪

Module 2 – OWASP Top 10 Hands-On

6 labs · The bug classes that make up the overwhelming majority of paid bounty reports
2.1
Broken Access Control / IDORInsecure Direct Object References · missing function-level checks
ObjectiveFind and prove an Insecure Direct Object Reference (IDOR) — consistently one of the highest-volume, easiest-to-verify bug classes on every platform.Juice ShopBurp Suite
  1. Log in and browse normally

    Visit your account, basket, and order history while Burp's proxy captures every request.

  2. Find ID-bearing requests

    In Burp's HTTP history, look for calls like /rest/basket/6 or /rest/user/whoami that reference a numeric or predictable ID.

  3. Tamper with the ID

    Send the request to Repeater and change the ID to a neighboring value. Resend it — do you get back someone else's data?

  4. Test function-level access control

    As a normal user, try navigating directly to an admin-only route (e.g. Juice Shop's /#/administration). Does it load without checking your role?

  5. Document the exact exposure

    Which ID, which endpoint, what data came back that shouldn't have. This becomes your report in Module 4.

TestVulnerable If…
Changed ID in basket/order requestYou see another user's real data, not an error
Direct access to admin routeThe admin panel loads with no role check
Direct call to admin REST endpointReturns 200 with data instead of 401/403
📋
IDOR reports are popular precisely because they're so cleanly provable — a before/after screenshot showing two different users' data through one parameter change tells the whole story.
2.2
SQL InjectionClassic authentication bypass via the login form
ObjectiveIdentify and exploit a classic SQL injection using Juice Shop's login form — the textbook entry point for this bug class.Juice ShopBurp Suite
  1. Capture a normal login

    Submit a regular (failing) login attempt and capture the request in Burp.

  2. Send it to Repeater

    Replace the email field with the classic bypass payload below.

  3. Observe the response

    Did it log you in without valid credentials — often as the very first account in the database?

  4. Confirm impact

    Check the account email shown post-login to prove whose account you accessed.

-- classic SQLi authentication-bypass payload, entered in the email field
' OR 1=1--
PayloadExpected If Vulnerable
' OR 1=1--Logged in with no valid credentials, often as the first DB row
' UNION SELECT ...Data from other tables appears in the response
⚠️
Never use destructive payloads (DROP TABLE, etc.) even on a practice target shared with other students. The goal is proving read/bypass impact, not breaking the environment.
2.3
Cross-Site Scripting (XSS)Reflected · Stored · DOM-based
ObjectivePractice all three XSS flavors and learn the proof-of-execution standard real reports use.Juice ShopPortSwigger Academy
  1. Reflected XSS

    Juice Shop's search bar reflects your input straight into the page. Try the payload below in the search field.

  2. Stored XSS

    Find a field that stores input for other users to view later — a product review or comment. Submit the payload there and reload as a different session.

  3. DOM-based XSS

    Start a free "DOM XSS" lab on PortSwigger Web Security Academy — purpose-built for client-side sinks like innerHTML and document.write.

  4. Always prove it cleanly

    Use alert(document.domain) as your proof. It's the industry-standard, non-destructive way to show you control execution.

// non-destructive proof-of-execution payload — industry standard for reports
<script>alert(document.domain)</script>
XSS TypeWhere TestedWhat Confirms It
ReflectedSearch bar / URL parameterAlert fires immediately from a crafted link
StoredProduct review / comment fieldAlert fires for any user who later views that content
DOM-basedPortSwigger DOM XSS labsAlert fires via a client-side sink, no server round-trip
💡
Real bounty reports almost always use alert(document.domain) rather than a "scarier" payload — it proves identical impact without resembling an actual attack on a live user.
2.4
CSRF & SSRFForged requests from the victim's browser — and from the server itself
ObjectiveUnderstand and test two distinct "request forgery" classes using PortSwigger Academy's purpose-built labs.PortSwigger Academy
  1. Start a CSRF lab

    Open PortSwigger Academy's "CSRF vulnerability with no defenses" lab (free).

  2. Build a minimal auto-submit proof-of-concept (PoC) page

    An HTML form that fires a state-changing request on page load — see the template below.

  3. Host and trigger it

    Follow the lab's instructions to deliver it to the simulated victim and confirm the account state changes.

  1. Start a free SSRF lab

    Find a feature that fetches a URL on the server's behalf — a "check stock at this URL" type feature is the classic Academy example.

  2. Redirect it internally

    Supply an internal address instead of the expected external one.

  3. Confirm impact

    Did the app return internal content it shouldn't have access to?

<!-- minimal CSRF PoC: auto-submitting form -->
<form action="https://lab-target/email/change" method="POST" id="f">
  <input type="hidden" name="email" value="attacker@evil.com">
</form>
<script>document.getElementById('f').submit()</script>

// SSRF: point a "fetch URL" feature at an internal address
http://localhost:8080/admin
BugProof Of Impact
CSRFVictim's account state changes purely from visiting your hosted page — no token required
SSRFServer returns content from an internal/unexpected address you supplied
2.5
Security MisconfigurationExposed files · default creds · debug leaks
ObjectiveSpot exposed debug endpoints, default credentials, and leftover files that should never have shipped.Juice Shopcurl
  1. Check for exposed version control

    Request /.git/config. A 200 response can mean the entire repo history is downloadable.

  2. Try default/test credentials

    Juice Shop deliberately ships some weak accounts — try a few common combinations through the login form, mindful of rate limits.

  3. Trigger a debug page

    Send a deliberately malformed request and see whether a stack trace renders instead of a clean error.

  4. Check security headers

    Look for missing Content-Security-Policy, X-Frame-Options, and Strict-Transport-Security.

# check for an exposed .git directory
curl -I http://localhost:3000/.git/config

# check security headers
curl -I http://localhost:3000
CheckVulnerable If…
/.git/configReturns 200 with real Git configuration content
Default credentialsAny weak/test account actually logs in
Malformed inputReturns a stack trace exposing paths or versions
Security headersCSP / X-Frame-Options missing on sensitive pages
📋
Misconfiguration findings are often lower severity alone — but programs reward them well when chained with another bug. Missing CSP plus a found XSS turns "just a popup" into full account takeover.
2.6
Authentication & Session FlawsPassword resets · JWTs · session reuse
ObjectiveTest password reset flows, session tokens, and JWTs for the mistakes that escalate into full account takeover.Juice ShopPortSwigger Academy
  1. Test the password reset flow

    Request a reset and inspect the token in Burp — is it predictable, reusable, or missing an expiration?

  2. Decode the session token / JWT

    Use Burp's built-in JWT tab or jwt.io to read the header and payload — what claims does it carry, and how is it signed?

  3. Try a known JWT attack

    Run a free PortSwigger JWT lab and test whether the server actually verifies the signature, or accepts an alg: none token.

  4. Check session reuse after logout

    Log out, then replay the old token against a protected endpoint — does the server still accept it?

// decode a JWT's header & payload (no key needed for this part)
echo "<jwt-token>" | cut -d. -f1,2 | base64 -d
TestVulnerable If…
Password reset tokenPredictable, reusable, or never expires
JWT with alg: noneServer still accepts it as valid
Old token after logoutStill works on protected endpoints
Weak JWT signing secretYou can brute-force it and re-sign your own forged token
⚠️
Brute-forcing real login forms — even slowly — can violate a program's rate-limit policy on its own. Practice credential and session attacks on Juice Shop and PortSwigger labs; never on a live program without explicit permission for that exact test type.
🛠️

Module 3 – Advanced Hunting Techniques

3 labs · Logic flaws, APIs, and a full capstone assessment
3.1
Business Logic & Race ConditionsBugs no scanner will ever find
ObjectiveFind flaws in application logic itself — the category where a thinking human consistently beats automated tools.Juice ShopBurp Suite
  1. Test price/quantity tampering

    Intercept a basket request in Repeater and alter the price or set quantity to a negative number before checkout.

  2. Test coupon abuse

    Try reusing a one-time coupon code multiple times, or stacking several at once.

  3. Test for a race condition

    Use Burp's parallel request sending (or Turbo Intruder) to fire the same redeem/discount request several times simultaneously.

  4. Test workflow-step skipping

    Try jumping straight to an "order confirmation" style URL without completing the step that's supposed to come before it.

// example: tampered basket request, quantity changed to negative
{"ProductId": 5, "BasketId": 12, "quantity": -10}
TestVulnerable If…
Tampered price/quantityServer accepts it and the final total reflects the tampered value
Reused one-time couponThe discount applies more than once
Parallel duplicate requestsA single-use action is processed more than once
Skipped workflow stepServer accepts an action before its prerequisite actually completed
💡
Business logic bugs pay well precisely because they require thinking about the workflow, not running a payload list. This is where experienced hunters consistently out-earn pure tool users.
3.2
File Upload & API Security TestingValidation gaps · BOLA · rate limiting
ObjectiveTest file uploads and API endpoints for the validation and access-control mistakes a UI walkthrough never surfaces.Juice ShopBurp Suite
  1. Test file type validation

    On Juice Shop's profile picture or complaint upload, try a file with a mismatched extension/content-type — e.g. an SVG containing a script, renamed with an image extension.

  2. Test path handling

    Try a filename containing path traversal characters and see how the server handles it.

  3. Test API authorization with Postman

    Replay each API call with no auth token, an expired token, and another user's token — this is BOLA (Broken Object Level Authorization), the API version of IDOR.

  4. Test API rate limiting

    Send the same request rapidly and check whether you ever get a 429 throttling response.

// path traversal attempt in an upload filename
../../../etc/passwd.jpg
TestVulnerable If…
Mismatched file type (e.g. SVG with script)Stored/served without sanitization, executable in a browser context
Path traversal in filenameServer writes outside the intended upload directory
API call with another user's tokenReturns that other user's data (BOLA)
Rapid repeated API callsNo throttling response at all
📋
API security testing (BOLA/BFLA) is one of the fastest-growing report categories on every major platform as more apps move API-first. Postman plus Burp covers almost everything you need.
3.3
Capstone — Full Juice Shop AssessmentModules 1–3, combined into one structured engagement
ObjectiveCombine everything from Modules 1–3 into one structured assessment, the same way you'll approach a real program.Juice ShopBurp SuiteCLI Tools
🎯
This is your Module 1–3 capstone. Set aside 90–120 minutes. Work through each phase in order, and keep notes on every finding — you'll turn them into a report in Module 4.
  1. Recon (≈15 min)

    Re-run fingerprinting and endpoint discovery fresh. List every API route you can find.

  2. Access control (≈20 min)

    Systematically test every ID-bearing endpoint you found for IDOR/BOLA.

  3. Injection (≈20 min)

    Test every input field — search, login, registration, contact/feedback — for SQLi and XSS.

  4. Logic & workflow (≈20 min)

    Test checkout for price/quantity tampering, coupon reuse, and step-skipping.

  5. Configuration & auth (≈15 min)

    Check headers, exposed files, the password reset flow, and session handling.

  6. Write-up (≈20 min)

    Draft a one-paragraph summary and reproduction steps for your single best finding.

CategoryFound A Real Issue?Severity Guess
Access Control / IDOR
Injection (SQLi/XSS)
Business Logic
Configuration
Auth / Session
🎯
You're ready for Module 4 when: you have at least 3 distinct, clearly reproducible findings across at least 2 different categories above.
📝

Module 4 – Reporting & Going Pro

3 labs · Turning findings into accepted reports, and a 30-day plan for your first real submission
4.1
Writing A Winning Vulnerability ReportThe structure every triager expects
ObjectiveLearn the exact structure triagers expect, and write one real report from your capstone findings.
  1. Pick your strongest capstone finding

    The clearest, most reliably reproducible one — not necessarily the scariest-sounding.

  2. Write a precise title

    Pattern: "[Vulnerability class] in [location] allows [impact]" — e.g. "IDOR in /rest/basket/:id allows viewing other users' basket contents."

  3. Write numbered reproduction steps

    Exactly as you'd hand them to a stranger who has never opened the app before.

  4. Attach proof

    A screenshot of the request/response pair, or a short screen recording — visual evidence, not just a description.

  5. State impact precisely

    "An attacker can view any other user's basket contents by incrementing the basket ID" — not "this could lead to a full data breach."

  6. Estimate severity

    Use CVSS (the Common Vulnerability Scoring System) if the program requires it, or its plain Low/Medium/High/Critical scale otherwise.

SectionWhat Triagers Are Checking For
TitleSpecific enough to understand the bug without opening the report
Steps to reproduceFollowable exactly, in order, with no missing context
Proof of ConceptVisual evidence the bug is real — not just "this looks bad"
ImpactPrecise, not inflated
SeverityMatches the program's own rating scale
⚠️
Exaggerating impact — "this could lead to RCE!" on a low-severity CSS injection — is the fastest way to lose credibility with a triager. Undersell slightly and let the bug speak for itself.
4.2
Submitting, Triage & Building ReputationWhat happens after you hit submit
ObjectiveUnderstand what happens after submission, and how to behave through triage, duplicates, and rejection.
StatusWhat It MeansWhat You Do
NewReceived, not yet reviewedWait — don't follow up within 24–48h
TriagedConfirmed and validatedCooperate promptly if asked for more info
DuplicateSomeone reported it firstAccept gracefully; ask politely for the report ID if you want to learn from it
Not ApplicableDoesn't qualify under policyRead the explanation; don't re-argue the same point
ResolvedFixed, bounty paid if applicableAsk if public disclosure is permitted before writing about it
  1. Submit through the official channel only

    Never email an employee directly or post on social media.

  2. Respond promptly and politely

    To any triager follow-up questions.

  3. Accept duplicates and rejections without argument

    One calm clarifying question is fine; repeated pushback damages your reputation.

  4. Track your own stats

    Submissions, response time, acceptance rate — over time this becomes your case for private program invites.

💡
Politeness compounds. A hunter known for clean, undramatic reports gets invited to private programs. One known for arguing every "Not Applicable" does not.
4.3
Your 30-Day Roadmap & Resource LibraryWhat to do next, and where to keep learning
ObjectiveLeave this workbook with a concrete plan and a list of where to keep building real skill.
  1. Week 1

    Re-run Modules 0–1 against a second self-owned target. Join Bugcrowd University's free courses for the categories you felt weakest in.

  2. Week 2

    Clear 10 more PortSwigger Academy labs in categories you haven't tried yet — insecure deserialization, NoSQL injection, GraphQL flaws.

  3. Week 3

    Pick the VDP you bookmarked back in Lab 0.1. Read its policy twice. Do your first authorized recon pass under its actual scope.

  4. Week 4

    Submit your first real report on that program, using the format from Lab 4.1. Whatever the outcome, log what you'd do differently.

CategoryResource
Free trainingPortSwigger Web Security Academy · Bugcrowd University · OWASP Juice Shop · OWASP WebGoat · TryHackMe free rooms
Best free educationHackerOne's public Hacktivity feed — read disclosed reports in your weakest category every week
Communitiesr/bugbounty · Bugcrowd & HackerOne community forums · infosec Discord servers
Programs to start onAny public Vulnerability Disclosure Program (VDP) before applying anywhere invite-only
🎯
You're ready for your first real submission when: you can find at least one OWASP Top 10 bug in an unfamiliar app within 30 minutes, and write a report a stranger could reproduce without asking you a single follow-up question.
🧬

Module 5 – Advanced Vulnerability Classes

6 labs · The bug classes that separate generalists from specialists who get invited to private programs
5.1
XML External Entity (XXE) InjectionReading local files and reaching internal services through XML parsers
ObjectiveDetect and prove XXE — when an XML parser processes external entities, letting attacker-supplied XML read local files or reach internal services.PortSwigger AcademyBurp Suite
  1. Start a free XXE lab

    PortSwigger Academy's "Exploiting XXE to retrieve files" is the standard starting point.

  2. Find an XML-consuming endpoint

    Stock checkers, file import/export, and SOAP-based features are the classic locations.

  3. Submit a DOCTYPE entity payload

    Define an external entity pointing at a local file, then reference it in the document body.

  4. Check for in-band leakage

    Does the file's content come back directly in the response?

  5. Try blind (out-of-band) XXE

    If nothing comes back directly, point the entity at a server you control (e.g. Burp Collaborator) and watch for a callback.

<!-- XXE payload to read a local file -->
<?xml version="1.0"?>
<!DOCTYPE data [<!ENTITY xxe SYSTEM "file:///etc/hostname">]>
<data>&xxe;</data>
TestVulnerable If…
In-band file read payloadFile contents appear directly in the response
Out-of-band (Collaborator) payloadYou receive a DNS/HTTP callback from the target server
Parameter-entity blind XXEData exfiltrates through a secondary out-of-band channel
📋
XXE is steadily disappearing as libraries disable external entities by default — but it's still common in legacy SOAP services, PDF generators, and "import from XML" features inherited through an acquisition. Check those specifically.
5.2
Server-Side Template Injection (SSTI)Escaping a template engine through unescaped user input
ObjectiveDetect SSTI — when user input is rendered directly into a server-side template engine — and fingerprint which engine you're up against.PortSwigger AcademyBurp Suite
  1. Start a PortSwigger SSTI lab

    Free, purpose-built for this exact bug class.

  2. Identify a candidate input

    Anything reflected back unescaped into a rendered page — a "name" field used in a personalized greeting is the classic case.

  3. Send a generic math probe

    The payloads below are distinctive across the major template engine families.

  4. Fingerprint the engine

    Whichever probe evaluates tells you which engine — and therefore which exploitation path — you're dealing with.

  5. Escalate inside the lab only

    Once fingerprinted, follow the lab's own path from "it evaluates math" toward full code execution.

// generic SSTI probes — distinctive across engines
{{7*7}}        // Jinja2 / Twig: renders 49 if vulnerable
${7*7}         // FreeMarker / Velocity-style: renders 49 if vulnerable
<%= 7*7 %>     // ERB / similar engines: renders 49 if vulnerable
Engine FamilyProbeConfirms Vulnerability If…
Jinja2 / Twig{{7*7}}Response shows 49 instead of the literal text
FreeMarker / Velocity${7*7}Response shows 49
ERB-style<%= 7*7 %>Response shows 49
⚠️
SSTI can escalate all the way to remote code execution on the server. Only push past "does it evaluate math" inside a lab built for it — never on a live, unfamiliar target without explicit authorization for that exact impact level.
5.3
Insecure DeserializationRecognizing serialized objects hidden in cookies and parameters
ObjectiveUnderstand how untrusted serialized data, deserialized without validation, can lead to remote code execution — and learn to spot it by its encoding pattern.PortSwigger AcademyBurp Suite
  1. Start a PortSwigger deserialization lab

    Free, with a session-handling mechanic built around this exact bug.

  2. Find a suspicious cookie or parameter

    Look for base64 blobs, Java's rO0 magic bytes, or PHP's O:8:"ClassName" pattern.

  3. Decode it

    Inspect the underlying object structure once decoded.

  4. Modify a property

    Change a role or admin flag, then re-encode it in the original format.

  5. Resend and check trust

    Does the server trust your modified value without re-validating it?

# PHP serialized object — note the O:length:"ClassName" pattern
O:4:"User":2:{s:8:"username";s:5:"alice";s:5:"admin";b:0;}

# Java serialized objects start with this magic byte sequence (base64)
rO0AB...
SignalFormat
rO0 (base64) / 0xac 0xedJava serialized object
O:N:"ClassName"PHP serialized object
Long base64 blob in a cookieWorth decoding regardless of platform
📋
Deserialization bugs are rarely found by guessing — they're found by recognizing the encoding pattern in an otherwise unremarkable cookie or hidden field, then pulling the thread.
5.4
NoSQL InjectionWhen the backend is MongoDB instead of SQL
ObjectiveLearn how injection logic changes when the backend is a NoSQL store — the mental model carries over from SQLi, only the syntax changes.PortSwigger AcademyBurp Suite
  1. Start a PortSwigger NoSQL injection lab

    Free, built specifically around MongoDB-style query injection.

  2. Test the login form with an operator payload

    Instead of a SQL-style string, send an operator object in place of a value.

  3. Try the form-encoded variant

    If the app expects form data rather than JSON, the operator syntax changes slightly — see below.

  4. Try a $where JavaScript payload

    Some MongoDB deployments allow arbitrary JavaScript evaluation inside queries.

  5. Confirm the bypass

    Same proof standard as SQLi — are you logged in without a valid password?

// NoSQL auth bypass: send password as an operator object instead of a string
{"username": "admin", "password": {"$ne": null}}

// classic operator-based bypass in a URL-encoded form field
username=admin&password[$ne]=1
PayloadExpected If Vulnerable
{"$ne": null} in place of a string passwordLogged in without a valid password
password[$ne]=1 (form encoding)Same bypass via array-style operator injection
$where JavaScript payloadServer evaluates attacker-supplied logic server-side
💡
You're still looking for a place where user input controls query logic, not just query data — exactly like SQLi. Only the syntax changes.
5.5
GraphQL-Specific VulnerabilitiesIntrospection abuse · BOLA over GraphQL · batching attacks
ObjectiveLearn the recon and testing techniques unique to GraphQL APIs.PortSwigger AcademyBurp Suite
  1. Find the GraphQL endpoint

    Commonly /graphql, /api/graphql, or /v1/graphql.

  2. Check whether introspection is enabled

    It documents the entire schema for you, including hidden fields and mutations.

  3. Test an ID-bearing query for BOLA

    Exactly like Lab 3.2's API authorization testing, just expressed in GraphQL syntax.

  4. Test query batching

    GraphQL allows multiple queries in a single request — check whether this lets you bypass a per-request rate limit.

  5. Test for excessive data exposure

    Request every field a query allows and see if it returns more than the UI ever displays.

# introspection query — dumps the entire schema if enabled
{ __schema { types { name fields { name } } } }
TestVulnerable If…
Introspection queryReturns the full schema instead of being disabled in production
ID-bearing query/mutationReturns another user's data (GraphQL BOLA)
Batched queries in one requestBypasses a per-request rate limit
Full-field queryReturns internal fields never shown in the UI
📋
Introspection left enabled in production isn't a bug by itself, but it hands you the entire attack-surface map for free. Always pull it first on any GraphQL target.
5.6
Subdomain Takeover & HTTP Request SmugglingClaiming abandoned cloud resources · front-end/back-end desync
ObjectiveLearn two distinct infrastructure-level bugs: claiming an abandoned cloud resource, and exploiting how front-end and back-end servers disagree about request boundaries.CLI ToolsPortSwigger Academy
  1. Revisit your Module 1 subdomain list

    On a domain you own, check each subdomain's DNS record for a CNAME pointing to an external service.

  2. Visit each candidate subdomain

    Look for a "no such bucket/app" style error instead of real content — a sign the underlying resource was deleted but the DNS record never was.

  3. Confirm against a known fingerprint list

    Public "can-i-take-over-xyz" style references document the exact error text each cloud provider returns for an unclaimed resource.

  4. On your own infrastructure only

    If confirmed, you could register the resource yourself to verify the takeover — then immediately release it and fix the DNS record.

  1. Start a PortSwigger request smuggling lab

    Free, and the safest place to ever attempt this technique.

  2. Send conflicting length headers

    The classic CL.TE desync sends both Content-Length and Transfer-Encoding, disagreeing about where the request ends.

  3. Observe the desync

    Does the front-end and back-end server disagree, letting a hidden second request "ride along"?

  4. Confirm impact via the lab's indicator

    Usually capturing another (simulated) user's request.

-- DNS check: does this subdomain's CNAME point somewhere now abandoned?
dig CNAME forgotten.yourdomain.com

// classic CL.TE request smuggling headers — practice inside a lab only
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED
BugConfirms Vulnerable
Subdomain takeoverCNAME points to a deleted/unclaimed resource, matching a known "not found" fingerprint
Request smugglingFront-end/back-end disagree on request length, letting a second hidden request ride along
📱

Module 6 – Mobile App Testing

5 labs · Android-focused, hands-on — the same playbook, a different runtime
6.1
Mobile Testing Fundamentals & Lab SetupMobSF · Frida · Objection · vulnerable practice apps
ObjectiveSet up an Android testing environment and pull in the intentionally vulnerable practice apps you'll use for this module.Mobile Toolkit
  1. Install Android Studio or platform-tools

    Gets you adb and an emulator — or use a personal Android device with USB debugging enabled.

  2. Install MobSF

    Free, automated static and dynamic analysis for APKs, via Docker.

  3. Install Frida and Objection

    Your dynamic instrumentation toolkit for later labs in this module.

  4. Download practice apps

    OWASP MASTG Crackmes, DIVA — Damn Insecure and Vulnerable App (github.com/payatu/diva-android), and InsecureBankv2 (github.com/dineshshetty/Android-InsecureBankv2) — all free, open-source, built specifically to be hacked.

  5. Install one and confirm it launches

    Side-load a practice APK onto your emulator/device via adb.

# pull MobSF via Docker
docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest

# install Frida + Objection for dynamic instrumentation
pip install frida-tools objection

# install a practice APK on a connected device/emulator
adb install diva-beta.apk
CheckExpected Result
localhost:8000MobSF upload UI loads in browser
frida-ps -ULists running processes on the connected device
adb devicesShows your device as "device", not "unauthorized"
Practice app installedAppears in the app drawer and launches normally
📋
Android is the practical starting point for almost every mobile hunter — no jailbreak required, and you can sideload any APK on an emulator or your own test device. MobSF's default login is mobsf / mobsf — change it before exposing the container beyond your own machine.
⚠️
Running Kali inside VMware? Don't try to run the Android emulator inside this same VM — see the "Optimized For Kali Linux" box near the top of this workbook for why, and the two ways around it.
6.2
Static Analysis — Decompiling & Reading an APKjadx · apktool · manifest review · hardcoded secrets
ObjectivePull an APK apart and read its manifest and source for hardcoded secrets, exported components, and obvious gaps.Mobile Toolkit
  1. Decompile with jadx

    Get readable Java/Kotlin-like source from the compiled bytecode.

  2. Unpack with apktool

    Get AndroidManifest.xml and resources in near-original form.

  3. Read the manifest

    Look for exported="true" on Activities, Services, or Broadcast Receivers — these can potentially be launched by any other app on the device.

  4. Grep the decompiled source for secrets

    API keys, hardcoded credentials, encryption keys committed straight into the code.

  5. Run MobSF for a first pass

    Then compare its automated findings against what you found manually.

# decompile to readable source
jadx -d output_folder diva-beta.apk

# unpack manifest & resources
apktool d diva-beta.apk

# grep for common hardcoded-secret patterns
grep -rniE "api[_-]?key|secret|password\s*=" output_folder/
SignalWhat It Means
exported="true", no permission setAny app on the device may launch that component
Hardcoded API key/credentialA secret an attacker gets for free by decompiling
android:debuggable="true"Debugging enabled in production — should never happen
MobSF "High" severity findingWorth manually confirming, not just trusting the scanner
💡
MobSF gives you a fast first pass; manual review of the manifest and a secrets grep is what actually finds the unique, reportable bug a scanner's generic ruleset misses.
6.3
Insecure Data StorageSharedPreferences · SQLite · external storage
ObjectiveCheck whether sensitive data is stored in plaintext anywhere on the device's filesystem.Mobile Toolkit
  1. Use the app normally

    Log in and enter sensitive test data — never real personal information.

  2. Pull the app's data directory

    Requires a rooted device/emulator — or use adb backup on a non-rooted one.

  3. Inspect SharedPreferences

    Look through the XML files for plaintext credentials or tokens.

  4. Inspect any SQLite databases

    Open with a SQLite browser and search sensitive columns.

  5. Check external/shared storage

    Data written there is readable by any other app with storage permission.

# pull the app's private data directory (rooted device/emulator)
adb shell "run-as jakhar.aseem.diva cat /data/data/jakhar.aseem.diva/shared_prefs/diva_prefs.xml"

# or, on a non-rooted device, use a full backup
adb backup -f backup.ab jakhar.aseem.diva
LocationVulnerable If…
SharedPreferences XMLStores a password, token, or PII as plaintext
SQLite databaseSensitive columns are unencrypted
External/shared storageSensitive data is readable by any app with storage permission
App-switcher cached screenshotA login screen's contents are recoverable from a cached snapshot
⚠️
This lab needs a rooted emulator or test device to fully inspect /data/data/. Never root a personal device that holds your real accounts just for this lab — use a disposable emulator image.
6.4
Traffic Interception & Pinning BypassRouting app traffic through Burp · bypassing certificate pinning at runtime
ObjectiveRoute a mobile app's traffic through Burp Suite, and bypass certificate pinning when the app tries to block you.Mobile ToolkitBurp Suite
  1. Set the device's Wi-Fi proxy

    Point it at Burp listening on your machine.

  2. Install Burp's CA certificate

    As a trusted user certificate (or system, on rooted devices).

  3. Browse the app and check Burp

    Requests should appear in HTTP history, exactly like a web app.

  4. Notice if traffic doesn't appear

    A connection error or missing requests usually means certificate pinning — the app only trusts its own hardcoded certificate.

  5. Bypass pinning with Objection

    Attach to the running app and disable the pinning check at runtime, with no APK modification needed.

  6. Confirm traffic now appears

    Retry the same action and check Burp's HTTP history again.

# attach Objection to a running app and bypass SSL pinning
objection -g jakhar.aseem.diva explore
# inside the objection shell:
android sslpinning disable
CheckExpected Result
Proxy set, CA installedHTTPS requests appear in Burp with no errors
App fails to load data with proxy onLikely certificate pinning in play
sslpinning disable, then retryRequests now appear in Burp's HTTP history
📋
Once pinning is bypassed, every technique from Modules 2–3 — IDOR, injection, BOLA, business logic — applies directly to the app's API calls. Mobile testing is mostly "get the traffic into Burp," then the same playbook.
6.5
Android Component VulnerabilitiesExported components · intents · deep links
ObjectiveTest exported Activities, Services, Broadcast Receivers, and deep links for unauthorized access into the app.Mobile Toolkit
  1. List exported components

    From your Lab 6.2 manifest review.

  2. Launch an exported Activity directly

    Via adb, bypassing the app's normal login/navigation flow.

  3. Test deep links

    If the app registers a custom URL scheme, craft a link that jumps straight to a sensitive screen.

  4. Test exported Broadcast Receivers

    Send a crafted broadcast and observe whether the app reacts to it from an untrusted source.

  5. Document the exact path

    Which component, which intent, what unauthorized action resulted.

# launch an exported activity directly, skipping login
# (use the real package/activity names from your own Lab 6.2 manifest review)
adb shell am start -n com.android.insecurebankv2/.PostLogin

# trigger a custom URL scheme deep link
adb shell am start -a android.intent.action.VIEW -d "divabank://transfer?amount=1000"
TestVulnerable If…
Direct launch of exported ActivityReaches a post-login screen without authenticating
Crafted deep linkTriggers a sensitive action outside the normal in-app flow
Crafted broadcast intentApp performs an action it should only trust from itself
📱
What about iOS? Static analysis transfers directly — decompiling an IPA, reading Info.plist for App Transport Security exceptions, and checking strings for hardcoded secrets all work without a jailbreak. Full dynamic testing (Frida-based pinning bypass, runtime manipulation) generally requires a jailbroken device or a cloud service like Corellium. Treat iOS as "this module, static-only" until you have access to one.
🔬

Module 7 – Source-Assisted Hunting

4 labs · When you can read the code instead of only guessing at it
7.1
Why Source Changes EverythingWhere legitimate hunters actually get source access
ObjectiveUnderstand when and why source access changes your strategy, and where you legitimately get it.
Access TypeExample
Program explicitly shares sourceWhitebox/internal engagements, some private programs
OSS bounty programsPrograms covering open-source projects directly
Exposed source maps.map files left enabled on a production JS bundle
Public company repoA company's own open-source libraries/SDKs on GitHub

The core shift: black-box, you guess where a bug might be. White-box, you can grep for it directly — then confirm it the same way you always have.

  1. Clone Juice Shop's own GitHub repo

    At github.com/juice-shop/juice-shop — the exact source of the app you've been testing black-box since Module 0.

  2. Find the code behind a bug you already found

    E.g. the SQL injection login bypass from Lab 2.2.

  3. Compare what reading taught you vs. testing blind

    Note specifically what the source revealed that probing alone never would have.

💡
Re-reading the source behind a bug you already found black-box is one of the fastest ways to build the instinct for what source-assisted hunting actually adds.
7.2
Reading Code For Vulnerable PatternsThe dangerous function names worth grepping for first
ObjectiveLearn the small set of patterns worth searching for first in any codebase.Source Tools
  1. Grep for string-concatenated SQL

    A classic injection pattern, in your cloned Juice Shop repo.

  2. Grep for innerHTML / eval / unsanitized template literals

    Classic XSS or code-injection sinks.

  3. Grep for child_process.exec-style calls

    Command injection candidates if user input reaches them.

  4. Trace each hit backward

    Does user-controlled input actually reach this sink, or is it hardcoded/sanitized?

  5. Confirm one hit live

    Against your running Juice Shop instance — full circle from source to working proof.

# grep for classic vulnerable patterns across a cloned repo
grep -rn "innerHTML" --include=*.ts src/
grep -rn "child_process" --include=*.js routes/
grep -rnE "SELECT .* \+ |query\(.*\+" --include=*.ts src/
PatternRisk If Reachable By User Input
String-concatenated SQLSQL injection
innerHTML / eval / unsanitized template literalXSS or code injection
child_process.exec / os.systemCommand injection
Unvalidated deserialization of request bodyInsecure deserialization (see Lab 5.3)
⚠️
A grep hit is a lead, not a finding. Always trace whether user input genuinely reaches the dangerous sink before reporting — most hits in a mature codebase are already sanitized upstream.
7.3
Automated & Historical Code ReviewSemgrep at scale · mining git history for leaked secrets
ObjectiveScale code review with static analysis, and check whether secrets removed from current code are still sitting in git history.Source Tools
  1. Install Semgrep

    A fast, rule-based static analysis tool with public security rulesets.

  2. Run a public ruleset against your cloned repo

    Covers hundreds of known vulnerable patterns in seconds.

  3. Triage the output

    Separate genuine findings from noise — the same instinct as Lab 7.2's manual grep, just at scale.

  4. Install gitleaks or trufflehog

    Tools built specifically to scan full commit history for secrets.

  5. Scan the full history, not just current files

    A secret deleted in a later commit is still recoverable from history unless the repo was rewritten.

# run Semgrep's public security ruleset against a cloned repo
semgrep --config p/security-audit .

# scan full git history for leaked secrets, not just current files
gitleaks detect --source . --log-opts="--all"
ToolWhat It Catches That Manual Grep Doesn't
SemgrepHundreds of known vulnerable patterns across many languages in seconds
gitleaks / trufflehogSecrets committed and later deleted, still present in full git history
📋
A surprising number of real bounty submissions are simply "I found your AWS key in a commit from 14 months ago that's still in your git history." Always scan history, not just the current branch tip.
7.4
Dependency & Supply Chain ReviewWhen the vulnerability isn't in the app's own code at all
ObjectiveCheck whether a project's dependencies — not its own code — are the actual source of a vulnerability.Source Tools
  1. Run a dependency audit

    Against the project's manifest file.

  2. Review each flagged package

    Is the vulnerable code path actually reachable by the app, or just present but unused?

  3. Check the advisory for the fixed version

    This becomes your report's remediation advice.

  4. Treat it as a complete finding

    "You're running version X of library Y with known CVE-Z" is a valid, reportable bug on its own.

# Node.js projects
npm audit

# Python projects
pip-audit
ResultWhat To Do
High/Critical severity flaggedCheck if the vulnerable function is actually called by the app
Fix available in a newer versionNote the exact version gap for your report's remediation section
Vulnerable code path not reachableStill worth a lower-severity note — some programs still reward it
💡
You don't need to find a single line of original code to file a legitimate report — a known-vulnerable dependency, confirmed reachable, is a complete finding by itself.
🎓

Module 8 – Career & Portfolio

4 labs · Turning skill into a sustainable practice, a portfolio, and a long-term plan
8.1
Building A Public PortfolioWhat to publish, where, and what never to publish without permission
ObjectiveDecide what to publish and how it should look to someone reviewing your work for a program invite or a job.
  1. Start a simple write-up home

    A personal site, a blogging platform, or even a structured GitHub repo of markdown write-ups — the platform matters far less than consistency.

  2. Write up every lab capstone and CTF you complete

    Using this workbook's report format from Module 4. These are 100% safe to publish — your own work, on sanctioned practice targets.

  3. Never publish a real finding without explicit permission

    Not even after it's fixed. Check the program's disclosure policy every single time.

  4. Keep every write-up to one structure

    Target/lab name, vulnerability class, your approach, the fix.

  5. Link it from your platform profile

    This is exactly what triagers and program managers check before private invites.

Safe To PublishNever Without Explicit Permission
Your own lab/CTF write-ups (Juice Shop, PortSwigger, HTB, etc.)Any real program's vulnerability, even after it's resolved
General technique explainers (how IDOR works, in the abstract)Specific details identifying a real, unfixed target
Your own tools/scriptsA program's internal information learned incidentally during testing
8.2
CTFs As Deliberate PracticeDrilling your weakest category on purpose, not playing at random
ObjectiveUse Capture The Flag competitions to deliberately target specific weak spots.
  1. Pick a platform matched to your level

    picoCTF for fundamentals, TryHackMe or HackTheBox for web-focused rooms, live competitions for speed under pressure.

  2. Revisit your Lab 3.3 capstone scorecard

    Identify your weakest category.

  3. Search specifically for that category

    Don't just play whatever's trending — target the gap.

  4. Time-box each attempt

    Then read the official write-up after, win or lose — that's often where the real learning happens.

  5. Keep a running log

    Challenge, category, solved/unsolved, what you'd do differently.

PlatformBest For
picoCTFAbsolute fundamentals, beginner-friendly, free
TryHackMeStructured, guided rooms across many categories
HackTheBoxLess hand-holding, closer to real-world conditions
Live competitive CTFsSpeed, pressure, and networking with other hunters
💡
A CTF win doesn't translate directly into bounty income, but the muscle memory for vulnerability classes absolutely does — and it's a deliberate way to drill exactly the category your capstone scorecard flagged as weak.
8.3
Certifications & Structured Learning PathsWhat each one signals, and whether it's worth the cost right now
ObjectiveUnderstand what each common certification actually signals, and whether it's worth pursuing for where you are right now.
CertificationSignalsWorth It If…
eJPTFoundational pentest knowledge, entry-levelYou want a credential before any real-world experience
eWPTWeb app pentest focus, closely matches this workbookYou want web-specific credibility cheaply
OSCPHands-on offensive security, broadly respectedYou're aiming at pentest/red-team jobs, not just bounty income
CRTO / OSEPAdvanced, red-team specificYou're already employed in offensive security and going deeper
None — pure bounty trackPublic reputation, no certificationYour goal is bounty income itself, not a job requiring a credential
  1. Decide your actual goal first

    A job that requires a credential on paper, or pure bounty income, which cares only about results.

  2. If bounty income is the goal

    The free path — this workbook, PortSwigger Academy, CTFs, and real programs — is sufficient on its own.

  3. If a job is the goal

    Check three real job listings you'd actually apply to and match the certification to what they ask for — don't guess.

📋
Certifications are a job-market signal, not a bounty-hunting requirement. Plenty of top-earning hunters hold none at all — their platform profile is the only credential that matters there.
8.4
Building Your Network & Long-Term Growth PlanA sustainable cadence instead of a one-month burnout
ObjectiveSet a sustainable, long-term review cadence instead of burning out in the first month.
  1. Join one community properly

    Rather than five superficially — a specific Discord server, r/bugbounty, or a local security meetup.

  2. Follow hunters in your weak categories

    Engage with a handful who write specifically about the areas your capstone scorecard flagged.

  3. Set a quarterly review, not a daily one

    Track submissions, acceptance rate, and your best-performing category, then bias next quarter toward it.

  4. Attend one in-person event a year if possible

    A local BSides conference is inexpensive and the single best way to turn online contacts into real opportunities.

  5. Revisit Module 0's ethics rules yearly

    The fundamentals don't change, but it's easy to drift as confidence grows.

CadenceWhat To Review
WeeklyDid I submit anything? Did I read 1–2 disclosed reports outside my comfort zone?
QuarterlyAcceptance rate, best-performing category, one skill gap to target next
YearlyRe-read program policies you actively test, refresh your portfolio, reassess certification needs
🎯
You've completed this workbook's full arc when: you can take an unfamiliar authorized target, run your own version of the Module 3 capstone process against it, write a report a stranger could reproduce, and know exactly where to look next when you get stuck.
🧰

Appendix A – Quick Reference

Every tool, target, and resource from Modules 0–8, in one place
CategoryTool / ResourceUsed InOn Kali
Proxy & InterceptionBurp Suite Community Edition — portswigger.net/burp/communitydownloadModules 0, 1, 2, 3, 5, 6Pre-installed
Reconsubfinder, amass, crt.sh, ffuf / gobusterModule 1apt install
MobileMobSF, Frida, Objection, jadx, apktoolModule 6apt + pip install
Source AnalysisSemgrep, gitleaks / trufflehog, npm audit, pip-auditModule 7apt + pip install
Practice TargetsOWASP Juice Shop — github.com/juice-shop/juice-shop · PortSwigger Web Security Academy — portswigger.net/web-security · DIVA — github.com/payatu/diva-android · InsecureBankv2 — github.com/dineshshetty/Android-InsecureBankv2Modules 0–7Clone/download
Free TrainingPortSwigger Academy · Bugcrowd University · TryHackMe · picoCTF · HackTheBoxModules 0, 8Browser-based
Bug Bounty PlatformsHackerOne · Bugcrowd · Intigriti · YesWeHack · SynackModules 0, 4, 8Browser-based
Communitiesr/bugbounty · platform community forums · local BSides conferencesModule 8
📚

Appendix B – Glossary

Every acronym used in this workbook, defined once
TermDefinition
BOLABroken Object Level Authorization — an endpoint returns or modifies another user's data because it never checks whether the requester actually owns that object
CSRFCross-Site Request Forgery — tricking a logged-in victim's browser into submitting a request they never intended to send
CVSSCommon Vulnerability Scoring System — a standardized 0–10 scale used to rate how severe a finding is
IDORInsecure Direct Object Reference — changing an ID in a request to access another user's data
PoCProof of Concept — the minimum evidence (screenshot, request/response, short script) that proves a vulnerability is real
Safe HarborA program's promise not to pursue legal action against researchers who test strictly within its published scope and rules
ScopeThe exact list of assets, vulnerability types, and rules a program has authorized you to test
SSRFServer-Side Request Forgery — tricking the server itself into making a request to an address you chose, often an internal one
SSTIServer-Side Template Injection — user input escapes a template engine and gets evaluated as code on the server
TriageA program's review process confirming whether a report is valid, a duplicate, or not applicable
VDPVulnerability Disclosure Program — accepts and fixes reports but does not pay a bounty
XXEXML External Entity injection — an XML parser follows an attacker-defined external entity, often reading local files