π Building a Scalable & Maintainable VulnerableApp Architecture
Over the last few years, while building solutions to simulate real security vulnerabilities, one thing became very clear: traditional vulnerable apps often become monolithic, hard to extend, and tightly coupled to a specific stack, limiting scalability and maintainability.
To solve this, we leaned into annotation-driven design, metadata contracts, and a distributed, modular architecture β and the results speak for themselves.
π§ 1. Annotation-Driven Vulnerability Definitions
At the core of VulnerableAppβs architecture is a set of custom annotations that drive the vulnerability model, UI, and scanner interaction.
Instead of hand-coding endpoints or UI metadata, developers annotate classes with:
@VulnerableAppRestControllerβ expose REST endpoints + UI metadata@VulnerableAppRequestMappingβ attach levels (secure/unsecure) + templates@AttackVectorβ describe exploit vectors and payloads
From this minimal metadata, the system builds UI and scanner definitions dynamically. Adding a new vulnerability is as simple as adding a class with the right annotations β no boilerplate code.
π‘ Architectural Win: Core model becomes declarative, extensible, self-documenting β huge win for scalability and onboarding.
π οΈ 2. Separation of Concerns β Backend vs UI
VulnerableApp exposes a single dynamic endpoint (/VulnerabilityDefinitions) returning metadata driven by annotations.
The UI builds itself from the contract. Every vulnerability includes names, templates, descriptions, and attack vectors.
This decoupled APIβUI contract improves maintainability and simplifies upgrades or rewrites.
π 3. Multi-Stack Support with VulnerableApp-facade
Scaling beyond Java/Spring required a multi-stack solution. Vulnerabilities exist in Python, PHP, Node, Go, and more.
VulnerableApp-facade is a gateway + orchestrator:
- Routes requests to multiple VulnerableApps based on URI patterns
- Each app provides a schema/contract β if adhered, the facade:
ββ Routes traffic
ββ Merges definitions
ββ Displays content in a shared UI shell - A generic skeleton UI reads the contract and embeds stack-specific content
This design is:
β Stack-agnostic
β Lightweight
β Easy to deploy as a distributed service farm
π‘ Architectural Win: Decouples vulnerability store + UI from stack, enabling horizontal scaling.
π Why This Matters
β¨ Declarative Metadata via Annotations β Add vulnerabilities without touching UI/infrastructure
β¨ Contract-Based Modular Architecture β Different stacks plug in seamlessly
β¨ Dynamic UI Driven from API Definitions β No hardcoded pages
β¨ Tooling-Friendly Endpoints (DAST/SAST) β Full automation and evaluation workflows
β¨ Lightweight Gateway (OpenResty + Lua) β Efficient orchestration without bloat
π‘ Final Thought
By emphasizing metadata contracts, modular services, and clear UI/backend separation, we solved scalability and cross-stack extensibility problems that traditional vulnerable apps struggle with.
If youβre building extensible systems that need to grow without pain, this pattern is highly effective.