-
-
Notifications
You must be signed in to change notification settings - Fork 735
Design doc for Challenge introduction
This document describes the planned transition from the current scanner-first experience in VulnerableApp to a dual-mode experience:
- Scanner Mode: existing behavior, unchanged.
- Challenge Mode: a guided learning mode that renders level cards with challenge text, hints, and an optional final payload.
This document is intended to be the shared implementation guide for contributors working across VulnerableApp, VulnerableApp-Facade, and the facade-schema contract.
Today, VulnerableApp is primarily consumed in scanner mode. That works well for direct vulnerability interaction, but it does not provide a guided learning flow for users who want to solve each level in a structured way.
Challenge Mode adds that missing layer without removing the existing scanner experience.
- Keep Scanner Mode fully backward compatible.
- Add Challenge Mode as an optional layer.
- Render each level as one or more challenge cards.
- Support a contract-driven model so the UI can be generated from structured data.
- Ensure the existing VulnerableApp ↔ VulnerableApp-Facade relationship remains intact.
- Allow existing vulnerable applications to continue working even if they do not yet provide challenge metadata.
- No scoring system in this phase.
- No user progress tracking in this phase.
- No gamification mechanics in this phase.
- No breaking rewrite of the current vulnerability modules.
- No requirement to migrate every module at once.
- VulnerableApp defines vulnerability modules and level behavior.
- VulnerableApp-Facade reads structured metadata and renders the UI shell.
- The UI is primarily scanner-oriented.
The current model is good for direct interaction, but it does not naturally support:
- guided challenge cards,
- progressive hints,
- an explicit challenge/scan toggle,
- or a clean contract for challenge-specific fields.
- Existing behavior remains the default.
- Existing pages and interactions continue to work.
- Existing metadata continues to render as before.
- The UI renders level cards.
- Each card exposes a challenge entry point.
- Hints are shown inside the card.
- A final payload can be shown hidden or collapsible.
- Users can move through challenges one by one.
The core design principle is:
Existing data stays valid; challenge data is additive.
This means the contract must support both:
- legacy vulnerability metadata,
- and new challenge-specific fields.
- Do not break current consumers.
- Add new fields only where needed.
- Make challenge fields optional.
- Keep a clear fallback path when challenge fields are absent.
The new contract should describe data as:
This is the new layer for Challenge Mode:
- challenge text
- hints
- optional payload
{
"name": "AuthenticationVulnerability",
"id": "AuthenticationVulnerability",
"description": "...",
"vulnerabilityTypes": [],
"levels": [
{
"levelIdentifier": "LEVEL_1",
"variant": "UNSECURE",
"resourceInformation": {
"htmlResource": {
"resourceType": "HTML",
"isAbsolute": false,
"uri": "/VulnerableApp/templates/AuthenticationVulnerability/LEVEL_1/Auth.html"
},
"staticResources": [
{
"resourceType": "CSS",
"isAbsolute": false,
"uri": "/VulnerableApp/templates/AuthenticationVulnerability/LEVEL_1/Auth.css"
},
{
"resourceType": "JAVASCRIPT",
"isAbsolute": false,
"uri": "/VulnerableApp/templates/AuthenticationVulnerability/LEVEL_1/Auth.js"
}
]
},
"challengeCards": [
{
"challengeText": "Bypass the authentication mechanism and gain access to the admin panel.",
"hints": [
{
"order": 1,
"text": "Look at how the username is validated."
},
{
"order": 2,
"text": "Check what happens when authentication fails."
}
],
"payload": {
"description": "Final exploit payload to bypass login.",
"value": "' OR 1=1 --"
}
}
]
}
]
}-
challengeCardsis optional. -
payloadis optional. - The UI must fall back to legacy rendering when
challengeCardsis not present. - A single payload may be associated with multiple hint cards.
- Hint cards are a UI grouping mechanism, not necessarily a security boundary.
VulnerableApp already uses an AttackVector annotation to describe attack guidance for vulnerability methods.
We should not force all challenge data into the existing annotation immediately. Instead, we should introduce a newer challenge annotation and let the facade resolve data in this order:
- Use new challenge-specific metadata if present.
- Otherwise fall back to the legacy
AttackVectordata.
-
AttackVectorremains the compatibility anchor. - A new annotation can provide richer challenge text and card-level hint structure.
- The facade merges or falls back depending on what is available.
Backward compatibility is a hard requirement.
- old modules without challenge data,
- old facade consumers,
- existing scanner-mode behavior,
- existing level resources and identifiers.
- If challenge data exists, Challenge Mode may render cards.
- If challenge data does not exist, Scanner Mode continues to behave exactly as today.
- Legacy modules must not fail because challenge fields are absent.
- The facade must tolerate mixed versions during migration.
- Keep the current UI intact.
- Do not require challenge cards.
- Do not hide or break existing functionality.
- Add a toggle control in the UI.
- Render challenge cards dynamically.
- Each card should contain:
- challenge text,
- hint sections,
- optional payload.
- Hints should be collapsed or progressively revealed.
- The payload should be hidden by default unless the design intentionally exposes it.
Each challenge card should be minimal and focused.
- challenge text
- one or more hint groups
- optional payload
{
"challengeText": "Extract data from the vulnerable endpoint.",
"hintCards": [
{
"hints": ["Look at the request parameters.", "Try changing the object identifier." ]
}
],
"payload": {
"description": "..."
"value": "..."
}
}This keeps the UI simple and gives contributors a consistent target.
VulnerableApp-Facade becomes the main translation layer between source annotations and UI output.
- read vulnerability metadata,
- read level resources,
- detect challenge-related metadata,
- build a card-ready model for Challenge Mode,
- preserve the existing scanner-mode contract,
- hide version-specific differences from the UI.
- embed UI logic directly,
- hardcode per-vulnerability rendering rules,
- break legacy schema consumers.
We should proceed in phases.
- Define the challenge-aware contract.
- Update facade-schema to support the new fields.
- Agree on fallback behavior.
- Add card generation.
- Add the scanner/challenge toggle handling.
- Ensure Challenge Mode only activates when challenge data is available.
- Add the same toggle and card logic to the legacy UI.
- Preserve existing scanner behavior.
- Update each vulnerability module to provide challenge metadata where appropriate.
- Start with high-value modules and the most straightforward levels.
- Keep this document updated as the contract evolves.
- Use it as the implementation reference for contributors.
The parent issue is challenge mode. The child tickets naturally split into these workstreams:
- Create contract JSON schema design.
- Update facade-schema to support the new fields.
- Update facade-schema to accept challenge text and hints.
- Update the facade package to consume the newer schema.
- Add a design doc that ties everything together.
- Add card generation to VulnerableApp-Facade.
- Add toggle support between scanner and challenge modes.
- Add the same behavior to the legacy UI.
- Authentication
- Command Injection
- JWT
- Cryptography Failures
- File Upload
- Path Traversal
- SQL Injection
- XSS
- XXE
- Open Redirect
- SSRF
- IDOR
- Clickjacking
- LDAP Injection
These modules should be migrated carefully so each one can provide challenge data without breaking its current scanner behavior.
When contributing to this effort:
- Prefer additive changes over breaking changes.
- Keep the contract optional and backward compatible.
- Keep the facade as the only transformation layer.
- Keep the UI as a pure renderer.
- Update one module or one layer at a time.
- When in doubt, preserve current scanner-mode behavior.
- Finalize the contract.
- Update facade-schema.
- Update VulnerableApp-Facade parsing and card generation.
- Add toggle behavior to the UI.
- Migrate a small number of vulnerabilities as examples.
- Roll out the rest module by module.