test(security): deep — JWT tampering, SQLi probes, mass-assignment, IDOR#15
Merged
Conversation
12 new tests in server/__tests__/security-deep.test.js, complementary to the existing security.test.js (3 JWT + X-Office-Id + auth-gate tests). JWT tampering: - alg:none unsigned token → 403 - payload-only modification (lawyer→director) → 403 (signature mismatch) - foreign secret re-sign → 403 - missing signature segment → 403 SQL injection probes (parameterised queries hold up): - login with classic SQLi payloads → 4xx, no token issued - SQLi-laced client name → stored literally, table intact - numeric id with SQL noise → 4xx, no data leak Mass-assignment guards: - body.office_id ignored on POST /api/clients (uses JWT office_id) - registering with userType=super_admin never grants director/admin role IDOR / cross-office isolation: - lawyer in office A sees no office B clients via GET /api/clients - lawyer cannot spoof office via X-Office-Id (middleware honours only directors) Header parsing safety: - X-Office-Id 'N OR 1=1; DROP TABLE...' → parseInt → safe integer, no SQLi 73 → 85 backend Jest tests, all green. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Contributor
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…onflict Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Глубокие security-тесты — дополнение к существующему
security.test.js. 12 новых тестов, всё ходит в реальный MySQL.73 → 85 backend Jest тестов, прогон полного backend suite: ~38 сек, все ✓.
Что покрыто (
server/__tests__/security-deep.test.js)JWT tampering (4 теста):
alg:noneтокен (без подписи) → 403lawyer→director) при оригинальной подписи → 403 (jwt.verify ловит mismatch)header.payload.) → 403SQL injection probes (3 теста):
admin' OR '1'='1,'; DROP TABLE users; --,' UNION SELECT...) → 4xx, ни один не возвращает токен; таблицаusersживаяDROP TABLE clients→ 201, значение сохранено литералом (parameterised query), таблица не уронена:idс SQL-шумом → 4xx/404, таблицаclientsцелаMass-assignment guards (2 теста):
/api/clientsсbody.office_id = otherOfficeId→ клиент создаётся в собственном офисе аттакера (controller перезаписываетoffice_idиз JWT)userType: 'super_admin'→ роль НЕ становится director/admin/ownerIDOR / cross-office isolation (2 теста):
GET /api/clients→ клиенты офиса B отсутствуют в ответеX-Office-Id: <officeB>создаёт/api/cases→ дело попадает в A, не B (middleware honours header только для директоров)Header parsing safety (1 тест):
X-Office-Id: 5 OR 1=1; DROP TABLE offices --→parseIntотрезает до 5, в SQL уходит safe integer, таблицаofficesцелаЧто добавлено
server/__tests__/security-deep.test.js(~270 строк, 12 тестов)TESTING.md— описание security-deep suiteReview & Testing Checklist for Human
cd server && DB_HOST=127.0.0.1 DB_PORT=33307 DB_USER=root DB_PASSWORD=testpass DB_NAME=lawtech_test JWT_SECRET=test_secret npx jest __tests__/security-deep.test.js --runInBand→ 12 passednpm test→ 85 passed (73 старых + 12 новых)Notes
Что эти тесты НЕ покрывают (могут быть отдельным PR/issue):
PUT /api/offices/:id,DELETE /api/offices/:id) — controller не проверяет ownership, любой авторизованный юзер может править/удалить чужой офис. Тест не написан, чтобы не вырывать CI на known vulnerability. Стоит исправить в коде: добавитьWHERE owner_id = req.user.id.express-rate-limit. Без него тестировать нечего. Если введёте — могу написать тесты на 429 при превышении.Все тесты используют существующие фабрики (
registerDirectorWithOffice,registerDirector,registerLawyer) — никаких новых side-effect helpers, кроме локальногоseedLawyerInOfficeдля прикрепления юриста к существующему офису.Link to Devin session: https://app.devin.ai/sessions/514f368ad0194bf18d0327e62a88aeda
Requested by: @Br1Im