Войдите или зарегистрируйтесь
Вы сможете писать комментарии и посты, ставить лайки и другое
Поиск
Тёмная тема

Посты по тегу: IT

Кибербезопасность 3 часть

6 дн. назад
Третья часть моего рассказа о направлениях кибербезопасности. И тема:Threat Hunting

Обратите внимание: Threat Hunting — продвинутая специализация. Обычно требуют 1-2 года опыта в SOC или IR. Но путь можно начать с нуля и сразу ориентироваться на эту цель.

Этап 0: Фундаментальная база (4-6 месяцев)

Цель: Получить знания, без которых охотиться не на что и негде.

1. Операционные системы — экспертное понимание
Windows (глубоко):

Архитектура: процессы, потоки, дескрипторы, реестр, DLL

Механизмы аутентификации: NTLM, Kerberos (как это выглядит в логах)

WMI, PowerShell, RPC — как используются злоумышленниками (Living off the Land)

Критически: Автозапуск (Persistence): Run Keys, Services, Scheduled Tasks, COM Hijacking

Linux:

Системные вызовы (syscalls), процессы, cron, systemd

Аудит: auditd правила, как детектировать подозрительные вызовы Файловые системы, скрытые каталоги, атрибуты

2. Компьютерные сети — видеть аномалии

Не просто теория, а аномалии:

DNS: запросы на DGA-домены, tunneling, fast-flux

HTTP/S: нестандартные User-Agent, beaconing (регулярные "звонки" на C2)

Протоколы: SMB, RDP, SSH — признаки brute-force и lateral movement

Инструменты: Wireshark, Zeek/Bro, tcpdump — не просто смотреть, а строить behavioural-

базу

3. Кибербезопасность — атаки и защита

MITRE ATT&CK Framework — ваш основной язык и карта

Изучить все тактики (Tactics), ключевые техники (Techniques)

Понимать, как каждая техника проявляется в данных (Data Sources)

Кибер-убийственная цепочка (Cyber Kill Chain) — альтернативный взгляд

Этап 1: Ядро Threat Hunting (6-8 месяцев)

Цель: Освоить методологию, инструменты и мышление охотника.

1. Методологии охоты

Гипотезно-ориентированный подход: Самая важная концепция!

"А что, если...?" → Гипотеза → Поиск данных → Анализ → Выводы

Пример: "А что, если в сети есть скрытый C2-канал через DNS?"

Модели:

Persistence Hunting: Поиск механизмов выживания в системе
Anomaly Hunting: Поиск отклонений от базовой линии
Intel-Driven Hunting: Охота по конкретным IOC и TTP из отчетов
Картирование к ATT&CK: Каждая ваша гипотеза должна быть привязана к конкретной технике MITRE (например, T1059.003 - Windows Command Shell)
2. Ключевые техники охоты

1. Stack Counting: Анализ вызовов процессов (какая программа кого запустила)
2. Baselining: Понимание "нормы" для вашего окружения (какие порты обычно открыты, какие процессы)
3. Deception Technology: Использование ловушек (honeytokens, canary files)
4. Hunting for LOLBAS: Поиск использования легитимных инструментов в злонамеренных целях

Первым фото прикреплю, что вы должны знать: где искать и что искать

Этап 2: Практика в лабораториях (параллельно с Этапом 1)

Цель: Наработать мышечную память и образ мышления.

1. Лабораторные платформы

TryHackMe:
"Threat Hunting" path (обязательно!)
"Windows Event Logs" room

"Red Team" rooms (чтобы понять TTP злоумышленников)

Hack The Box (Defensive Paths):

"Cyber Defense" track

Сложнее, но ближе к реальности

LetsDefend.io:

Реалистичная SIEM, можно практиковать гипотезы Кейсы, основанные на реальных инцидентах

2. Создание домашней лаборатории для охоты

Продвинутая схема:

[Атакующий (Kali)] → [Жертва (Win10 + Linux)] → [Данные] → [Аналитическая платформа]



[Сбор данных: EDR, Sysmon, Zeek]



[SIEM: Elastic Stack + HELK или Security Onion]



[Threat Hunter (вы) + Jupyter Notebook]

Что настроить:

1. Sysmon + SwiftOnSecurity Config на Windows — золотой стандарт логирования

2. Zeek для сетевого трафика — генерирует структурированные логи

3. Elastic Stack или Security Onion как платформа для анализа

4. Atomic Red Team для симуляции атак и тестирования гипотез

3. Инструменты охотника

Сбор и обогащение - OSQuery, Velociraptor, Logstash

Анализ данных - Jupyter Notebook + Python (Pandas, Matplotlib), R

Анализ процессов - Sysinternals Suite, Process Explorer, Process Monitor

Сетевой анализ - Zeek, RITA (BlackHat), Stenographer

EDR-подобные - Wazuh, Elastic Agent, LimaCharlie

Оркестрация - TheHive, Cortex (для управления гипотезами)

Этап 3: Углубление и специализация (4-6 месяцев)

Цель: Перейти от проверки гипотез к проактивной охоте.

1. Data Science для охотника

Основы Python: Не просто скрипты, а анализ

Pandas для работы с большими объемами логов

Matplotlib/Seaborn для визуализации аномалий

Jupyter Notebook как основная рабочая среда

Статистика: Понимание распределений, выбросов (outliers), корреляций Машинное обучение (базово): Кластеризация для поиска аномалий

2. Углубление в атаки

Red Team视角: Пройти базовые курсы по пентесту

Основы Active Directory атак (Kerberoasting, Pass-the-Hash)

Техники обхода защиты (AV/EDR evasion)

Современные C2-фреймворки (Cobalt Strike, Sliver)

Цель: Не стать хакером, а понимать, что и где искать

3. Сертификации

Для начала: CompTIA CySA+ (охватывает основы анализа)

Специализированные:

Blue Team Level 1 (BTL1) — практическая база

Certified Threat Intelligence Analyst (CTIA) — понимание угроз

GIAC Cyber Threat Intelligence (GCTI) — продвинутый уровень

Идеальная цель: SANS FOR508: Advanced Incident Response, Threat Hunting, and Digital Forensics → GCFA/GCTI
Этап 4: Формирование портфолио и поиск работы

Цель: Стать Junior Threat Hunter.

1. Портфолио охотника

GitHub:

Jupyter Notebooks с разборами охоты

Скрипты для автоматизации (парсинг логов, enrichment IOC)

Конфигурации Sysmon, Zeek, детекционные правила

Блог/Write-ups:

Полные циклы охоты: гипотеза → поиск → находки → рекомендации

Пример: "Охота на Kerberoasting в Active Directory"

Разборы реальных APT-отчетов и их TTP

Участие в сообществе:

Публикация детекционных правил в форматах Sigma или YARA

Контрибьюшн в open-source проекты (Velociraptor, OSQuery)

2. Ключевые компетенции для резюме

Hard Skills:

Знание MITRE ATT&CK и умение строить гипотезы

Опыт работы с EDR/XDR платформами (CrowdStrike, SentinelOne, Microsoft Defender) Навыки анализа данных (SQL, Python, ElasticSearch/Kibana)

Понимание современных атак и TTP

Soft Skills:

Любопытство и настойчивость (главное качество!) Критическое мышление Умение визуализировать и объяснять данные

Способность работать с неполной информацией

3. Типовые задачи на собеседовании

Теоретические:

"Опишите вашу любимую технику MITRE ATT&CK и как бы вы искали её в сети?" "Как бы вы обнаружили lateral movement в сегментированной сети?"

"Что такое beaconing и как его детектировать статистически?"

Практические:

Дадут набор логов (Sysmon + Proxy) и спросят: "Есть ли здесь компрометация?" Попросят написать гипотезу для охоты на конкретную угрозу (например, ransomware) Предложат проанализировать дамп трафика на наличие C2
Ресурсы для обучения

Бесплатные:

MITRE ATT&CK Navigator — интерактивное изучение матрицы

Detection Lab от Chris Long — готовая лаборатория на GitHub

PurpleSharp — инструмент для симуляции атак и тестирования детекций

Threat Hunter Playbook от Roberto Rodriguez (@Cyb3rWard0g)

Awesome Threat Detection — curated list ресурсов на GitHub

Платные (но стоящие):

Hunt Evil — практический курс от автора Practical Threat Intelligence

SANS FOR508 — лучший, но дорогой курс

Pluralsight — курсы по анализу данных для security

Сообщества:

Open Threat Research Forge (OTRF) — Discord с профессионалами

SOC & Threat Hunting — Telegram-чаты

Twitter: @Cyb3rPandaH, @Cyb3rWard0g, @huntresslabs, @SwiftOnSecurity

Критически важные советы:

1. Начинайте с малого: Одна хорошая гипотеза в неделю лучше 10 поверхностных.

2. Документируйте всё: Даже неудачные охоты — это опыт. Ведите "Hunter's Journal".

3. Мыслите как противник: Регулярно смотрите записи с Red Team конференций.

4. Автоматизируйте рутину: Если дважды делаете одно действие — пишите скрипт.
5. Создайте свою "карту охоты": Таблица: TTP → Гипотеза → Где искать → Инструменты.

Путь сложный, но это одна из самых творческих и востребованных ролей в cybersecurity. Вы становитесь не просто реагирующим аналитиком, а проактивным исследователем. Прикреплю фото таблицы, чтобы можно было заскринить план обучения. Всем благ, дальше расскажу о Red Team / Pentest.
Показать полностью...
+1
6

Кибербезопасность, продолжение

6 дн. назад
Продолжаю рассказывать о направлениях в кибербезопасности. Сейчас расскажу о этапах обучения в направлении: Incident Response

Этап 0: Фундаментальная база (4-6 месяцев)

Цель: Построить прочную основу без которой расследование инцидентов невозможно.

1. Компьютерные сети - обязательное знание на уровне администрирования

Глубокое понимание: TCP/IP стек, все основные протоколы (DNS, HTTP/S, SMTP, DHCP, ARP, ICMP)

Критически важное: Чтение и анализ сетевого трафика в Wireshark

Практика:

Сборка тестовой сети в GNS3/EVE-NG

Решение заданий на анализ PCAP-файлов (примеры на Malware-Traffic-Analysis.net)

Книга: "Wireshark 101" by Laura Chappell

2. Операционные системы - на уровне продвинутого пользователя

Windows (обязательно глубоко):

Архитектура ОС (процессы, службы, DLL, реестр)

Журналы событий (Event Logs): Security, System, Application

Аутентификация (NTLM, Kerberos)

Автозапуск (AutoStart Extensibility Points)

Linux:

Файловая система, права, процессы

Журналирование (syslog, journald, auditd) Bash-скрипты для автоматизации

3. Основы информационной безопасности

Модели угроз, векторы атак, жизненный цикл атаки Базовые понятия: IOC, TTP, MITRE ATT&CK Framework

Курс: SANS SEC301 (можно найти материалы) или CompTIA Security+

Этап 1: Специализированные знания IR (6-8 месяцев)

Цель: Изучить непосредственно дисциплины, составляющие инцидент-респонс.
1. Форензика (Digital Forensics)

Дисковая форензика:

Работа с образами дисков (dd, FTK Imager)

Анализ файловых систем (NTFS, ext4 - метаданные, журналы)

Timeline analysis (Plaso, log2timeline)

Поиск артефактов: Prefetch, ShimCache, AmCache, SRUM

Оперативная память (Memory Forensics):

Создание дампов памяти (DumpIt, winpmem)

Анализ с помощью Volatility Framework

Поиск процессов, сетевых соединений, инжектированных библиотек

Сетевая форензика:

Анализ PCAP-файлов на предмет аномалий

Выявление C2-трафика, эксфильтрации данных Инструменты: NetworkMiner, Capa

2. Малаварный анализ (начальный уровень)

Статический анализ: strings, PE-структура, импорты/экспорты

Динамический анализ в песочницах: Any.run, Hybrid-Analysis, локально Cuckoo Sandbox

Базовый анализ отчетов VirusTotal

3. Процесс расследования инцидентов

Модели: NIST SP 800-61, SANS PICERL (Preparation, Identification, Containment, Eradication, Recovery, Lessons Learned)

Документирование: Chain of Custody, форматы отчетов

Коммуникация: Как общаться с другими отделами во время инцидента

Этап 2: Практика и инструменты (параллельно с Этапом 1)

Цель: Наработать практические навыки.

1. Лабораторные среды и платформы

TryHackMe:

"Incident Response" path

"Forensics" rooms

"Malware Analysis" introductory rooms

LetsDefend.io:

Лучшая платформа для IR практики

Реалистичные симуляции инцидентов

Работа с SIEM как в реальном SOC

Blue Team Labs Online (Security Blue Team): Более сложные сценарии

SANS DFIR SIFT Workstation: Установите и освойте набор инструментов

2. Создание домашней лаборатории

Минимум:

1. Виртуальная машина Windows 10 (жертва)

2. Виртуальная машина Kali Linux (атакующий + инструменты анализа)

3. Виртуальная машина с REMnux (форензика)

4. SIEM/лог-сервер (Elastic Stack/Wazuh)

Практические сценарии:

Сымитировать атаку (например, с помощью Atomic Red Team) Собрать артефакты (дампа памяти, диска, логи)

Провести расследование Написать отчет

3. Инструменты - обязательный набор (будет фото ниже)

Этап 3: Углубление и сертификации (4-6 месяцев)

Цель: Систематизировать знания и получить подтверждающие документы.

1. Сертификации - оптимальный путь
1. CompTIA Security+ (база) → CompTIA CySA+ (аналитика) → CompTIA Pentest+ (понимание атак)
2. GIAC Certified Incident Handler (GCIH) - золотой стандарт, но дорогой

3. EC-Council Certified Incident Handler (ECIH) - более доступный вариант

4. Blue Team Level 1 (BTL1) - практический экзамен

2. Углубленные темы

Threat Hunting: Proactive поиск угроз

Анализ больших данных: Основы ElasticSearch/KQL, Splunk SPL

Автоматизация: Python/Go для автоматизации сбора артефактов Клауд-форензика: Основы расследований в AWS/Azure

Этап 4: Подготовка к работе (постоянно)

Цель: Найти первую позицию Junior IR Analyst.

1. Портфолио и проекты

GitHub:

Скрипты для автоматизации (парсинг логов, сбор артефактов)

Конфигурации инструментов

Docker-образы с настройками лаборатории

Блог/Write-ups:

Подробные разборы инцидентов из LetsDefend

Анализ малвари с VirusTotal/Hybrid-Analysis

Обзоры инструментов и методик

2. Ключевые компетенции для резюме

Технические:

Расследование инцидентов по методологии NIST/SANS Форензический анализ (диск, память, сеть)

Базовый малаварный анализ

Работа с системами мониторинга (SIEM)

Знание MITRE ATT&CK

Софт-скиллы:

Внимание к деталям

Умение работать под давлением

Техническое письмо (отчеты)

Коммуникация с нетехническими специалистами

3. Собеседование - к чему готовиться

Технические вопросы:

"Опишите процесс расследования компрометации рабочей станции" "Как определить, что система заражена малварью?"

"Что такое Living off the Land атаки? Приведите примеры"

"Как вы будете расследовать подозрительную активность в сети?"

Практические задания:

Анализ PCAP-файла на наличие C2-трафика

Исследование образа диска на предмет persistence-механизмов Разбор логов на предмет bruteforce-атаки

Также в фотографии добавлю план обучение на первый год. Ну а сейчас дам то, где же вам брать те самые необходимые данные:
Бесплатные курсы:

SANS DFIR YouTube Channel - вебинары от экспертов 13Cubed YouTube Channel - отличные tutorials по форензике

Cybrary - курсы по IR

DFIR Diva - ресурсы от Kristin Gudbrandsen

Книги:

1. "The Practice of Network Security Monitoring" by Richard Bejtlich

2. "Windows Forensic Analysis" by Harlan Carvey

3. "The Art of Memory Forensics" by Michael Hale Ligh

4. "Incident Response & Computer Forensics" by Jason Luttgens

Сообщества:

DFIR Discord - общение с практиками r/computerforensics на Reddit

Ну и конечно же советы:

1. Практика > Теория - 70% времени уделяйте hands-on

2. Документируйте всё - ведите заметки в формате, который поймет коллега

3. Специализируйтесь - после освоения основ выберите нишу (облачная форензика, мобильные устройства и т.д.)
4. Сети - посещайте митапы (например, OWASP), общайтесь в профессиональных чатах

Всем безопасникам удачи, дальше расскажу о Threat Hunting
Показать полностью...
+1
3

Направления кибербезопасности

8 дн. назад
Кибербезопасность — это не одна работа и не один путь. Здесь нет универсального «стань киберспецом». Кто-то целыми днями смотрит логи и ловит атаки. Кто-то расследует взломы. Кто-то ломает системы легально. А кто-то вообще не пишет код, но управляет рисками и аудитами. Этот пост — карта направлений в кибербезопасности. Он нужен, чтобы Вы поняли, куда реально идти, что там делают на практике и чего ждать по деньгам и сложности. Без мотивационных сказок. Без «войти за месяц». Только честная картина рынка и вариантов развития. Прочитай — и выбери путь осознанно, а не наугад.

SOC / Blue Team Этап 0:
Фундамент (3-6 месяцев)
Цель: Понимать, как всё устроено. Без этого этапа дальнейшее обучение будет шатким.
1. Компьютерные сети (Самое важное!):
• Теория: Модель OSI и TCP/IP. Протоколы: Ethernet, IP, TCP/UDP, DNS, HTTP/HTTPS, DHCP, ARP. NAT, VLAN, Subnetting.
• Ресурсы: Книга "Компьютерные сети" Таненбаума, курс Network+ от CompTIA (бесплатные видео на YouTube).
• Практика: Настроить домашний роутер, поработать с Wireshark для просмотра базового трафика.
2. Операционные системы:
• Windows: Архитектура, процессы, службы, реестр, журналы событий (Event Log). Управление через PowerShell (основы).
• Linux: Обязательно! Установите дистрибутив (Ubuntu, CentOS). Изучите командную строку (bash), структуру файловой системы, управление процессами, пакетами, правами (chmod/chown), основы сетевых утилит (netstat, ss, tcpdump).
• Ресурсы: Microsoft Learn, сайт likegeeks.com, книга "Linux для начинающих".
3. Кибербезопасность - основы:
• Триада CIA (Конфиденциальность, Целостность, Доступность).
• Базовые понятия: угрозы, уязвимости, риски, виды атак (DoS, фишинг, malware).
• Ресурсы: Введение в кибербезопасность от Cisco Networking Academy (бесплатно), TryHackMe - комнаты "Pre Security" и "Introduction to Cyber Security".
Этап 1: Ядро Blue Team (6-9 месяцев)
Цель: Получить конкретные навыки, необходимые для работы в SOC.
1. Системный и сетевой мониторинг:
• SIEM (Security Information and Event Management): Основная рабочая среда SOCаналитика.
• Практика: Разверните дома ELK-стек (Elasticsearch, Logstash, Kibana) или Wazuh (бесплатный SIEM с HIDS). Настройте сбор и анализ логов с вашего ПК.
• Изучите: Что такое корреляция событий, алерты, дашборды.
2. Анализ угроз (Threat Intelligence):
• Понять: Что такое IOC (Indicators of Compromise) - хэши, IP-адреса, домены.
• Научиться: Пользоваться открытыми источниками (OTX AlienVault, VirusTotal, Abuse.ch).
• Форматы: STIX/TAXII (базово).
3. Расследование инцидентов (Incident Response):
• Жизненный цикл: Подготовка → Обнаружение → Анализ → Устранение → Восстановление → Уроки.
• Практика на CTF: Расследуйте "утечки данных", "заражение вирусом" на платформах для тренировок.
• Форензика (базово): Анализ дампов оперативной памяти, дисков (автономно). Инструменты: Volatility, Autopsy.
4. Основы защиты сетей:
• Firewall (МЭ): Разберитесь с понятием политик (allow/deny), stateful inspection.
• IDS/IPS (Системы обнаружения/предотвращения вторжений): Чем отличаются, как работают (на основе сигнатур и аномалий).
• Практика: Поработайте с open-source решениями: Snort (IDS), Suricata (IDS/IPS), pfSense (firewall).
5. Логи и их анализ:
• Какие логи критичны: Windows Security/System Logs, Linux auth.log/syslog, веб-сервера (Apache/nginx), сетевые устройства.
• Научиться: "Читать" логи, вытаскивать из них ключевую информацию (IP, имя пользователя, временная метка, действие).
Этап 2: Практика и сертификации (параллельно с Этапом 1)
Цель: Закрепить знания, получить подтверждающие документы для резюме.
1. Лабораторная практика:
• TryHackMe: Лучший старт! Пройдите все комнаты из дорожки "Cyber Defense" и "SOC Level 1". Интерактивно, с пояснениями.
• LetsDefend.io: Платформа, созданная специально для Blue Team. Вы выступаете в роли SOC-аналитика, работаете с реальной SIEM, расследуете инциденты. Критически важно!
• Blue Team Labs Online (Security Blue Team): Более продвинутые лабораторные работы.
• Создайте свою домашнюю лабу: В VMware/VirtualBox разверните мини-сеть: "жертва" (Windows), "атакующий" (Kali Linux), "защитник" (Linux с ELK/Wazuh).
2. Сертификации (выберите 1-2 для старта):
• CompTIA Security+: Фундаментальный сертификат по безопасности. Обязателен к изучению программы, даже если не сдаете экзамен.
• CompTIA CySA+ (Cybersecurity Analyst): Более сфокусирован на анализе и навыках Blue Team. Отличный следующий шаг после Security+.
• Blue Team Level 1 (BTL1) от Security Blue Team: Практический экзамен в формате лаборатории. Очень ценится сообществом.
• EC-Council Certified SOC Analyst (CSA): Специализированный сертификат для SOC.

Этап 3: Трудоустройство (поиск первой работы)
Цель: Получить позицию Junior SOC Analyst или Security Operations Center Intern.
1. Портфолио:
• GitHub: Выкладывайте свои скрипты (например, на Python для парсинга логов), конфигурации для SIEM, отчеты по расследованию инцидентов из LetsDefend.
• Блог/Write-ups: Пишите разборы решенных вами заданий с TryHackMe/LetsDefend. Показывайте ход мыслей аналитика.
2. Резюме и LinkedIn:
Резюме: Делайте упор на навыки (SIEM, анализ логов, IDS, основы сетей, Linux) и практический опыт (лабы, CTF, пет-проекты). Укажите пройденные курсы и сертификаты.
LinkedIn: Заполните профиль на 100%. Укажите ключевые слова: "SOC Analyst", "Cybersecurity", "Threat Hunting", "SIEM".
Подпишитесь на хедхантеров и компании.
3. Подготовка к собеседованию:
• Техническая часть: Будьте готовы: Разобрать пейлоад (PCAP-файл) в Wireshark. Проанализировать образец лога и сказать, что произошло. Объяснить, как работает DDoS-атака и как ее обнаружить. Рассказать, что вы будете делать, если увидите алерт "Множественные неудачные попытки входа в систему".
• Поведенческая часть: Говорите о своем энтузиазме, желании учиться, внимательности к деталям. Ты должен быть лучше, чем другие в глазах работодателя, покажи уверенность, даже если ты боишься.
Ключевые навыки Junior SOC Analyst:
• Hard Skills: Понимание сетей, ОС, основ безопасности. Умение работать с SIEM, анализировать логи, понимать IOC. Базовые знания по IDS/IPS, фаерволам.
• Soft Skills: Аналитическое мышление, внимание к деталям, стрессоустойчивость (работа в сменах), умение ясно излагать мысли в отчете, желание постоянно учиться.
Об остальных направлениях расскажу в следующих постах.
Показать полностью...
+2
10

Nuxt 3 and 4: issue with multiple navigateTo calls

29 дн. назад
At work, on one of our projects, I ran into an issue in Nuxt 4 where a page component needs to perform different redirects via navigateTo() based on various conditions during the execution of the setup function. Something like this:

<template>
  Some page
</template>

<script lang="ts" setup>
if (1 + 1 === 2) {
  await navigateTo('/?abc=1', {
    redirectCode: 302,
  });
}

if (2 + 2 === 4) {
  await navigateTo('/?abc=2', {
    redirectCode: 302,
  });
}

if (3 + 3 === 6) {
  await navigateTo('/?abc=3', {
    redirectCode: 302,
  });
}

if (4 + 4 === 8) {
  await navigateTo('/?abc=4', {
    redirectCode: 302,
  });
}
</script>

This is where the problem appears: in the end, the redirect always goes to the very last URL, i.e. in the example above the navigation ends up at /?abc=4. I dug into the documentation but couldn't find anything built-in to prevent subsequent navigateTo calls from being triggered. It seems this behavior is related to vue router.

You can't write it like this either:
if (1 + 1 === 2) {
  await navigateTo('/?abc=1', {
    redirectCode: 302,
  });
  return; // not allowed in script setup
}

In the end, the only solution that worked was introducing a boolean variable and checking it before calling navigateTo:
let isAlreadyRedirected = false;

if (1 + 1 === 2) {
  await navigateTo('/?abc=1', {
    redirectCode: 302,
  });
  isAlreadyRedirected = true;
}

if (!isAlreadyRedirected && 2 + 2 === 4) {
  await navigateTo('/?abc=2', {
    redirectCode: 302,
  });
  isAlreadyRedirected = true;
}

if (!isAlreadyRedirected && 3 + 3 === 6) {
  await navigateTo('/?abc=3', {
    redirectCode: 302,
  });
  isAlreadyRedirected = true;
}

if (!isAlreadyRedirected && 4 + 4 === 8) {
  await navigateTo('/?abc=4', {
    redirectCode: 302,
  });
  isAlreadyRedirected = true;
}
Once again: this is the only thing that solved the problem for me. If you have any other solution, please let me know.
Показать полностью...
+2
3

Nuxt 3 и 4: проблема со множественными вызовами navigateTo

недавно
На работе на одном проекте столкнулся в Nuxt 4 с проблемой, когда в page-компоненте нужно делать разные редиректы через navigateTo() по различным условиям в процессе выполнения setup функции. Примерно так:

<template>
  Some page
</template>

<script lang="ts" setup>
if (1 + 1 === 2) {
  await navigateTo('/?abc=1', {
    redirectCode: 302,
  });
}

if (2 + 2 === 4) {
  await navigateTo('/?abc=2', {
    redirectCode: 302,
  });
}

if (3 + 3 === 6) {
  await navigateTo('/?abc=3', {
    redirectCode: 302,
  });
}

if (4 + 4 === 8) {
  await navigateTo('/?abc=4', {
    redirectCode: 302,
  });
}
</script>

Тут возникает проблема: в конечном итоге срабатывает редирект на самый последний урл, т.е. в коде выше переход будет на /?abc=4. Я порылся в документации, не нашёл ничего встроенного, чтобы избежать срабатывания последующих вызовов navigateTo. Вроде как это поведение связано с vue router.

Вот так написать тоже нельзя:
if (1 + 1 === 2) {
  await navigateTo('/?abc=1', {
    redirectCode: 302,
  });
  return; // так нельзя в script setup
}

Пришлось делать единственное решение - это завести boolean-переменную и проверять уже её.

let isAlreadyRedirected = false;

if (1 + 1 === 2) {
  await navigateTo('/?abc=1', {
    redirectCode: 302,
  });
  isAlreadyRedirected = true;
}

if (!isAlreadyRedirected && 2 + 2 === 4) {
  await navigateTo('/?abc=2', {
    redirectCode: 302,
  });
  isAlreadyRedirected = true;
}

if (!isAlreadyRedirected && 3 + 3 === 6) {
  await navigateTo('/?abc=3', {
    redirectCode: 302,
  });
  isAlreadyRedirected = true;
}

if (!isAlreadyRedirected && 4 + 4 === 8) {
  await navigateTo('/?abc=4', {
    redirectCode: 302,
  });
  isAlreadyRedirected = true;
}
Ещё раз - это единственное, что решило проблему. Если у вас есть какое-то другое решение, напишите плиз.
Показать полностью...
+2
16

Пагинация курсором в PostgreSQL: не путайте реальный CURSOR и фейковый курсор из WHERE

недавно
На любом собесе по system design и хайлоаду вас наверняка спросят про пагинацию. И вопрос этот с подвохом, т.к. на хайлоаде БД очень большие, с миллионами записей. Например, спросят как сделать бесконечную ленту последних постов с подгрузкой. И тут главное не обос****ться как я сделал на своем собесе 😂

Итак, что мы знаем про курсоры? В PostgreSQL есть самые настоящие курсосы! Они так и называются CURSOR. В постгресе они работают только внутри транзакций.
BEGIN;
DECLARE zhopa_cursor CURSOR FOR
  SELECT id, title, created_at FROM posts;

-- Получаем 10 строк:
FETCH 10 FROM zhopa_cursor;

-- Получаем еще следующие 10 строк сразу после места, где остановились до этого:
FETCH 10 FROM zhopa_cursor;

CLOSE zhopa_cursor;
COMMIT;

Обратите внимание, что обязательны транзакция и конкретное имя для курсора. Можно ли это использовать в вебе? Нет. Но я на собесе начал заливать про эти курсоры постгреса и про хранение имен курсоров, хотя непонятно как это все реализовать для веба. Типа не закрывать некоторое время транзакцию и держать открытой некоторое время пока идут http запросы? 😂

Короче, в веб разработке есть так называемые курсоры, которые никакими курсорами на самом деле не являются. Это обычные WHERE условия в SQL! Но за каким-то х***м это называется курсором.

Вот SQL получения первого списка постов для ленты:

SELECT id, title, created_at
FROM posts
ORDER BY created_at DESC, id DESC
LIMIT 20;

Далее браузер в http запросе для получения следующих 20 постов передает payload:

"last_created_at": "2026-01-15 12:30:00+00",
"last_id": 12345,

И бэк делает SQL запрос:

SELECT id, title, created_at
FROM posts
WHERE (created_at, id) < ($1, $2)
ORDER BY created_at DESC, id DESC
LIMIT 20;

Вот эта строка:
WHERE (created_at, id) < ($1, $2)
это и есть как бы наш курсор, хотя нифига это не курсор.

Такой запрос с псевдо-курсором намного быстрее, чем юзанье OFFSET когда постгрес читает все подходящие записи в таблице и тут же скипает часть их.
Показать полностью...
+2
10

Ещё один миф из JavaScript: нестрогое равенство

недавно
Очередной миф на сайте "Современный учебник JavaScript":
https://learn.javascript.ru/comparison
Цитата:
При сравнении значений разных типов JavaScript приводит каждое из них к числу.

Откуда дровишки? Правда о JavaScript написана только в одном месте - в документации языка. Поэтому смотрим доку:
https://262.ecma-international.org/16.0/index.html
EqualityExpression : EqualityExpression == RelationalExpression
 1. Let lRef be ? Evaluation of EqualityExpression.
 2. Let lVal be ? GetValue(lRef).
 3. Let rRef be ? Evaluation of RelationalExpression.
 4. Let rVal be ? GetValue(rRef).
 5. Return ? IsLooselyEqual(rVal, lVal).

Ага, значит, ищем IsLooselyEqual:

The abstract operation IsLooselyEqual takes arguments x (an ECMAScript language value) and y (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. It provides the semantics for the == operator. It performs the following steps when called:

1. If SameType(x, y) is true, then
   a. Return IsStrictlyEqual(x, y).
2. If x is null and y is undefined, return true.
3. If x is undefined and y is null, return true.
4. NOTE: This step is replaced in section B.3.6.2.
5. If x is a Number and y is a String, return ! IsLooselyEqual(x, ! ToNumber(y)).
6. If x is a String and y is a Number, return ! IsLooselyEqual(! ToNumber(x), y).
7. If x is a BigInt and y is a String, then
   a. Let n be StringToBigInt(y).
   b. If n is undefined, return false.
   c. Return ! IsLooselyEqual(x, n).
8. If x is a String and y is a BigInt, return ! IsLooselyEqual(y, x).
9. If x is a Boolean, return ! IsLooselyEqual(! ToNumber(x), y).
10. If y is a Boolean, return ! IsLooselyEqual(x, ! ToNumber(y)).
11. If x is either a String, a Number, a BigInt, or a Symbol and y is an Object, return ! IsLooselyEqual(x, ? ToPrimitive(y)).
12. If x is an Object and y is either a String, a Number, a BigInt, or a Symbol, return ! IsLooselyEqual(? ToPrimitive(x), y).
13. If x is a BigInt and y is a Number, or if x is a Number and y is a BigInt, then
   a. If x is not finite or y is not finite, return false.
   b. If ℝ(x) = ℝ(y), return true; otherwise return false.
14. Return false.

Вот и весь ответ. В JS есть чёткий алгоритм нестрогого сравнения, который назван IsLooselyEqual, а всё остальное - отсебятина.

null == undefined; // вернёт true

В Javascript при нестрогом сравнении null равен undefined не потому, что они оба привелись к 0, а потому что в пункте 2 чётко сказано, если первый оператор null и второй оператор undefined, то нужно вернуть true.
Показать полностью...
+1
12

Неочевидно опасное undefined behaviour в языке Си

недавно
Чтобы мозг не раскисал, учу Си. Язык простой и одновременно довольно сложный. А ещё в нём есть куча undefined behaviour - неопределённое поведение компилятора для пограничных случаев, которых на самом деле масса.

Вот пример простейшей функции:
int get_zero(void) {
  int num;
  return num & 0;
}
Переменная num не инициализирована, значит там могут сидеть любые "мусорные" биты.
& - это оператор побитового И, который сравнивает последовательно биты двух чисел и ставит в соответствующий бит возвращаемого числа 1, только если оба бита - это 1, иначе поставит туда 0.

Вроде всё просто и кажется, что функция всегда должна вернуть 0, ведь "побитовый и" с нулём всегда вернёт ноль.
123 // 00000000 00000000 00000000 01111011
0   // 00000000 00000000 00000000 00000000
Сравнение битов двух чисел выше всегда вернёт 0, т.к. второе число тоже 0. Неважно, какие там будут биты у первого числа, всегда в итоге 0.

Но проблема кода здесь связана со спецификацией Си. Код небезопасен, потому что теоретически компилятор может делать всё что угодно! Программа может "упасть", компилятор может удалить код и прочее. Компилятор имеет право делать что угодно в этом случае. Undefined behaviour - это поведение программы, для которого стандарт языка не накладывает никаких требований, стандарт не говорит, что должно или не должно произойти!

Т.е. писать код таким образом в Си - опасно. Даже переполнение обычного signed int (он же просто int) в Си - это уже undefined behaviour!
int x = 2147483647; // Максимальное значение
x = x + 1; // Опачки - undefined behaviour - рисково!
Вот такое приходится учить. А кто-то жалуется на сложности Golang.
+2
132

Внимание владельцам сайтов: Gmail почта позволяет создавать дубликаты аккаунтов в огромных количествах

недавно
На многих сайтах регистрация аккаунта осуществляется через email-адрес. Одно мыло - один аккаунт, вроде всё просто. Если забанить такого пользователя, то он не сможет зарегистрироваться снова на тот же самый email. Но это теоретически.

А практически при наличии одной электронной почты на Gmail можно создавать в интернет-сервисах огромное количество аккаунтов, не меняя адреса. Дело в том, что Gmail игнорирует регистр символов и наличие точек в имени пользователя.

Допустим есть пользователь c такой гугловской почтой:
vasya.pupkin.example@gmail.com
Если поменять регистр букв в имени юзера и отправить письмо на:
Vasya.PUPkin.example@gmail.com
то ему придёт письмо в настоящий ящик!

Сколько таких комбинаций возможно? Очень много!

Мало того, можно подобавлять точки в адрес:
va.s.ya.pu.p.k.in.example@gmail.com
и ему тоже придёт письмо в ящик-оригинал.
Даже если убрать точки из оригинала:
vasyapupkinexample@gmail.com
то письмо тоже придёт!

Представьте, сколько десятков тысяч комбинаций можно сделать с точками и изменениями регистра букв. Можно насоздавать тысячи вредительских аккаунтов, если сайт не защитился от этой "фишки" гуглопочты. Банить устанешь.
+2
159

ChatGPT 5 - туфта, не заменит программистов (реальный пример на Nuxt 4)

недавно
OpenAI зарелизили ChatGPT 5 - очередную самую крутую модель своей нейросети. А что в итоге?
Мой промпт:
Я делаю build nuxt 3 / nuxt 4 приложения.
Как понять в какие чанки какие файлы залезли?
Почему чанки такие большие?

До этого спрашивал у 4-ки - предлагал ставить vite-bundle-visualizer. Сразу говорю - это не надо делать, всё уже есть встроенное. Сегодня появилась возможность спросить у 5-ки - повторно спросил. Пятый ChatGPT опять предлагает поставить пакет, на этот раз rollup-plugin-visualizer.

Окей, пытаюсь добиться у него информации, которая должна по моему мнению быть показана в ответе (CLI команды), ChatGPT 5 выдаёт:
Пытаюсь узнать про "npx nuxi analyze", он ищет в интернете и долго думает и всё равно выдаёт:
Показать полностью...
+1
23

Весы с машинным зрением в Перекрёстке

недавно
В нашем городе опять технологическое чудо. К кассам самообслуживания все уже привыкли, но вот умные весы впервые поставили.
Показать полностью...
+2
15

Наконец-то купил себе лавандовый раф

недавно
Я айтишник. Тот самый айтишник, быть которым так модно стало в последние 5 лет. Хотя в самом IT я уже много-много лет с нулевых годов.

Так вот за свою жизнь я ни разу не пил лавандовый раф, хоть и айтишник (терпеть не могу такое название программистов). Исправился, купил.
Показать полностью...
+4
23

Nuxt продан: Vercel, который владеет Next.js, теперь владеет и главным SSR-фреймворком для Vue

недавно
Новость пришла откуда не ждали: монополизация во фронтенде - Vercel купил Накст. Они и так владели Некстом (главным SSR-фреймворков для Реакта), а теперь у них руки добрались и до вьюшной экосистемы.

Об этом сообщил создатель NuxtJS - Daniel Roe (ник danielroe на Гитхабе). Чисто теоретически Накст остаётся независимым, а Vercel купил только NuxtLabs, а также нанял себе ключевых разработчиков Накста. А практически - у них теперь Nuxt и они теперь будут задавать направление развития.

Не знаю, хорошо это и плохо, но монополизация - это точно плохо.
+2
149

Популярность Vue.js в России в 2025 году

недавно
В комментах на ютубе поспорил о популярности Vue JS. Мне доказывали, что балом правит Реакт, а Vue где-то на задворках. Увы, реакт-разработчики варятся в своём котле и не видят текущих тенденций. А текущая тенденция такова, что в России Вьюха постепенно откусывает кусок у Реакта.

Для анализа выбрал тематику недвижимости - застройщики. Список крупнейших застройщиков России в 2025 году, данные с Домклика, по количеству сделок:
1. ПИК
2. Самолет
3. ЮгСтройИнвест
4. Холдинг Setl Group
5. ССК
6. Страна Девелопмент
7. ГК ФСК
8. Гранель
9. ЛСР
10. DOGMA
11. АКВИЛОН
12. Домостроительный комбинат
13. ГК Кортрос
14. Талан
15. ГК "А101"
16. ЭНКО
17. Брусника
18. ГК Расцветай
19. GloraX
20. DARS Development
Смотрим сайты:
pik.ru - React
samolet.ru - Vue
gk-usi.ru - другое
setlgroup.ru - Vue
sskuban.ru - Vue
strana-development.ru - другое
fsk.ru - Vue
granelle.ru - Vue
lsr.ru - React
dogma.ru - React
group-akvilon.ru - Vue
dsk1.ru - Vue
kortros.ru - Vue
ижевск.талан.рф - Vue
a101.ru - Vue
enco.ru - другое
moskva.brusnika.ru - Vue
гкрасцветай.рф - другое
glorax.com - Vue
dars.ru - React

Ну как вам? Реакт - 4 сайта, VueJS - 12 сайтов. Сам не ожидал таких результатов, тут Вью опережает Реакт в 3 раза! Но обычно примерно 50/50 или даже чуть больше у Реакта.

Единственная сфера деятельности в России, где засилье Реакта - это банки. Так сложилось по историческим причинам, там началось всё с Реакта и остальные банки стали как обезьянки повторять и ставить себе Реакт тоже.

Многие React-разработчики просто не пробовали что-то другое. Я пробовал React, я пробовал Vue и сделал свой выбор в пользу второго. Стоит начать писать код на Vue и к React-у не захочется возвращаться.
Показать полностью...
+3
91

How to use Quill Editor with Nuxt 3 and SSR (Vue)

недавно
If you try to use Quill Editor with Nuxt 3 when rendering a page in SSR you will get this error:
500 document is not defined.
That means NodeJS doesn't have the global variable 'document'. Because SSR rendering is executed in
a NodeJS environment, not a browser.

The sad fact: <client-only> won't help with this problem. The problem with quill's code is that during import, it assumes it's being executed in the browser. I hope you remember that the code imported from the module is not just imported, but executed, i.e. the authors of Quill wrote it so that the 'document' object is immediately accessed there. Very bad.

One solution is to disable SSR, but its an awful solution. But the second solution is to use dynamic JS imports.

My <script lang="ts" setup> in QuillEditor.vue in Nuxt 3 project:
import 'quill/dist/quill.core.css';
import 'quill/dist/quill.snow.css';
// import Quill from 'quill'; // SSR problem with 'document', need to use dynamic import
import type Quill from 'quill';

const elemForQuillEditor = ref<HTMLDivElement|null>(null);

let editor: null|Quill = null; // Do not store in ref() - it causes bugs!

// ...

async function createQuillAndSetListeners() {
  const Quill = (await import('quill')).default; // This is most important thing - usage of JS dynamic import

  if (!elemForQuillEditor.value) return;
  editor = new Quill(elemForQuillEditor.value, {
    theme: 'snow',
    modules: {
      history: {
        delay: 2000,
        maxStack: 500,
        userOnly: true,
      },
      toolbar: {
        container: [
          ['bold', 'italic', 'underline', 'strike'],
          ['link'],
          [{ list: 'ordered' }, { list: 'bullet' }],
          [{ script: 'sub' }, { script: 'super' }],
          [{ header: [1, 2, 3, 4, 5, 6, false] }],
          [{ color: [] }, { background: [] }],
          ['clean'],
          ['undo', 'redo'],
        ],
        handlers: {
          undo() {
            editor?.history.undo();
          },
          redo() {
            editor?.history.redo();
          },
        },
      },
    },
    placeholder: props.placeholder,
  });
  
  editor.on('text-change', () => {
    if (!editor) return;
    // ... my other code
  });
}

// ...

onMounted(createQuillAndSetListeners);

Now your Quill editor will work in Nuxt 3 even during SSR!
+2
73

Как по-английски костыль в программировании

недавно
В русском языке не очень хороший код, который решает задачу некачественно, но всё же решает, принято называть костылём. Часто костыли делают как бы временным решением, но в большинстве случаев они остаются навсегда. В любой крупной кодовой базе всегда куча костылей, можете мне поверить.

В английском языке принято говорит "workaround", т.е. обходной путь. Но этот термин не несёт смысловой нагрузки, которую в русском языке означает костыль. Костыль - это значит код можно заменить нормальным кодом, это значит, что разрабу даже немного стыдно за код, но поделать пока ничего нельзя. А workaround - это более мягкий термин, этакий хак для достижения цели.

Так вот на английском языке есть аналогичное слово - kludge (кладж). Смело используйте его в своих слаках и гугл-митингах, когда общаетесь на английском. Никаких больше workaround, теперь только честный kludge!
+3
201

Хитрость spread-синтаксиса в JS

недавно
А вы знали, что теоретически spread-синтаксис в JS можно применять почти к любому типу.
Вот пример "обычного" использования:
// Массив спредится
console.log([...[1, 2, 3]]); // [1, 2, 3]
// Строка спредится
console.log([...'Famabara']); // ['F', 'a', 'm', 'a', 'b', 'a', 'r', 'a'] 
Но если попытаться заспредить number, то будет ошибка:
console.log([...555]); // Uncaught TypeError: 555 is not iterable
Не является iterable.
Так давайте сделаем iterable!
Number.prototype[Symbol.iterator] = function * () {
  yield 'Фамабара';
  yield 'лучше';
  yield 'всех';
}

console.log([...555]); // ['Фамабара', 'лучше', 'всех']
Мы успешно заспредили number! Толку от этого никакого, на сам факт забавен.
Можно джунов за собесах мучить :)
+4
182

Firefox не чинит баг уже 13 лет

недавно
На Famabara появилась возможность перетаскивать мышкой части формы поста, если лень сортировать кнопками вверх/вниз. И, оказалось, что эта функция не работает в Firefox.
Багу 13 лет!!! Вы когда-нибудь видели, чтобы у популярного продукта не чинили баг столько времени? Пожалуйста:
https://bugzilla.mozilla.org/show_bug.cgi?id=739071

Если у предка стоит атрибут draggable="true", то клик мышкой по <textarea >или по <input type="text"> не позволит сфокусировать нормально в нужном месте текста. Мигающий промт возникнет или в начале текста или в том месте, где уже был до блюра.

<div draggable="true">
  <input value="Кликните в середину текста" type="text" />
</div>

Ну это совсем позорище! Багу поставили Priority: P3 и Severity: S3 (типа неважные вещи), а все дублирующие баг-репорты закрывают уже в течение 13 лет.

Есть одно решение, найденное в схожем багрепорте FF, но для contenteditable="true" - надо зажать Alt и кликнуть. Удобно, да? :)
+2
134

Как в Git безопасно поправить коммит в удалённой (remote) ветке

недавно
Представим вы несколько дней работали, писали код и наконец-то сделали коммит:
git commit -m "#715 changed color of button from red to green"
git push
И тут вы понимаете, что забыли убрать какой-нибудь console.log() или fmt.Println().
Можно добавить ещё один коммит поверх, что-то вроде:
git commit -m "#715 clean unnecessary code"
Но в некоторых командах это могут посчитать мусорным коммитом. Что делать?

Вместо второго коммита "правим" первый коммит, дописывая amend:
git commit --amend -m "#715 changed color of button from red to green"
И теперь можно пушить снова. Но сервер не даст запушить, ведь у нас локально и на ремоуте уже разные истории одной ветки. Можно запушфорсить:
git push force
Но это может быть очень плохо, если над веткой работает несколько человек. Кто-то мог уже поверх нашего коммита свои коммиты накатать. Но есть хороший параметр force-with-lease, который перезапишет ветку только тогда, когда никто поверх не дописал свои коммиты:
git push --force-with-lease
В этом случае никто не пострадает.
+3
79

TypeScript скоро станет в 10 раз быстрее

недавно
Андерс Хейлсберг (автор Тайпскрипта) опубликовал пост в блоге:
https://devblogs.microsoft.com/typescript/typescript-native-port/

В общем, TypeScript скоро станет в 10 раз быстрее, вернее, он уже стал таким, просто пока эту версию не сделали общедоступной.

Вот такой прирост скорости компиляции крупных проектов теперь показывает tsc:
Как видно, прирост на порядок - т.е. примерно в 10 раз. Достигается это за счет использования Golang для работы tsc, а не JS. Сам по себе JS быстрый, но он упирается в один поток. А кто писал на Go, то знает, насколько легко там запустить горутину. Теперь tsc будет использовать несколько имеющих потоков, что и даст прирост скорости компиляции.

Обратите внимание, это полноценная работа tsc, а не как у esbuild, где только транспиляция без проверки типов.

На момент написания этого поста текущая версия TypeScript - 5.8.2. Следующая мажорная версия - 6-я - будет всё ещё на JS-е, а вот 7-я версия будет уже на "нативном" коде, т.е. компилироваться из Go. Автор их так и называет:
For the sake of clarity, we’ll refer to them simply as TypeScript 6 (JS) and TypeScript 7 (native)

В общем, новость хорошая. Быстрее будет не только компиляция в JS, то и VSCode будет работать быстрее, потому что там все подсказки в редакторе, даже если это JS-код, реализованы с помощью тайпскрипта.
Показать полностью...
+3
142
1
2