CORS

Тема дорожной карты · Node.js

CORS (Cross-Origin Resource Sharing) — это HTTP-механизм, сообщающий браузерам, будет ли серверное приложение принимать запросы, поступающие с другого домена, порта или протокола. В приложениях Node.js и Express.js CORS-заголовки, такие как Access-Control-Allow-Origin, должны быть настроены корректно, чтобы JavaScript-клиенты во фронтенде могли обращаться к вашему API без блокировки политикой браузера о единственном источнике (same-origin policy). Наиболее распространённый способ обработки CORS в серверном приложении Express.js — использование npm-пакета cors, позволяющего настроить разрешённые источники, методы и заголовки всего одним вызовом middleware. Без корректной настройки CORS легитимные запросы к API от вашего собственного фронтенда будут завершаться ошибкой, поэтому это является критически важным аспектом для любого серверного приложения Node.js, обслуживающего браузерного клиента. В продакшне всегда ограничивайте Access-Control-Allow-Origin доверенными доменами, не используя шаблонный символ *, чтобы не открывать сервер нежелательным кросс-доменным запросам.

Как это работает

CORS имеет слои: валидация input (zod, ajv) на границе, параметризованные SQL-запросы, эскейп пользовательского контента в HTML (или templating engine с авто-эскейпом), HTTPS везде (терминируется на reverse proxy), секреты в env (не в репо), правильные флаги JWT/cookie (HttpOnly, Secure, SameSite). Middleware helmet добавляет разумные HTTP-заголовки (HSTS, X-Frame-Options, CSP).

Когда применять

Security-baseline с первого дня: rate-limit на auth-эндпойнтах, лимит размера body, хеш паролей через bcrypt/argon2, подпись JWT сильным секретом + короткий TTL, валидация каждого input. npm audit в CI с гейтом на high/critical. OWASP ASVS — как чек-лист при планировании. Penetration test перед публичным запуском — bug bounty дешевле инцидентов.

Типичные ошибки

Ловушки CORS: игнор CVE в зависимостях (каждый — потенциальный инцидент); JWT-секрет утёк в клиентский код или git-history; SQL-инъекция, потому что кто-то забыл параметр (SELECT * FROM u WHERE id = ${req.query.id} — никогда); eval или Function() на user-input; пароли в MD5/SHA1 (используйте argon2id с правильными параметрами). Security — это процесс, не разовый аудит.

Связанные понятия

Полезные ресурсы