Чистка читеров
Добавлено: 06 май 2009, 14:40
Проблема читерства - одна из самых серьезных в использовании различных систем электронного голосования. Мы столкнулись с ней при организации конкурсов рисунков и фотографий (http://shgpi.edu.ru/contests/). Со своей (программистской) стороны я постарался с ней разобраться, но все решения наталкиваются на все возрастающую изобретательность читеров. Рассмотрим одно из последних решений проблемы (наверняка - временное). Дано - таблица голосов пользователей. Ее структура:
Казалось-бы, пускать голосовать по уникальному IP-адресу (REMOTE_ADDR) и все. Однако не все так просто. Во первых, хотелось бы пускать с одного компьютера не единожды, а как минимум - раз в час (пусть проголосует вся семья!). Во вторых, IP-адрес - вещь на самом деле крайне не уникальная. Достаточно обеспечить выход в интернет через прокси-сервер или NAT и вот уже на IP адрес положиться нельзя. К счастью, есть еще несколько параметров, по которым с большой вероятностью можно судить об уникальности компьютера.
Во первых, проблему с прокси частично решает поле HTTP_X_FORWARDED_FOR (конечно - если это "честный" прокси, а не анонимный крякерский). В нем сохраняются адреса всех прокси, через которые прошел запрос, в начале списка - адрес отправителя. Значит с большой вероятностью HTTP_X_FORWARDED_FOR обеспечит нам уникальный адрес пользователя прокси.
Теперь о проблеме NAT. С первого взгляда проблема нерешаемая, ведь адрес, с которого пришел запрос - это адрес шлюза, а не клиента. К счастью, при использовании NAT работают обычно с пулом адресов, что повышает вероятность корректного голосования нескольких различных юзеров. Если в дополнение применять HTTP_USER_AGENT - идентификацию, посылаемую браузером, и HTTP_COOKIE - отправляемые куки, то можем получить вполне приемлимый результат, а именно - комбинацию HTTP_USER_AGENT и HTTP_X_FORWARDED_FOR (последний удается использовать в любом случае, т.к. наш сервер находится за обратным прокси) для идентификации компьютера, а добавив HTTP_COOKIE - для идентификации сеанса.
Хороша система, да одна проблема - читеры ее взламывают на раз-два-три.
Продолжение следует ...
- Код: Выделить всё
CREATE TABLE `shgpi`.`gallery_foto_votes_3` (
`id` bigint(20) NOT NULL auto_increment,
`toUser` bigint(20) NOT NULL default '0',
`vote_date` datetime NOT NULL default '0000-00-00 00:00:00',
`REMOTE_ADDR` varchar(30) NOT NULL default '',
`REMOTE_PORT` varchar(10) NOT NULL default '',
`HTTP_COOKIE` varchar(2500) NOT NULL default '',
`HTTP_VIA` varchar(250) NOT NULL default '',
`HTTP_X_FORWARDED_FOR` varchar(250) NOT NULL default '',
`HTTP_USER_AGENT` varchar(255) NOT NULL default '',
`HTTP_ACCEPT` varchar(50) NOT NULL default '',
`HTTP_ACCEPT_LANGUAGE` varchar(50) NOT NULL default '',
`HTTP_ACCEPT_ENCODING` varchar(50) NOT NULL default '',
`HTTP_ACCEPT_CHARSET` varchar(50) NOT NULL default '',
`HTTP_KEEP_ALIVE` varchar(10) NOT NULL default '',
`HTTP_CACHE_CONTROL` varchar(10) NOT NULL default '',
`HTTP_CONNECTION` varchar(20) NOT NULL default '',
PRIMARY KEY (`id`),
KEY `toUser` (`toUser`)
)
Казалось-бы, пускать голосовать по уникальному IP-адресу (REMOTE_ADDR) и все. Однако не все так просто. Во первых, хотелось бы пускать с одного компьютера не единожды, а как минимум - раз в час (пусть проголосует вся семья!). Во вторых, IP-адрес - вещь на самом деле крайне не уникальная. Достаточно обеспечить выход в интернет через прокси-сервер или NAT и вот уже на IP адрес положиться нельзя. К счастью, есть еще несколько параметров, по которым с большой вероятностью можно судить об уникальности компьютера.
Во первых, проблему с прокси частично решает поле HTTP_X_FORWARDED_FOR (конечно - если это "честный" прокси, а не анонимный крякерский). В нем сохраняются адреса всех прокси, через которые прошел запрос, в начале списка - адрес отправителя. Значит с большой вероятностью HTTP_X_FORWARDED_FOR обеспечит нам уникальный адрес пользователя прокси.
Теперь о проблеме NAT. С первого взгляда проблема нерешаемая, ведь адрес, с которого пришел запрос - это адрес шлюза, а не клиента. К счастью, при использовании NAT работают обычно с пулом адресов, что повышает вероятность корректного голосования нескольких различных юзеров. Если в дополнение применять HTTP_USER_AGENT - идентификацию, посылаемую браузером, и HTTP_COOKIE - отправляемые куки, то можем получить вполне приемлимый результат, а именно - комбинацию HTTP_USER_AGENT и HTTP_X_FORWARDED_FOR (последний удается использовать в любом случае, т.к. наш сервер находится за обратным прокси) для идентификации компьютера, а добавив HTTP_COOKIE - для идентификации сеанса.
Хороша система, да одна проблема - читеры ее взламывают на раз-два-три.
Продолжение следует ...