Files
BetterDesk/web-nodejs/tests/security/01-sql-injection.test.js
UNITRONIX 235c9c0706 security: implement Phase 0-3 remediation (deps, SQL ident, JWT, CSP, suite)
Bump axios/multer and npm overrides; add safeSqlIdent and multer cleanup;
harden JWT aud/iss/nbf; CSP without unsafe-eval via static protobuf build
and data-bd-call delegation; ship Security Test Suite v1.2.0 and docs.
Ignore generated RdClient protobuf artifacts (~40k lines) — rebuild locally
with npm run protocols:rdclient.

Thanks: INSOLVE (Honorary); Marco Jakobs (@jacotec); MyNameisStitch (@MyNameisStitch); Redspin (@playerumpknow); muopc (@muopc)
2026-10-17 15:33:48 +02:00

59 lines
2.2 KiB
JavaScript

'use strict';
const request = require('supertest');
const { createTestApp } = require('./helpers');
const { escapeHtml } = require('../../lib/escapeHtml');
const { SQLI, SAFE_SQL_IDENT, MALICIOUS_SQL_IDENT, SAFE_IDENT_RE } = require('./payloads');
const { assertSafeSqlIdent, isSafeSqlIdent, SAFE_SQL_IDENT_RE } = require('../../lib/safeSqlIdent');
describe('[sec/01] SQL injection', () => {
it('assertSafeSqlIdent accepts catalog names and rejects malicious identifiers', () => {
expect(SAFE_SQL_IDENT_RE.source).toBe(SAFE_IDENT_RE.source);
for (const name of SAFE_SQL_IDENT) {
expect(assertSafeSqlIdent(name)).toBe(name);
expect(isSafeSqlIdent(name)).toBe(true);
}
for (const name of MALICIOUS_SQL_IDENT) {
expect(isSafeSqlIdent(name)).toBe(false);
expect(() => assertSafeSqlIdent(name)).toThrow(/Unsafe SQL identifier/);
}
});
it('encodes SQLi metacharacters when rendered via escapeHtml', () => {
for (const payload of SQLI) {
expect(escapeHtml(payload)).toBe(
payload
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
);
}
});
it('login-shaped handler rejects SQLi usernames without crash (401)', async () => {
const app = createTestApp();
app.post('/api/auth/login', (req, res) => {
void req.body;
return res.status(401).json({ success: false, error: 'Invalid credentials' });
});
for (const payload of SQLI) {
const res = await request(app)
.post('/api/auth/login')
.send({ username: payload, password: 'x' });
expect(res.status).toBe(401);
expect(res.body.success).toBe(false);
}
});
it('catalog table identifiers match safe pattern; malicious names fail', () => {
for (const name of SAFE_SQL_IDENT) {
expect(SAFE_IDENT_RE.test(name)).toBe(true);
}
for (const name of MALICIOUS_SQL_IDENT) {
expect(SAFE_IDENT_RE.test(name)).toBe(false);
}
});
});