惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cisco Talos Blog
Cisco Talos Blog
V
V2EX
C
Check Point Blog
GbyAI
GbyAI
D
Docker
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog RSS Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
Netflix TechBlog - Medium
T
Troy Hunt's Blog
博客园 - Franky
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Microsoft Security Blog
Microsoft Security Blog
P
Privacy & Cybersecurity Law Blog
WordPress大学
WordPress大学
The Cloudflare Blog
S
SegmentFault 最新的问题
Latest news
Latest news
Microsoft Azure Blog
Microsoft Azure Blog
P
Proofpoint News Feed
I
InfoQ
博客园 - 【当耐特】
NISL@THU
NISL@THU
A
About on SuperTechFans
T
Tailwind CSS Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
The Hacker News
The Hacker News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Scott Helme
Scott Helme
雷峰网
雷峰网
C
CXSECURITY Database RSS Feed - CXSecurity.com
Security Latest
Security Latest
V
Vulnerabilities – Threatpost
Security Archives - TechRepublic
Security Archives - TechRepublic
A
Arctic Wolf
Hacker News: Ask HN
Hacker News: Ask HN
N
News and Events Feed by Topic
IT之家
IT之家
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
aimingoo的专栏
aimingoo的专栏
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
SecWiki News
SecWiki News
大猫的无限游戏
大猫的无限游戏
S
Security Affairs
The Register - Security
The Register - Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
L
LINUX DO - 热门话题
T
Tor Project blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Как технически проверить чужой сайт на 152-ФЗ за 30 секунд: архитектура сканера
mrq · 2026-06-22 · via Все публикации подряд на Хабре

Средний

7 мин

149

В 2025 году штрафы по 152-ФЗ выросли с 60 тыс. до 18 млн ₽ (ч. 8 ст. 13.11 КоАП — повторная утечка ПДн объёмом 10+ млн записей). Параллельно РКН перешёл на массовые проверки сайтов: за 2024 год — 1 870 проверок и 1,2 млрд ₽ штрафов. Большинство нарушений — технические: нет HTTPS, нет cookie-баннера, форма без чекбокса согласия, политика в Google Docs.

Юристы умеют находить такие нарушения вручную за час. Мы написали сканер, который делает то же самое за 30 секунд. В статье — архитектура, scoring-подход к чекбоксам согласия, реальные грабли (политика в Google Docs, скрытые checkbox в Tilda, многошаговые формы записи в клиниках). Код на PHP 8, без зависимостей, ~1 800 строк.

Что вообще нужно от сканера 152-ФЗ

Закон 152-ФЗ задаёт оператору ПДн (любому, кто собирает имя/email/телефон через форму на сайте) 9 обязанностей. Технически с улицы можно проверить 8 из них:

  1. HTTPS (ст. 19) — без TLS нельзя.

  2. Политика обработки ПДн на сайте оператора (ст. 18.1) — публичная, с 7 разделами.

  3. Согласие на обработку ПДн в каждой форме (ст. 6 + 9) — отдельный, осознанный, не предустановленный checkbox.

  4. Информирование об использовании cookie (ст. 16 Закона о связи + 152-ФЗ + практика РКН) — баннер с двумя кнопками.

  5. Регистрация в реестре РКН (ст. 22) — если обработка не подпадает под исключения ч. 2.

  6. Локализация БД (ч. 5 ст. 18) — БД ПДн россиян только в РФ.

  7. Поручение обработки (ст. 6 ч. 3) — если используется внешний сервис (Tilda Forms, JivoSite, Bitrix24) — нужен договор.

  8. Учёт ПДн сотрудников (ст. 10.1) — если на сайте есть страница «Команда» с ФИО/фото/должностями.

Девятая — режим обработки внутри компании (приказ оператора, реестр субъектов, ответственный) — снаружи не виден.

Сканер делает все 8 проверок параллельно, агрегирует в один отчёт со ссылками на нарушенные нормы и потенциальный штраф.

Архитектура: разбор по слоям

┌─────────────────────────────────────────────────┐
│  POST /v1/p152/scan {url}                       │
└──────────────────────┬──────────────────────────┘
                       │
       ┌───────────────┼───────────────┐
       ▼               ▼               ▼
  Главная        Form-pages       Политика
  страница       (parallel)       (parallel)
       │               │               │
       └───────┬───────┴───────┬───────┘
               ▼               ▼
       Детекторы         Внешние API
       (10 шт)           (РКН реестр,
                         ГеоIP хостинга)
               │
               ▼
       Findings → Score → JSON

Бэкенд — PHP 8.3 / nginx / PostgreSQL 16 на отдельной машине под api.imgchanger.org. Воркер запускается из обработчика handlers/p152_scan.php, библиотечная логика — в api/lib/p152_quick_scan.php.

Бюджет времени на один сайт — 5 секунд хард-кэп. Реальная медиана из прода — 2.1с (без кэша). При повторных сканированиях (TTL кэша — 7 дней) — мгновенно.

Главный трюк — curl_multi для всего

Наивная реализация качала бы кандидаты последовательно: главная (3с) → /privacy (3с) → /policy (3с) → /personal-data (3с) → … = 30+ секунд. Это тупик: пользователь уходит со страницы.

Решение — curl_multi_init + параллельная загрузка пачки URL:

function p152_fetch_urls_parallel(array $urls, int $timeout = 4): array {
    $mh = curl_multi_init();
    $handles = [];
    foreach ($urls as $u) {
        $ch = curl_init(p152_idn_url($u));
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_MAXREDIRS      => 3,
            CURLOPT_TIMEOUT        => $timeout,
            CURLOPT_CONNECTTIMEOUT => 3,
            CURLOPT_USERAGENT      => P152_USER_AGENT,
            CURLOPT_SSL_VERIFYPEER => false,
        ]);
        curl_multi_add_handle($mh, $ch);
        $handles[$u] = $ch;
    }
    $active = null;
    do {
        $status = curl_multi_exec($mh, $active);
        if ($active) curl_multi_select($mh, 0.2);
    } while ($active && $status === CURLM_OK);
    // … собрать результаты
}

Тонкости:

  • TIMEOUT 4с на URL — иначе один медленный сайт ломает весь батч.

  • MAXREDIRS 3 — Tilda/Битрикс любят 301→301→301.

  • SSL_VERIFYPEER false — половина мелких сайтов с самоподписанными или просроченными сертами; мы не хотим падать на них.

  • IDN-нормализация p152_idn_url() — для доменов .рф через idn_to_ascii() в xn--, иначе libcurl не пройдёт.

Это даёт честное ~4× ускорение: 15 URL загружаются за 3-4 секунды, а не за 15×3=45с.

Детектор форм — scoring вместо binary

Наивный подход: «есть <input type="checkbox"> рядом с формой → согласие есть». Это даёт ~30% false positive на реальном вебе. Потому что:

  • Битрикс рендерит чекбокс согласия в отдельном <div> вне <form>, в 400+ символах от формы (шаблоны личного кабинета).

  • Tilda даёт checkbox с display:none и кладёт сверху красивый кастомный <label> — юридически это отсутствие чекбокса, пользователь не видит.

  • Caldera Forms (WordPress) даёт полям хэш-имена fld_154589, а GDPR-чекбокс размечает через data-label="agreement".

  • Многошаговые формы записи на приём в клиниках: первая страница — телефон, согласие — на третьем шаге в скрытом <div> за 6000 символов.

Решение — суммарный scoring по сигналам в окне ±400 символов вокруг <form>:

Сигнал

Score

Видимый <input type=checkbox>

+5

<input name=*acceptance/agreement/consent*> или data-label=agreement

+5

Класс плагина:wpcf7-acceptance, t-checkbox, caldera-forms-consent-field

+3

Кастомный лейбл <label class="checkbox/agree/consent">

+3

Ссылка на политику в контексте формы (href=*policy*)

+2

Текст «согласие / 152-ФЗ / обработка персональных данных»

+2

«Нажимая кнопку, я даю согласие…» + ссылка на политику

+3

Многошаговый мастер: checkbox + consent-text в окне ±3000/6000

+6

Решение: ≥6 → согласие есть; 3–5 → подозрительно (info, без штрафа); 0–2 → нарушение (high). Скрытый CSS-чекбокс отнимает 5 очков — формы только со скрытым чекбоксом помечаются checkbox_hidden_only.

В проде это даёт ~96% точности по нашему набору (340 размеченных вручную сайтов).

Детектор политики — приоритеты + контентный фильтр

Политику ищем в три захода:

Приоритет 1 — явно политика. URL содержит privacy/privacy-policy/politika-konfidencialn/personal-data, или текст ссылки матчит regex полит[а-я]*\s+(?:обработк|конфид|в\s+отношении\s+обраб). Учитываем PDF-документы из медиабиблиотеки с тем же якорем — типовой паттерн Битрикс.

Приоритет 2 — вероятно политика. Менее уверенные URL/тексты.

Приоритет 3 — это согласие/оферта, не политика. URL содержит soglashenie/agreement/oferta/dogovor. Возвращается только как fallback с пометкой type='consent'.

После сбора кандидатов content-check: грузим страницу и в первых 30 000 символов текста ищем фразу «политика обработки» / «политика конфиденциальности» / «privacy policy». Если нет — это не политика, а что-то соседнее.

Это нужно потому что URL вроде /dokumenty/ или /info/ без анализа контента дают шум.

Свежая ловушка: политика в Google Docs

Реальный кейс из прода (legalup.online, юридическая контора): на главной — три ссылки с правильными анкорами:

  • «Политика обработки персональных данных LegalUp» → docs.google.com/document/d/.../edit

  • «Пользовательское соглашение LegalUp» → docs.google.com/document/d/.../edit

  • «Согласие на обработку персональных данных» → docs.google.com/document/d/.../edit

Регексп P1 ловит — кандидат отбирается. Дальше content-check грузит Google Docs /edit. И тут — тишина. Google Docs отдаёт каркас JS-приложения; текст документа подгружается через закрытый API только в браузере. В первых 30K символов HTML — никаких «политика обработки».

В первой версии сканер возвращал policy.found=false, как будто политики нет. Это технически неверно (политика есть, ссылка есть, документ открыть можно) и юридически тоже неполно — у этого паттерна свой риск.

Поправка: early-return до content-check, если хост кандидата — известный SaaS-хостинг:

$externalHosts = [
    'docs.google.com'   => ['Google Docs',          'США', 'high'],
    'drive.google.com'  => ['Google Drive',         'США', 'high'],
    'notion.so'         => ['Notion',               'США', 'high'],
    'dropbox.com'       => ['Dropbox',              'США', 'high'],
    '1drv.ms'           => ['Microsoft OneDrive',   'США', 'high'],
    'icloud.com'        => ['Apple iCloud',         'США', 'high'],
    'yadi.sk'           => ['Яндекс.Диск',          'РФ',  'medium'],
    'cloud.mail.ru'     => ['Mail.ru Облако',       'РФ',  'medium'],
];
foreach (['p1', 'p2'] as $lv) {
    foreach ($prio[$lv] as $candUrl) {
        $host = strtolower((string)parse_url($candUrl, PHP_URL_HOST));
        if (isset($externalHosts[$host])) {
            return [
                'found'            => true,
                'type'             => 'external_hosting',
                'url'              => $candUrl,
                'external_service' => $externalHosts[$host][0],
                'external_country' => $externalHosts[$host][1],
                'external_risk'    => $externalHosts[$host][2],
            ];
        }
    }
}

Юридический смысл: политика в Google Docs (США) — это сразу ч. 5 ст. 18 (БД ПДн вне РФ — при открытии посетителем IP/cookies уходят в Google) + ст. 18.1 (политика должна быть на сайте оператора). Штраф по ч. 8 ст. 13.11 КоАП — до 6 млн ₽ при повторном нарушении локализации.

Внешние интеграции: реестр РКН + ГеоIP

Реестр РКНpd.rkn.gov.ru/operators-registry. Поиск по ИНН → JSON со статусом регистрации. ИНН берём с сайта — из футера / реквизитов / политики через regex \b\d{10,12}\b + проверка контрольной суммы.

ГеоIP хостингаip-api.com (бесплатный лимит 45 req/min, для нас хватает). Отдаёт страну сервера, ASN, организацию. Если не РФ — пометка в отчёте: «БД на сайте может храниться вне РФ, проверьте ч. 5 ст. 18».

Эти два запроса делаем тоже параллельно с основным fetch главной — итоговый бюджет времени не растёт.

Антипаттерны, которые мы научились не путать

Поиск ≠ форма ПДн. Если в <form> ≤1 PII-поле + role="search" / action="/search" — это поиск, пропускаем.

Honeypot ≠ ПДн. Caldera/CF7 кладут невидимое поле name="web_site" для антиспама. Списком исключаем.

Регистрация ≠ Контактная форма. У формы регистрации часто бывают классы modal__search__inputsearch в substring наивно матчил бы их как поиск. Категории проверяем строго: role="search", name="q", name="s", action="/search".

checked в HTML ≠ pre-checked. Слово checked встречается в data-was-checked и в классах is-checked. Регексп — (?<![-\w])checked(?![-\w]) — только как boolean-атрибут.

Согласие действием. Битрикс/самописные сайты часто реализуют «Нажимая кнопку, я даю согласие на обработку…» + ссылка на политику. Юридически — серая зона: РКН в письмах рекомендует именно чекбокс, но прямого запрета нет. Для базовых форм без спецкатегорий ПДн — допустимо, ставим +3 в score.

Где сканер до сих пор слабоват

  • JS-rendered контент. Сканер на curl — видит только server-rendered HTML. Сайты на React/Vue/Next.js без SSR теряют 50-90% контента. План: добавить опциональный второй проход через headless-browser (chromium / playwright) для подозрительных сайтов.

  • PDF-политика. Видим что это PDF, но не парсим. План: pdftotext для извлечения первых 5К символов и пропуск через p152_analyze_policy_sections.

  • Подсчёт штрафа сейчас оценочный (mode по ч. 3 ст. 13.11 = 45 тыс. для юрлиц). Для реалистичной оценки — нужно учитывать оборот компании (для крупного бизнеса ч. 5 ст. 13.11 даёт до 18 млн), повторность, объём утечки. Это уже не «технический сканер», а юр.экспертиза.

Что в итоге

Если оценивать «по делу»: технических нарушений 152-ФЗ на сайтах малого и среднего бизнеса в 2026 году — много. По нашим прогонам, 78% сайтов имеют хотя бы одно нарушение из категорий high; 31% — три и более.

Шесть месяцев работы сканера дали два неожиданных вывода:

  1. Самое частое нарушение — не отсутствие политики, а скрытый CSS-чекбокс согласия в формах Tilda. Видимая «галка» — это псевдо-элемент :before, реальный <input> под display:none уже отмечен. Пользователь не может его снять.

  2. Второе по частоте — политика не на своём домене: Google Docs, Notion, реже Dropbox. Авторы видят это как «галочка ради галочки», не понимая, что само по себе это два нарушения (локализация + публикация на сайте оператора).

Если кто-то делает похожий инструмент или хочет встроить чек 152-ФЗ как лидмагнит в свой сервис — открыт обсудить архитектуру в комментариях. Сам сканер крутится на imgchanger.org/ru/p152 — можно проверить любой сайт без регистрации.