English | Русский
WebSec SQL Injection is an educational backend security lab built with Node.js + Express + SQLite, demonstrating SQL Injection and a secure implementation of the same API workflow.
The project deliberately provides two endpoints:
- vulnerable — constructs SQL queries through string concatenation;
- secure — uses parameterized queries, allowlist validation, and response filtering.
The vulnerable endpoint exists exclusively for local learning and testing. This project is not a guide to attacking real systems.
- SQL Injection through unsafe string concatenation;
- the
OR 1=1scenario in an isolated demo API; - UNION-based data exposure in a training database;
- parameterized queries as the primary defense;
- allowlist validation of user input;
- excluding the
passwordfield from secure API responses; - logging suspicious search events;
- a consistent JSON error format;
- OpenAPI, Postman, automated tests, and GitHub Actions CI.
- Node.js
- Express
- SQLite
- JavaScript
- Node.js Test Runner
- OpenAPI
- Postman
- GitHub Actions
websec-sql-injection/
├── src/
│ ├── routes/
│ ├── middleware/
│ ├── services/
│ ├── data/
│ └── utils/
├── tests/
├── docs/
├── postman/
├── .github/workflows/ci.yml
├── .env.example
├── package.json
└── README.md
Local setup requires Node.js 22.5+ (the project uses the built-in
node:sqlite module). The recommended, tested version is 24.15.0, recorded in
.nvmrc. With nvm: nvm install 24.15.0, then nvm use 24.15.0.
Check node --version before npm ci: Node 20 is not supported.
Run the commands from the repository root. In PowerShell, copy the environment file
with Copy-Item .env.example .env.
git clone https://github.com/nikamurkaa/websec-sql-injection.git
cd websec-sql-injection
npm ci
npm startDefault API address:
http://localhost:3000
Stop the server with Ctrl+C.
| Method | Endpoint | Purpose |
|---|---|---|
GET |
/health |
Health check |
GET |
/search/vulnerable?username=... |
Deliberately vulnerable search |
GET |
/search/secure?username=... |
Secure search |
GET |
/security-events |
Search/security event log |
The unsafe approach:
SELECT ... WHERE username = '<user input>'
where <user input> is concatenated into the SQL statement.
The secure endpoint uses a parameterized query, passing the user value separately from the SQL template. It also applies allowlist validation and response filtering.
| Risk | Secure endpoint protection |
|---|---|
| SQL Injection | parameterized query |
| Unrestricted input | allowlist username validation |
| Sensitive data exposure | password field excluded from responses |
| Suspicious activity | security event logging |
See docs/security-model.md for details.
The demonstration SQL Injection payload succeeds against the deliberately unsafe endpoint. The API returns multiple records instead of a single user.
The same input is blocked by the secure endpoint through validation and safe SQL parameter handling.
Suspicious and blocked requests are recorded in the security event log.
The complete set of local test scenarios is available in docs/manual-checks.md.
npm test
npm run checkTests compare vulnerable and secure endpoint behavior and verify validation, response filtering, and security logging.
OpenAPI: docs/openapi.yaml.
Postman: postman/.
Completed as an educational lab on SQL Injection, secure query construction, and API hardening.


