Skip to content
  1. registrationnow
  2. live
  3. results

Getting Started

How to Play

New to the competition? Here's everything you need to get from a GitHub sign-in to your first points.

Secure Development

The loop

find the flaw → patch it → open a PR → CI scores it

There are no flags to submit. Every challenge is scored by an automated regression test that only passes once the vulnerability is actually fixed.

Please use AI

Solving these with an AI agent is the intended path, not a loophole. Bring whatever you already use and let it read the target. The fastest way to get a useful result is OWASP’s own Secure Agent Playbook: structured, OWASP-grounded procedures for security code review, dependency and secrets scanning, and API assessment, mapped to the same Top 10 categories these challenges are graded against. Point it at your fork before you start reading files by hand.

  1. 1

    Sign in with GitHub

    Use the sign-in button in the header. Your GitHub login is how the leaderboard and your profile track your progress. The scorer credits points to the account that authors the pull request, so play from the same account you sign in with.

  2. 2

    Join a team, or play solo

    Scoring is per team. From your profile: create a team, join one by code or invite link, or hit Play solo for a one-click team of one. Do it before you patch — your PRs are scored either way, but points earned while you're on no team count toward no team's total.

  3. 3

    Pick a target and a challenge

    Browse the 6 vulnerable apps on the Challenges page: Juice Shop, DVWA, WebGoat, Security Shepherd, VulnerableApp, and VAmPI. Each has dozens of independent challenges at different difficulty levels; pick any one to start.

  4. 4

    Find the vulnerability

    Work the target like a real audit: read the source, exercise the app, and identify the OWASP Top 10 flaw behind the challenge. Please use AI here. Point an agent at the codebase and have it do the analysis and draft the remediation. That's the intended workflow, not a shortcut around it.

  5. 5

    Patch it and open a pull request

    Fork the target's repo under the kavacon-ctf-2026 org, fix the vulnerability on a branch in your fork, and open a PR back against the repo's ctf branch. This is secure development practice, not flag hunting. The fix itself is the deliverable.

  6. 6

    Get scored automatically

    A GitHub Action builds your patched app and runs the full regression suite against it. Every passing challenge test scores its points automatically: no manual grading, no waiting on an organizer. Points post once the event receives the result, usually a few minutes after the push. Pushing more fixes to the same PR re-scores it.

Worked example

Your first patch, end to end

Here’s the whole loop on a real challenge: Login Admin in Juice Shop, a classic SQL injection. Follow it verbatim to land your first points and see exactly what a scoring run looks like, then repeat the pattern on every other challenge.

  1. 1

    Fork the target and clone your fork

    Fork kavacon-ctf-2026/juice-shop on GitHub (or with the gh CLI), then clone it. The default branch is the one the scorer watches.

    gh repo fork kavacon-ctf-2026/juice-shop --clone
    cd juice-shop
  2. 2

    Create a branch for your fix

    One branch per fix keeps your PRs clean and easy to re-score.

    git checkout -b fix/login-sql-injection
  3. 3

    Find the flaw

    The Login Admin challenge (A05: Injection) lives in routes/login.ts. User input is concatenated straight into the SQL string, so an email like ' OR 1=1-- logs in as the first user in the table: the admin.

    // routes/login.ts: the vulnerable query
    models.sequelize.query(
      `SELECT * FROM Users WHERE email = '${req.body.email || ''}'
        AND password = '${security.hash(req.body.password || '')}'
        AND deletedAt IS NULL`,
      { model: UserModel, plain: true }
    )
  4. 4

    Patch it

    Replace string interpolation with bind parameters. The database driver now treats the email and password strictly as data, so they can never rewrite the query itself.

    // routes/login.ts: parameterized fix
    models.sequelize.query(
      'SELECT * FROM Users WHERE email = $1 AND password = $2 AND deletedAt IS NULL',
      {
        model: UserModel,
        plain: true,
        bind: [req.body.email || '', security.hash(req.body.password || '')]
      }
    )
  5. 5

    Commit and push to your fork

    Write the commit message like you would on a real security fix: say what was vulnerable and how the patch closes it.

    git add routes/login.ts
    git commit -m "Fix SQL injection in login route with bind parameters"
    git push -u origin fix/login-sql-injection
  6. 6

    Open the PR against ctf

    The base repo is kavacon-ctf-2026/juice-shop and the base branch is ctf. The scorer only watches that branch. The GitHub web UI's “Compare & pull request” button works too; just check the base branch.

    gh pr create --repo kavacon-ctf-2026/juice-shop --base ctf \
      --title "Fix SQL injection in login route" \
      --body "Replaced string-interpolated SQL with bind parameters."
  7. 7

    Watch the scorer do its thing

    The ctf-score Action builds your patched app, boots it in a sandbox, and runs the challenge regression suite against it. When it finishes you'll get a “🏆 CTF Patch Score” comment on the PR, and your points appear on the leaderboard and your profile moments later.

Bonus

That one-line fix doesn’t just close Login Admin. The same injection powers the Login Bender and Login Jim challenges, so a single parameterized query scores all three. Real fixes often cascade like this: patch the root cause, not the symptom.

Quiz

The loop

read the question → pick your answer → submit it → it's scored on the spot

There are no flags to submit. Every question is graded automatically against a stored answer key the moment you answer it.

  1. 1

    Sign in with GitHub

    Use the sign-in button in the header. Your GitHub login is how the leaderboard and your profile track your progress, and nothing is graded for a signed-out visitor.

  2. 2

    Join a team, or play solo

    Scoring requires a team — answers don't count until you're on one, and the quiz page sends a teamless player to their profile first. From there: create a team, join one by code or invite link, or hit Play solo for a one-click team of one.

  3. 3

    Open the question set

    Every question the organizers have published is on the Quiz page, each one showing what it is worth. Take them in any order, at your own pace, and come back to the rest later.

  4. 4

    Answer the question

    Some questions have a single right answer; others are select-all-that-apply and only score if your whole selection matches. Read carefully before you submit: a question can be capped to a limited number of attempts, and can put you on a cooldown between tries.

  5. 5

    Get scored on submit

    Your answer is graded immediately against the answer key. A correct answer scores its full points, a wrong one scores nothing, and either way there is no manual grading and no waiting on an organizer.

Jeopardy

The loop

find the flag → submit it → it's scored on the spot

Every flag is checked immediately against the answer stored for it, the moment you submit.

  1. 1

    Sign in with GitHub

    Use the sign-in button in the header. Your GitHub login is how the leaderboard and your profile track your progress, and nothing is graded for a signed-out visitor.

  2. 2

    Join a team, or play solo

    Scoring requires a team — flags don't count until you're on one, and the board sends a teamless player to their profile first. From there: create a team, join one by code or invite link, or hit Play solo for a one-click team of one.

  3. 3

    Open the board

    Every flag the organizers have published is on the Flags page, grouped by category. Each one shows what it's worth and how many people have already solved it. Work in any order, at your own pace.

  4. 4

    Find the flag

    Read the description, then do whatever it takes to turn up the flag it's pointing at. There's no fixed method — some flags live in a file, others in a running app, others in the description itself.

  5. 5

    Submit it and get scored

    Paste the flag into the box and submit. It's checked instantly: matching ignores leading or trailing whitespace, and casing too — unless the flag is marked case-sensitive, which its card tells you. There's no cap on how many times you can try, though organizers can set a short cooldown between submissions on the same flag.

AI

The loop

open the challenge → play it externally → it reports back, or you submit the flag

Every solve is checked the moment it lands — automatically when the external site reports it, or instantly against the stored flag when you submit one yourself. Either way, the box's own clock decides when it happened.

  1. 1

    Sign in with GitHub

    Use the sign-in button in the header. Your GitHub login is how the leaderboard and your profile track your progress, and it's also the identity your personal launch link carries onto the external site.

  2. 2

    Join a team, or play solo

    Scoring requires a team — a challenge doesn't count until you're on one, and the board sends a teamless player to their profile first. From there: create a team, join one by code or invite link, or hit Play solo for a one-click team of one.

  3. 3

    Open the board

    Every challenge the organizers have published is on the AI page, grouped by category. Each one shows what it's worth and how many people have already solved it. Work in any order, at your own pace.

  4. 4

    Open a challenge for your personal link

    Opening a challenge from its page mints a launch link that signs you straight into the external site as you. It's yours alone — anyone who has it plays under your name, cooldown included — and if it ever goes stale, reopening the page mints a fresh one.

  5. 5

    Play it, and let it report back or submit the flag

    Play the challenge on the external site. Most report a solve back on their own the instant you clear them; where a challenge also takes a typed flag, paste it into the box on its page and it's graded immediately. Either way, the box's own clock decides when you solved it.

Good to know

Secure Development

  • Every push to an open PR re-runs the scorer, and the run evaluates your whole app, so you can keep stacking fixes on one branch or open a fresh PR per fix, whichever you prefer.
  • Your best-ever result per challenge is what counts. A later fix always replaces an earlier miss; you can never lose points by trying.
  • Points are credited to the GitHub account that authored the PR. A challenge patched by several teammates counts once for the team, so a team's total can be less than its members' points added together.

Quiz

  • Every question carries its own point value, and says what it is worth before you answer it.
  • Organizers can cap how many times a question may be attempted and make you wait between tries. The question tells you when it is on cooldown and when you have run out of attempts.
  • Points are credited to the GitHub account you signed in with. A question answered by several teammates counts once for the team, so a team's total can be less than its members' points added together.

Jeopardy

  • Every flag carries its own point value, and shows what it's worth before you submit it, plus how many people have already solved it.
  • There's no cap on attempts. Organizers can set a short cooldown between submissions on the same flag, and the board tells you when it's still counting down.
  • Points are credited to the GitHub account you signed in with. A flag found by several teammates counts once for the team, so a team's total can be less than its members' points added together.

AI

  • Every challenge carries its own point value, and shows what it's worth before you open it, plus how many people have already solved it.
  • Your launch link is personal. Reopening the challenge page mints a fresh one, but don't hand yours to someone else: whatever they do with it happens under your name, cooldown included, and every point it earns still lands on your account.
  • Points are credited to the GitHub account your launch link named. A challenge solved by several teammates counts once for the team, so a team's total can be less than its members' points added together.

How scoring works

Secure Development

Every challenge is worth a fixed number of points based on difficulty, and harder vulnerabilities pay out more. Points post once the event receives your PR’s passing result, usually a few minutes after the push, and your best-ever result for each challenge is what counts, so a later fix always replaces an earlier miss. Your live total, per-app breakdown, and patched and non-patched counts are visible on your profile once you’re signed in.

Quiz

Every question is worth a fixed number of points, set by the organizers when they author it. Points are awarded the moment a correct answer is submitted, graded against a stored answer key, so nothing waits on manual review. Your live total is visible on your profile once you're signed in, and on the leaderboard alongside everyone else's.

Jeopardy

Every flag is worth a fixed number of points, set by whoever wrote it, and that value never changes as more people solve it. Points are awarded the instant a correct flag is submitted — leading or trailing whitespace is ignored, and casing is too unless the flag is marked case-sensitive — so nothing waits on manual review. Your live total is visible on your profile once you're signed in, and on the leaderboard alongside everyone else's.

AI

Every challenge is worth a fixed number of points, set by whoever wrote it. Points are awarded the moment your solve is recorded — automatically when the external site reports it, or instantly when a typed flag matches — so nothing waits on manual review. Your live total is visible on your profile once you're signed in, and on the leaderboard alongside everyone else's.

Stuck, or need an organizer? Find one at the Kavacon CTF 2026 By OWASP area.