LEX — AI Legal Platform for Law Firms

AI-powered legal analysis platform for law firms and corporate counsel.

Features

Resources

Blog Articles

Technology

Built on AWS (EC2, Bedrock Claude AI, ALB, WAF, S3, ACM, KMS). PostgreSQL, Redis, Qdrant vector database. TypeScript, React, Node.js.

Start free — 50 credits on registration. Sign up

TECH 15 хв

Безпека LEX AI: GDPR-аудит, 10 виправлень і 7 рівнів захисту

5 паралельних white-hat агентів перевірили платформу на відповідність GDPR та OWASP Top 10. Знайшли 23 вразливості — від SQL-ін\

Безпека LEX AI: GDPR-аудит, 10 виправлень і 7 рівнів захисту

Юридична платформа обробляє найчутливіші дані: судові справи, контракти, персональну інформацію клієнтів. Безпека — не фіча, а фундамент. Ми провели повний security audit силами 5 паралельних AI-агентів і виправили всі критичні знахідки за одну сесію.

Ця стаття — прозорий розбір: що знайшли, що виправили, і як побудована повна архітектура захисту LEX AI.


Як проводили аудит

Замість класичного ручного пентесту ми запустили 5 спеціалізованих white-hat агентів паралельно, кожен зі своєю зоною відповідальності:

Агент Фокус Файлів перевірено
🔍 Data Collection Cookie consent, трекінг, OAuth scopes 42
💾 Data Storage БД-схеми, retention, Redis, Qdrant, MinIO 53
👤 User Rights GDPR Art. 15-22 (доступ, видалення, портабельність) 25
🛡️ OWASP Top 10 Injection, XSS, Auth, CORS, CSRF, rate limiting 45
🌐 Data Transfers Third-party API, sub-processors, cross-border 48

Кожен агент автономно сканував кодову базу, перевіряв відповідність стандартам і створив структурований звіт з CVSS-оцінками.


Що знайшли: 23 вразливості

Критичні (виправлені)

1. Google Ads завантажувався ДО cookie consent

index.html містив hardcoded <script> тег Google Ads, який виконувався при кожному завантаженні сторінки — до того, як React-додаток встигав показати банер cookie consent. Кожен відвідувач вже мав дані відправлені в Google, навіть якщо потім відхилив аналітику.

Виправлення: Google Ads тепер завантажується динамічно тільки після consentStore.isAllowed('analytics'). Додано Google Consent Mode v2 з denied за замовчуванням:

gtag('consent', 'default', {
  analytics_storage: 'denied',
  ad_storage: 'denied',
  ad_user_data: 'denied',
  ad_personalization: 'denied',
});

2. JWT Secret з fallback на відомий рядок

Декілька файлів містили fallback-значення для JWT-секрету. Якщо при деплої змінна оточення не встановлена — додаток тихо працював з передбачуваним секретом, що дозволяло генерувати валідні JWT для будь-якого користувача.

Виправлення: Додаток тепер крашиться при старті, якщо JWT-секрет не встановлений через змінну оточення. Fallback-значення повністю видалені.

3. SQL Injection через інтерполяцію параметрів

Кілька місць у коді використовували пряму інтерполяцію параметрів у SQL-рядки замість параметризованих запитів. У поєднанні з п.2 це створювало прямий вектор SQL Injection.

Виправлення: Всі SQL-запити переведено на параметризовані плейсхолдери ($1, $2, ...).

Високі (виправлені)

4. Конверсійний трекінг без перевірки consent — всі gtag('event', 'conversion') виклики (реєстрація, оплата, top-up) тепер перевіряють consentStore.isAllowed('analytics') перед відправкою.

5. Nginx CORS відображав будь-який Origin — SSE-ендпоінти використовували $http_origin напряму, що дозволяло будь-якому сайту робити запити з credentials. Замінено на строгий whitelist дозволених доменів.

6. XSS через dangerouslySetInnerHTML — 3 компоненти рендерили HTML з бази без санітизації. Додано DOMPurify:

dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(html) }}

7. Динамічні SQL-таблиці без whitelist — деякі функції приймали імена таблиць як параметри без валідації. Додано строгий allowlist дозволених таблиць і колонок.

8. Cleanup-функції ніколи не запускались — функції очищення застарілих даних (сесії, видалені документи, токени) існували, але не були прив'язані до cron. Додано автоматичні cron-задачі.

9. Email-адреси логувались у plaintext — 9+ місць в auth-контролерах. Додано maskEmail(): user@example.comus***@example.com.

10. OAuth реєстрація без rate limiting — ендпоінт реєстрації OAuth-клієнтів дозволяв необмежену кількість запитів. Додано rate limiting по IP.


7 рівнів захисту LEX AI

Безпека платформи побудована за принципом defense in depth — кожен рівень компенсує можливі слабкості іншого.

Рівень 1: Cloudflare (Edge Protection)

Весь трафік проходить через Cloudflare перед тим, як досягне нашого сервера:

Рівень 2: TLS 1.3 (Transport Encryption)

Рівень 3: Nginx (Reverse Proxy + Security Headers)

Nginx — перший сервер, який бачить запит після Cloudflare:

Header Значення Захист від
HSTS max-age=31536000; includeSubDomains Downgrade атаки
X-Frame-Options SAMEORIGIN Clickjacking
X-Content-Type-Options nosniff MIME sniffing
Referrer-Policy strict-origin-when-cross-origin Information leakage
CSP Повна політика (12 директив) XSS, injection

Content Security Policy включає:

Рівень 4: Application Security (Express.js)

Multi-layer rate limiting — кожен тип ендпоінту (auth, chat, API, password reset) має окремі ліміти по IP або User ID. При падінні Redis rate limiting працює через in-memory fallback.

CORS — Express-рівень валідує origins незалежно від Nginx через строгий whitelist дозволених доменів.

Рівень 5: Authentication (6 методів)

LEX AI підтримує 6 методів автентифікації:

  1. Email + Password — bcrypt хешування, account lockout після невдалих спроб (15 хв)
  2. Google OAuth 2.0 — мінімальні scopes (profile + email), idToken верифікація
  3. WebAuthn / Passkeys — біометрична автентифікація через FIDO2, challenge TTL 5 хв
  4. Diia (Дія) — державна автентифікація, session TTL 10 хв
  5. OIDC / Authentik — SSO через Authentik
  6. API Keys — для MCP-клієнтів (Claude Desktop, Claude Code), database-backed з audit log

Dual Auth Middleware автоматично визначає тип токена і застосовує відповідну стратегію верифікації для кожного методу автентифікації.

Рівень 6: Database Security

Рівень 7: Data Protection (GDPR)

Реалізовані права:

Cookie Consent:

E2EE для документів:

Автоматичне очищення — регулярне видалення застарілих сесій, soft-deleted документів та OAuth токенів за налаштованими інтервалами.


Що залишається зробити

Аудит виявив і речі, які потребують більше часу:

Задача Пріоритет
Зберігати consent реєстрації на сервері (зараз тільки UI) High
Передавати consent через OAuth redirect flow High
Реалізувати Art. 18 (обмеження обробки) Medium
Реалізувати Art. 21 (право заперечити) Medium
Оновити Privacy Policy щодо Google Ads Medium
Додати Google Cloud Vision до DPA як sub-processor Medium
Column-level encryption для PII полів Medium
Nonce-based CSP замість unsafe-inline Low

Висновки

  1. AI-агенти для security audit — 5 паралельних агентів покрили більше поверхні атаки за 3 хвилини, ніж ручний review за день
  2. Defense in depth працює — жодна окрема вразливість не давала повний доступ до системи завдяки багаторівневій архітектурі
  3. GDPR — це код, не документ — права користувачів мають бути реалізовані в коді (export, delete, consent), а не тільки описані в Privacy Policy
  4. Прозорість будує довіру — ми публікуємо результати аудиту, бо вважаємо, що юридична платформа має бути відкритою щодо своєї безпеки

Весь код виправлень доступний у PR #1224.


Реєстрація: legal.org.ua