{"slug": "we-caught-a-sql-injection-with-an-offline-ai-security-scanner-here-s-the-exact", "title": "We caught a SQL injection with an offline AI security scanner — here's the exact query it found", "summary": "Sendwave Hub's AI Security Studio, an offline security research platform, detected a classic SQL injection vulnerability in a demo Express app's login endpoint. The platform's deterministic parser and rule engine identified the flaw, with a local LLM explaining the evidence without accessing raw source code or network traffic. The finding, marked as high risk with CWE-89 and CWE-306, demonstrates the tool's ability to run fully offline and provide precise, evidence-based results.", "body_md": "Here's a login endpoint from a small Express demo app\n\n([ scan-target-demo-apps/apps/01-sql-injection](https://github.com/sendwavehub/scan-target-demo-apps)):\n\n``` js\napp.post('/login', (req, res) => {\n  const { username = '', password = '' } = req.body;\n  const query = `SELECT id, username, email, is_admin FROM users\n                  WHERE username = '${username}' AND password = '${password}'`;\n  const result = db.exec(query);\n  // ...\n});\n```\n\nYou've seen this shape before. `username`\n\nand `password`\n\ngo straight into the SQL string — no\n\nparameter binding, no escaping. Submit `admin' --`\n\nas the username and anything as the password,\n\nand the query becomes:\n\n```\nSELECT id, username, email, is_admin FROM users\nWHERE username = 'admin' -- ' AND password = 'anything'\n```\n\n`--`\n\ncomments out the rest of the line. The password check never runs. `{\"ok\": true}`\n\n, logged in\n\nas `admin`\n\n.\n\nClassic CWE-89, OWASP A03:2021. Nothing novel here — the interesting part is what caught it.\n\nWe ran this target through **AI Security Studio**, an offline security research platform we've\n\nbeen building. No cloud calls, no code leaves the machine — everything you're about to read\n\nhappened on a laptop with no network access to anywhere but `localhost:3001`\n\n.\n\nThe important design decision: **the LLM never sees raw source code or raw HTTP traffic.**\n\nThe pipeline looks like this:\n\n```\nParser → Rule Engine → Knowledge Retrieval → Summarization → LLM → Reasoning → Finding → Report\n```\n\nA deterministic parser and rule engine do the actual *finding*. The local LLM only explains\n\n*already-discovered* evidence — it's not asked to eyeball a codebase and guess where the bugs\n\nmight be. If the evidence isn't there, the platform is built to say \"Needs Manual Verification\"\n\ninstead of inventing a conclusion.\n\nFor this run, that meant:\n\n`http://localhost:3001`\n\nas scope.`server.js:56`\n\nand the missing\nauth check on the state-changing `POST /login`\n\nroute.The generated report includes the actual vulnerable line as evidence, not a generic \"possible SQL\n\ninjection\" label:\n\n``` js\nSource preview.\n  app.post('/login', (req, res) => {\n    const { username = '', password = '' } = req.body;\n    const query = `SELECT id, username, email, is_admin FROM users WHERE username = '${username}' AND password = '${password}'`;\n```\n\nRisk: High. Root cause: CWE-89 (and a separate CWE-306 finding for the missing authorization\n\ncheck). Suggested fix: parameterized queries. Confidence explicitly marked — some findings from\n\nthis pass are \"Confirmed,\" others are flagged \"Needs Manual Verification\" rather than asserted,\n\nbecause header/config-level evidence alone doesn't prove exploitability the way a manual\n\nActive Test / Repeater run does.\n\nIt's easy to gloss over \"runs locally\" as a checkbox feature. In practice it means:\n\nThe demo app is intentionally vulnerable and open source — safe to point any scanner at, including\n\nthis one:\n\nBuilt for security researchers, pentesters, and AppSec teams doing work they're authorized to do.\n\nNext up in this series: stored XSS — one comment field, every visitor who loads the page.", "url": "https://wpnews.pro/news/we-caught-a-sql-injection-with-an-offline-ai-security-scanner-here-s-the-exact", "canonical_source": "https://dev.to/jomynn/we-caught-a-sql-injection-with-an-offline-ai-security-scanner-heres-the-exact-query-it-found-4187", "published_at": "2026-08-20 13:57:45+00:00", "updated_at": "2026-08-20 14:16:29.275949+00:00", "lang": "en", "topics": ["ai-tools", "ai-safety", "developer-tools"], "entities": ["AI Security Studio", "Sendwave Hub", "Express", "CWE-89", "CWE-306", "OWASP"], "alternates": {"html": "https://wpnews.pro/news/we-caught-a-sql-injection-with-an-offline-ai-security-scanner-here-s-the-exact", "markdown": "https://wpnews.pro/news/we-caught-a-sql-injection-with-an-offline-ai-security-scanner-here-s-the-exact.md", "text": "https://wpnews.pro/news/we-caught-a-sql-injection-with-an-offline-ai-security-scanner-here-s-the-exact.txt", "jsonld": "https://wpnews.pro/news/we-caught-a-sql-injection-with-an-offline-ai-security-scanner-here-s-the-exact.jsonld"}}