⚠️ WARNING: This application is INTENTIONALLY VULNERABLE. DO NOT deploy to the internet or any production environment. It is designed solely for security training, demonstrations, and testing of SAST/DAST/SCA tools.
IWA Pharmacy Direct is a deliberately insecure e-commerce web application — a Node.js/TypeScript port of the IWA-Java Spring Boot demo app by OpenText/Fortify. It is used to demonstrate and teach application security tools including:
- Fortify SAST — finds code-level vulnerabilities
- Fortify DAST — finds runtime vulnerabilities
- Fortify Software Composition Analysis (SCA) — open-source vulnerability scanning
- Fortify on Demand (FoD) — cloud-based SAST/DAST
- ScanCentral SAST/DAST — enterprise SAST/DAST scanning
All vulnerabilities are intentional and must be preserved for teaching purposes.
- Node.js 20 LTS
- npm 10+
npm install
cp .env.example .envnpm run dev
# App runs on http://localhost:8888
# React UI is served at http://localhost:8888/app/npm run build
npm start
# App runs on http://localhost:8080
# React UI is served at http://localhost:8080/app/docker-compose up
# App runs on http://localhost:8080
# React UI is served at http://localhost:8080/app/See DEPLOY.md for the Azure App Service container deployment guide.
| Username | Password | Role(s) |
|---|---|---|
| admin | Password123! | ROLE_ADMIN, ROLE_USER |
| user1 | Password123! | ROLE_USER |
| user2 | Password123! | ROLE_USER |
| api | Password123! | ROLE_API |
| test | Password123! | ROLE_TEST |
| Profile | Port |
|---|---|
| development | 8888 |
| production | 8080 |
REST API available at /api/v3/ with OpenAPI docs at /swagger-ui.
Key endpoints:
POST /api/v3/site/sign-in— Authenticate and receive JWTGET /api/v3/products— Browse productsGET /api/v3/users— User management (auth required)
The /app/assistant/setup page saves an OpenAI API key in browser localStorage for demos. The /app/assistant page reads the saved browser key and sends it to POST /api/v3/agent/chat as X-OpenAI-API-Key.
For public deployments, do not configure OPENAI_API_KEY in the container environment. This prevents visitors from using your private server-side key.
For private demos, you can still allow a shared server-side key by setting both variables in the container environment:
OPENAI_API_KEY=sk-...
ALLOW_SERVER_OPENAI_API_KEY=trueWithout ALLOW_SERVER_OPENAI_API_KEY=true, the API ignores the server environment key and requires the browser-provided key.
Because this is an intentionally vulnerable app with XSS demos, use a restricted or disposable OpenAI project key for browser setup.
Visit /app/vulnerabilities in the running app for a full list of all 27 planted vulnerabilities with reproduction steps.
Legacy browser routes redirect to their React /app/* equivalents during the frontend migration.
See DEMO.md for detailed exploitation walkthroughs.
The application UI is built with React and TypeScript from frontend/src/ into public/app/. EJS, jQuery, Bootstrap, and legacy browser plugins are no longer part of the runtime. The views/ directory is retained as historical training reference while intentionally vulnerable behaviors are preserved in the React frontend and backend routes.
# SAST
./bin/sast-scan.sh
# ScanCentral SAST
./bin/scancentral-sast-scan.sh
# FoD SAST + SCA
./bin/fod-scan.shnpm run test:e2eThe Playwright suite builds the application, starts an isolated test server on port 8890, and uses data/e2e.sqlite as its test database.
This repository is intentionally vulnerable and is out of scope for vulnerability reports. See SECURITY.md for details.
Apache-2.0 — see LICENSE.