
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
@kdinisv/sql-scanner
Advanced tools
Smart SQL injection scanner with crawler and optional Playwright capture.
Лёгкий SDK для поиска SQL-инъекций в Node.js. Умеет точечно сканировать URL и выполнять «умное» сканирование с краулингом. Работает в ESM и CommonJS, типы включены. Поддерживает отчёты JSON/Markdown/CSV/JUnit и приоритизирует payload’ы (в т.ч. time/union PoC) по отпечатку СУБД.
— Node.js >= 18.17 — Типы: TypeScript – Опционально: Playwright для JS-страниц (захват сетевых запросов SPA)
npm i @kdinisv/sql-scanner
# (опционально) для SPA-страниц
npm i -D playwright
import { SqlScanner } from "@kdinisv/sql-scanner";
const scanner = new SqlScanner();
const result = await scanner.scan({
target: "https://example.com/search?q=test",
method: "GET",
enable: { query: true, error: true, boolean: true, time: false },
});
console.log(result.vulnerable, result.details);
const { SqlScanner } = require("@kdinisv/sql-scanner");
(async () => {
const scanner = new SqlScanner();
const result = await scanner.scan({ target: "https://example.com?id=1" });
console.log(result);
})();
const smart = await scanner.smartScan({
baseUrl: "https://example.com",
maxDepth: 2,
maxPages: 50,
usePlaywright: true,
});
console.log(smart.crawledPages, smart.candidates.length, smart.sqli.length);
new SqlScanner(options?)
scan(input)
smartScan(options)
Пример:
{
"vulnerable": true,
"details": [
{
"point": { "kind": "query", "name": "q" },
"technique": "error",
"payload": "' OR '1'='1",
"vulnerable": true,
"responseMeta": { "status": 200, "len": 12345, "elapsedMs": 120 },
"evidence": "You have an error in your SQL syntax",
"confirmations": ["error_signature"],
"reproduce": {
"curl": ["curl \"https://example.com/search?q=' OR '1'='1\""]
},
"remediation": [
"Используйте параметризованные запросы/Prepared Statements",
"Не конкатенируйте пользовательский ввод в SQL"
]
}
]
}
Совет: фильтруйте details.filter(d => d.vulnerable)
для списка подтвержденных находок.
Пример:
{
"crawledPages": 12,
"candidates": [
{ "kind": "url-with-query", "url": "https://site/search?q=" },
{
"kind": "form",
"action": "https://site/login",
"method": "POST",
"fields": [{ "name": "email", "value": "" }]
}
],
"sqli": [
{
"vulnerable": false,
"details": [
{
"point": { "kind": "query", "name": "q" },
"technique": "boolean_truefalse",
"payload": "...",
"vulnerable": false
}
]
}
]
}
await scanner.scan({
target: "http://127.0.0.1:3000/rest/products/search?q=",
enable: { query: true, error: true, boolean: true, time: false },
payloads: {
error: ["'", "' OR 1=1--", "' UNION SELECT 1--"],
boolean: [{ true: "' OR 1=1--", false: "' OR 1=2--", label: "or_comment" }],
},
});
– Предварительная авторизация (форма/JSON)
await scanner.scan({
target: "https://site.local/products?id=1",
method: "GET",
auth: {
url: "https://site.local/api/login",
method: "POST",
type: "form-urlencoded", // или "json"
usernameField: "username",
passwordField: "password",
username: "admin",
password: "secret",
additionalFields: { remember: "1" },
verifyUrl: "https://site.local/",
success: { notContainsText: "Sign in" },
},
enable: { query: true, error: true, boolean: true },
});
Аналогично в smartScan:
await scanner.smartScan({
baseUrl: "https://site.local",
auth: {
url: "https://site.local/api/login",
method: "POST",
type: "json",
usernameField: "email",
passwordField: "password",
username: "admin@site.local",
password: "secret",
verifyUrl: "https://site.local/",
success: { notContainsText: "Sign in" },
},
});
await scanner.smartScan({
baseUrl: "https://example.com",
maxDepth: 2,
maxPages: 50,
techniques: { error: true, boolean: true, time: false },
});
await scanner.scan({
target: "https://example.com/search?q=1",
enable: { query: true, error: true, boolean: true, time: false },
onProgress: (p) => {
if (p.phase === "discover") {
console.log(`points=${p.points}`);
} else if (p.phase === "scan") {
console.log(
`checks ${p.processedChecks}/${p.plannedChecks}, eta=${p.etaMs}ms`
);
}
},
});
await scanner.smartScan({
baseUrl: "https://example.com",
onProgress: (p) => {
if (p.phase === "crawl") {
console.log(`crawled ${p.crawledPages}/${p.maxPages}`);
} else if (p.phase === "scan") {
console.log(
`scanned ${p.scanProcessed}/${p.scanTotal}, eta=${p.etaMs}ms`
);
}
},
});
Запуск без установки:
npx --package @kdinisv/sql-scanner sql-scan https://example.com
Глобально:
npm i -g @kdinisv/sql-scanner
sql-scan https://example.com
# отключить захват JS/SPA (без Playwright)
sql-scan https://example.com --no-js
# сохранить отчёт (Markdown/JSON/CSV/JUnit)
sql-scan https://example.com --report md --out report.md
sql-scan https://example.com --report json --out report.json
sql-scan https://example.com --report csv --out report.csv
sql-scan https://example.com --report junit --out report.xml
CLI показывает индикатор прогресса и оценку ETA в процессе.
CLI поддерживает конфигурацию через .env-файл (dotenv). Создайте .env
в корне проекта (см. .env.example
). Основные переменные:
--headed
(делает headless=false)Переменные окружения прокси HTTP_PROXY/HTTPS_PROXY/NO_PROXY также учитываются.
В репозитории есть лёгкие локальные HTTP-эмуляторы баз данных, которые имитируют поведение MySQL/PostgreSQL/MSSQL/Oracle/SQLite для техник:
Они используются в автотестах и не требуют внешних контейнеров/стендов:
tests/servers/dbEmulators.ts
tests/db-emulator.test.ts
Запуск тестов:
npm test -s
http://127.0.0.1:3128
или с авторизацией http://user:pass@proxy.local:8080
.— Приоритет пейлоадов: если error-based детект дал отпечаток СУБД (MySQL/Postgres/MSSQL/Oracle/SQLite), time-based подбор сначала пробует соответствующие пейлоады (например, pg_sleep/WAITFOR/DBMS_LOCK.SLEEP), что ускоряет и повышает точность.
— Union-based PoC: реализованы безопасные пробы ORDER BY (сравнение ответов на валидный/заведомо «лишний» индекс) и базовые UNION SELECT пейлоады. При наличии отпечатка СУБД выбираются наиболее подходящие варианты.
const result = await scanner.scan({
target: "https://api.site.local/search",
method: "POST",
jsonBody: { q: "test", page: 1 },
enable: { json: true, error: true, boolean: true, time: false },
});
// target указывает на страницу с формой; сканер сам получит HTML и извлечёт поля
const res = await scanner.scan({
target: "https://site.local/login",
enable: { form: true, error: true, boolean: true, time: false, query: false },
});
const res = await scanner.scan({
target: "https://site.local/profile?id=1",
headers: { "X-Trace": "abc" },
cookies: { session: "token" },
enable: { header: true, cookie: true, error: true, boolean: true },
});
const res = await scanner.scan({
target: "https://site.local/search?q=1",
enable: { query: true, time: true },
// Поднимите порог, если бэкенд медленный
timeThresholdMs: 3000,
});
— Встроено статистическое подтверждение (p-value) для time-based: несколько парных замеров baseline/injected, расчёт p (односторонний тест). В evidence попадают p, z, средние времена. Для шумных систем можно повысить timeThresholdMs.
// Без JS (быстрее, только HTML)
await scanner.smartScan({
baseUrl: "https://site.local",
usePlaywright: false,
crawlConcurrency: 6, // быстрее HTML-краулинг
});
// С JS (если установлен Playwright): захватывает запросы SPA
await scanner.smartScan({
baseUrl: "https://site.local",
usePlaywright: true,
playwrightMaxPages: 4, // 0 или отрицательное — без ограничения
playwrightConcurrency: 3, // несколько страниц параллельно
playwrightWaitMs: 1200, // чуть дольше ждём XHR
scanParallel: 3, // параллельно сканируем кандидатов
});
const onlyVuln = result.details.filter((d) => d.vulnerable);
const byTechnique = onlyVuln.reduce(
(acc, d) => {
acc[d.technique] = (acc[d.technique] || 0) + 1;
return acc;
},
/** @type {Record<string, number>} */ {}
);
— Готовые репорты: JSON/Markdown/CSV/JUnit
import {
toJsonReport,
toMarkdownReport,
toCsvReport,
toJUnitReport,
} from "@kdinisv/sql-scanner";
const json = toJsonReport(result);
const md = toMarkdownReport(result);
const csv = toCsvReport(result);
const junitXml = toJUnitReport(result);
// Сохраните в файл или отправьте в CI-артефакты
В отчётах теперь присутствуют примеры воспроизведения и советы по исправлению:
reproduce
с curl ...
, а также remediation
— список рекомендаций.reproduce_curl
и remediation
.<failure>
попадает тело с блоками curl:
и fix:
.const scanner = new SqlScanner({ parallel: 4, maxRequests: 500 });
const res = await scanner.scan({ target: "https://site.local/?q=1" });
// Для smartScan скорость можно настраивать:
await scanner.smartScan({
baseUrl: "https://site.local",
crawlConcurrency: 4,
playwrightConcurrency: 2,
scanParallel: 2,
});
// Экспериментальная техника: сначала ORDER BY (ok vs bad), затем UNION
const res = await scanner.scan({
target: "http://127.0.0.1:3000/search?q=1",
enable: {
query: true,
union: true,
error: false,
boolean: false,
time: false,
},
});
const unionFindings = res.details.filter((d) => d.technique === "union");
// evidence включает orderby-sim=... и/или sim(base,union)=...
Примечание: это PoC с консервативными, безопасными пейлоадами. В бою комбинируйте с error/boolean/time для повышения уверенности.
Используйте сканер только на ресурсах, для которых у вас есть разрешение.
FAQs
Smart SQL injection scanner with crawler and optional Playwright capture.
The npm package @kdinisv/sql-scanner receives a total of 147 weekly downloads. As such, @kdinisv/sql-scanner popularity was classified as not popular.
We found that @kdinisv/sql-scanner demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.