Fix SQL injection in TypeScript and Next.js
===========================================

Bind every value: put ? placeholders in the SQL and pass the values to the
driver, as in db.prepare(sql).all(name, status), inside the route handler's
data layer. Never build SQL with template literals. Column names and ASC/DESC
cannot be bound, so look the requested sort up in a Map of allowed SQL
fragments and answer 400 for anything else.

Page: https://softwaresecurity.com/fix/sql-injection/typescript-nextjs/

What is in this archive
-----------------------
sql-injection/typescript-nextjs/   the project: three implementations of the same code and one test suite
  lib/impl/vulnerable.ts   (vulnerable)
  lib/impl/fixed.ts   (fixed)
  lib/impl/wrong.ts   (a plausible fix that still fails)
run-all.mjs   runs the tests in all three modes and checks the results (Node.js only)
LICENSE-CODE.txt

Run it
------
  Tested with Node.js 26.11.1 (node:sqlite needs 22.13.0 or later without a
  flag; route handlers use the default Node.js runtime); package.json allows
  Node.js ^22.23.2 || ^24.18.1 || >=26.5.1. run-all.mjs needs Node.js 22 or
  later. Supported versions: https://softwaresecurity.com/fix/versions/

  From the sql-injection/typescript-nextjs folder, install the dependencies once
  (this needs network access):

    npm ci

  Then run the tests. IMPL chooses the implementation the tests load:

    # every test passes
    IMPL=fixed npm test --silent
    # an exploit test fails
    IMPL=vulnerable npm test --silent
    # a test fails
    IMPL=wrong npm test --silent

  The JUnit report is written to reports/junit.xml. To run all three modes and
  check the results in one step, run the harness from this top folder (it needs
  only Node.js; --install runs the install step first):

    node run-all.mjs --install sql-injection/typescript-nextjs
    node run-all.mjs sql-injection/typescript-nextjs

Verified
--------
  11 October 2026 on macOS 27.0 (Darwin 27.0.0, arm64), with node 26.11.1, npm
  11.20.0, next 16.4.0, react 19.3.0, vitest 5.0.3 (Vite 8.3.4), typescript
  6.0.3, node:sqlite built in (SQLite 3.53.4), semgrep 1.180.0. Versions and
  results hold for that date: run the tests with your own versions before
  relying on the fix.

Licence
-------
  The code is MIT licensed (LICENSE-CODE.txt). The page text is CC BY 4.0.
