Я пытаюсь построить MySQL
запрос (или PHP
скрипт), чтобы идентифицировать пользователей, которые делятся своими учетными данными для входа в систему с другими людьми. Я хочу не заставлять пользователей явно регистрировать свои устройства (как это делают банки), потому что я хочу минимизировать неудобства для настоящих пользователей. Я понимаю, что нет никакого способа полностью устранить ложные срабатывания или ложные отрицания, но я хочу сделать лучшее, что могу.
Во время входа на сервер сервер сохраняет ip address
, user id
и browser fingerprint
(fingerprintjs2) в базу данных. (Отпечаток пальца является полууникальным значением браузера).
Если каждый пользователь использовал только один ip
это было бы легко — я бы просто SELECT
все пользователи, которые зашли на сайт с нескольких ips. Это, конечно, не тот случай. В реальном мире пользователи могут войти в систему с нескольких подключений (например, работа, дом, телефон), а в случае dynamic ips
сам адрес может измениться.
У большинства пользователей не будет более 5 разных подключений (есть исключения, но не так много). Я согласен с тем, что (возможно) нет способа определить, входит ли один человек в систему с 5 разных подключений или 5 разных людей входят в систему с одного подключения.
Пока мой запрос захватывает только пользователей, которые вошли в систему с более 5 соединения, проблема «множественных соединений на пользователя» выходит за рамки уравнения.
Теперь я должен столкнуться с проблемой пользователей с dynamic ips
,
Насколько я понимаю, большинство ISPs
которые обеспечивают динамические соединения, изменят только последнюю группу цифр (я хотел бы получить подтверждение или статистику по этому поводу).
Если мой запрос рассматривает «соединение» как первые 3 группы ip
цифры, то проблема решается для пользователей с ISPs
которые меняют только последнюю группу цифр.
Вот простой MySQL
запрос, который я написал. Это отличает группы ips
(без последней группы цифр) по имени пользователя и показывает те имена пользователей, которые связаны с более чем 5 из них:
SELECT
GROUP_CONCAT(DISTINCT ip SEPARATOR '/') AS ips,
username,
COUNT(DISTINCT ip) AS n_ips
FROM
(
SELECT DISTINCT user_id, SUBSTRING_INDEX(ip_address,'.',3) AS ip
FROM
ip_logins
WHERE
login_date > DATE_SUB(NOW(), INTERVAL 7 DAY )
) AS weekips
JOIN users AS u ON (
u.id = weekips.user_id
)
GROUP BY
username
HAVING
COUNT(n_ips) > 5
ORDER BY
n_ips DESC
То, как я намерен иметь дело с «полностью» dynamic ips
(где любая цифра может измениться) путем подсчета всех входов в систему, которые разделяют browser fingerprint
как единое «соединение». Я рассуждаю так: если пользователь вошел в систему с нескольких ips с одинаковыми browser fingerprint
, то все эти входы в систему, вероятно, от одного человека с «полностью» dynamic ip
, Это не решает проблему полностью, потому что не удается учесть пользователей, которые используют несколько браузеров (так как отпечаток браузера будет другим).
Я мог бы использовать печенье вместо browser fingerprint
, но они могут быть удалены или отключены.
Я хотел бы получить информацию о моей стратегии и несколько советов о том, как ее улучшить. Если уже есть реализация с открытым исходным кодом что-то вроде этого (в PHP
) — Я хотел бы знать; нет смысла изобретать велосипед.
Почему бы не начать с простого, например: определения, когда пользователь обращается к сайту с двух или более IP-адресов одновременно, с порогом <30 с между запросами. Это уже должно поймать много плохих парней.
id account_id ip_address time page
1 1 1.1.1.1 00:00:00 /weather/amsterdam/today <-- multiple IPs
2 1 2.2.2.2 00:00:05 /weather/london/yesterday <-- on the same
3 1 3.3.3.3 00:00:06 /weather/brussels/today <-- account
4 1 4.4.4.4 02:02:02 /weather/paris/tomorrow
Других решений пока нет …