Веб

Ограничение выдачи купонов: Fingerprint + IP

Узнайте, как привязать купоны к устройству с помощью device fingerprint и IP‑адреса, реализовать hard‑ban и защитить систему от мошенников.

Как ограничить выдачу купонов только на одном компьютере/устройстве, используя клиентский уникальный идентификатор (fingerprint) или IP‑адрес, чтобы сделать получение купона более защищённым (hard ban)?

Купоны, которые выдаются только на одном устройстве, можно защитить, привязывая их к уникальному идентификатору клиента — «device fingerprint» — и сочетая это с ограничением по IP‑адресу. Такой подход позволяет быстро распознать и исключить злоумышленников, а также реализовать hard‑ban (постоянное блокирование) для устройств, которые нарушают правила.

Содержание

Понятие и преимущества Device Fingerprint

Device Fingerprint – это уникальный цифровой отпечаток устройства, сформированный на основе совокупности характеристик браузера, системы и среды выполнения.

  • Независимость от аккаунта – даже без регистрации можно идентифицировать устройство.
  • Трудно подделать – большинство браузеров используют множество «параметров» (canvas, WebGL, шрифты, таймзоны), которые сложно синхронно изменить.
  • Подходит для анонимных пользователей – не требует cookie‑ов, которые могут быть удалены.

Согласно Fingerprint.com, использование отпечатков позволяет ограничить выдачу купонов до одного на устройство, снижая риск мошенничества.

Ограничение по IP‑адресу и его ограничения

IP‑адреса часто применяются для базовой фильтрации, но имеют ряд проблем:

  • Общие сети – офисы, гостиницы, мобильные точки доступа обслуживают множество пользователей с одним IP.
  • VPN/прокси – злоумышленники могут менять IP, обходя ограничения.
  • Непостоянство – динамические IP могут смениться без предупреждения.

Исследование на Security StackExchange подтверждает, что полагаться исключительно на IP – «плохая идея», поскольку это приводит к ложным блокировкам и позволяет злоумышленникам менять IP.

Реализация ограничения по Fingerprint

  1. Сбор отпечатка

    javascript
    import FingerprintJS from '@fingerprintjs/fingerprintjs';
    
    async function getFingerprint() {
      const fp = await FingerprintJS.load();
      const result = await fp.get();          // { visitorId: '...', components: [...] }
      return result.visitorId;                 // Хэш‑отпечатка
    }
    
  2. Отправка на сервер
    При запросе получения купона клиент отправляет visitorId вместе с запросом.

  3. Проверка на сервере

    • Храните в базе данных маппинг visitorId → usedCoupon.
    • При новом запросе проверяйте, использовался ли уже купон для данного visitorId.
    • Если да – отклоните запрос с сообщением «Купон уже использован на этом устройстве».
  4. Объединение с IP

    • Сохраняйте ipAddress вместе с visitorId.
    • При подозрительной активности, например, 5 попыток за 10 минут, добавьте visitorId в черный список и блокируйте дальнейшие запросы от этого IP.

Пример таблицы хранения:

visitorId (hash) couponCode ipAddress lastUsed status
5f1c2e… SAVE10 192.0.2.1 2025‑08‑01 active
3a9d4b… 198.51.100.5 2025‑07‑25 banned

Hard Ban и прогрессивное ограничение

Hard Ban – непрерывное блокирование устройства или IP после подтверждённого злоупотребления.
WorkOS Radar демонстрирует, как реализовать прогрессивное ограничение:

  • Нижний порог – 3 неудачные попытки → запрос Captcha.
  • Средний порог – 5 неудачных попыток → временный блок (30 мин).
  • Высокий порог – 10 неудачных попыток → hard‑ban (постоянное блокирование) — добавление в черный список.

Пример реализации в Express.js:

js
const banned = new Set(); // Хранилище черного списка

app.post('/redeem', async (req, res) => {
  const { visitorId, coupon } = req.body;
  if (banned.has(visitorId)) return res.status(403).send('Доступ запрещён');

  // Проверяем, использовался ли купон
  const used = await db.findOne({ visitorId });
  if (used) return res.status(400).send('Купон уже использован');

  // Логика использования купона…
});

После превышения порога добавляем visitorId в banned и сохраняем запись в базе для аудита.

Практические советы и лучшие практики

Практика Что делает Как реализовать
Хеширование отпечатка Предотвращает прямой доступ к идентификатору visitorId = SHA256(visitorId)
Таймауты и повторные проверки Держит систему в актуальном состоянии setInterval(checkExpiredBans)
Промежуточный слой кэша Ускоряет проверку Redis, Memcached
Регулярные обновления библиотек Убирает уязвимости Проверять версии Fingerprint.js
Логи и мониторинг Позволяет отслеживать аномалии ELK stack, Grafana

Как избежать обхода

  • Блокировка JavaScript – большинство отпечатков зависят от JS, поэтому отключение JS может обойти защиту.
    • Решение: проверять наличие ключевых скриптов через navigator и отклонять запросы без JS.
  • Прокси/Анонимайзеры – смена IP не спасёт от отпечатка.
    • Решение: использовать комбинированный подход – IP + Fingerprint.
  • Фальшивые отпечатки – некоторые библиотеки позволяют подделать данные.
    • Решение: включить «проверку» на сервере, сравнивая несколько компонентов отпечатка и отклонять подозрительные.

Заключение

  • Device Fingerprint – основной инструмент для ограничения купонов до одного на устройство.
  • IP‑адрес используется в паре для усиления защиты, но не должен быть единственным критерием.
  • Hard Ban реализуется через постоянный черный список отпечатков и IP, с прогрессивной остановкой при подозрительной активности.
  • Внедряйте кэширование, логирование и регулярные обновления библиотек, чтобы система оставалась надёжной и масштабируемой.
  • Следуйте лучшим практикам, чтобы балансировать между безопасностью и удобством реальных пользователей.

Источники

  1. Fingerprint.com – Prevent Coupon and Promo Abuse
  2. WorkOS Radar – Rate Limiting with Device Fingerprinting
  3. Security StackExchange – Limit REST API calls by fingerprinting and IP
  4. Vouchery.io – Promo Code Abuse Prevention
  5. FingerprintJS Demo – Coupon Fraud
  6. Mozilla MDN – Device Fingerprinting
Авторы
Проверено модерацией
Модерация