← Назад к вопросам

Какая безопасность нарушится с target="_blank"?

1.0 Junior🔥 71 комментариев
#Soft Skills и рабочие процессы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Уязвимость target="_blank": Tabnabbing

Использование target="_blank" без дополнительных мер безопасности может привести к серьёзной уязвимости под названием tabnabbing (захват вкладки).

Суть проблемы

Когда вы открываете ссылку с target="_blank", новая вкладка получает доступ к объекту window.opener. Это означает, что код на внешнем сайте может:

  1. Перенаправить исходную вкладку на фишинговый сайт
  2. Подменить содержимое страницы
  3. Украсть данные пользователя

Сценарий атаки:

  1. Пользователь на вашем сайте нажимает ссылку на внешний (недоверенный) сайт
  2. target="_blank" открывает новую вкладку
  3. На внешнем сайте может быть вредоносный код:
// На внешнем (вредоносном) сайте
window.opener.location = "https://phishing-site.com/fake-login";
// Пользователь видит на исходной вкладке поддельную страницу входа
  1. Пользователь видит свой сайт, но это фишинг, и вводит пароль
  2. Атакующий получает доступ к аккаунту

Решение: rel="noopener noreferrer"

Правильный способ использования target="_blank":

<!-- Неправильно -->
<a href="https://external-site.com" target="_blank">Открыть</a>

<!-- Правильно -->
<a href="https://external-site.com" target="_blank" rel="noopener noreferrer">Открыть</a>

Что делают эти атрибуты:

  • rel="noopener" — отключает доступ к window.opener. Это самое важное для защиты от tabnabbing
  • rel="noreferrer" — не отправляет HTTP Referer на внешний сайт (добавляет приватность)

В современных браузерах (Chrome 49+, Firefox 52+) target="_blank" автоматически устанавливает noopener, но рекомендуется указывать явно для совместимости.

React/Next.js: правильная реализация

// Компонент с внешней ссылкой
export function ExternalLink({ href, children }) {
  return (
    <a 
      href={href} 
      target="_blank" 
      rel="noopener noreferrer"
    >
      {children}
    </a>
  );
}

// Использование
<ExternalLink href="https://example.com">Нажми меня</ExternalLink>

Или можно использовать кастомный хук для упрощения:

function useExternalLink(href) {
  return {
    href,
    target: "_blank",
    rel: "noopener noreferrer"
  };
}

// В компоненте
<a {...useExternalLink("https://example.com")}>Ссылка</a>

Дополнительные меры безопасности

1. CSP (Content Security Policy) Настройте CSP заголовок, чтобы ограничить доступ к window.opener:

Content-Security-Policy: default-src "self"; script-src "self"

2. Валидация ссылок Проверяйте, что href указывает на безопасный протокол:

function isValidExternalLink(href) {
  try {
    const url = new URL(href);
    return ["http:", "https:"].includes(url.protocol);
  } catch {
    return false;
  }
}

// Использование
{isValidExternalLink(href) && (
  <a href={href} target="_blank" rel="noopener noreferrer">
    Ссылка
  </a>
)}

3. Whitelist доменов Для критичных ссылок делайте whitelist:

const TRUSTED_DOMAINS = ["github.com", "stackoverflow.com", "mdn.org"];

function isTrustedLink(href) {
  const url = new URL(href);
  return TRUSTED_DOMAINS.includes(url.hostname);
}

Заключение

target="_blank" — не опасен сам по себе, но **всегда используй rel="noopener noreferrer"**. Это стандартная практика и защищает пользователей от tabnabbing атак. В фронтенде React/Next.js рекомендуется либо использовать утилиты для форматирования внешних ссылок, либо создать переиспользуемый компонент ExternalLink.