Pull to refresh

Comments 37

Я бы задал все предложенные вопросы на Тостере и получил правильные ответы.
Нельзя просто так взять и получить правильные ответы на вопросы ;)
Для некоторых вопросов из этого теста требуется уточнение контекста. Например, вопрос про экранирование символов перед вставкой в базу данных для защиты от SQL-Injection. Какие функции для этого подходят? addslashes, например, для одних кодировок годится, а для других нет (подробнее тут).
У меня уже была идея написать бота под этот тест по последнему варианту, но когда поставили каптчу, то понял, что уже кто-то воспользовался этим, поэтому интерес пропал.

Предлагаю следующие варианты защиты теста:
— Ввод чисел в качестве ответов (например, задачи по результирующий набор данных при джойнах или в задачках типа «что будет результатом работы скрипта»)
— Варьировать количество общих ответов и правильных ответов на вопрос.
— Изменять текст в вопросах и ответах, чтобы сложнее было технически привязаться.
— Добавить вопросы вида «введите название функции, которая делает ...»

PS: Кстати существуют распознавалки recaptcha. Там вероятность хоть и не очень высокая, но для автоматического перебора хватает. Добавьте еще интервал между ответами и бан на N минут в случае, если отвечают очень быстро. Ну и бан по IP на частый неправильный ввод каптчи.
Кстати можно добавить элементы фана:
В случае, если с одного IP было много тестов за последние 24 часа, то вставлять в тест вопросы с отсутствием правильных ответов, непрофильные вопросы («Какого цвета зебра?»), а в результатах теста говорить о том, что «За сегодня вы уже славно потрудились, поэтому ваш балл мы не покажем. Держите просто красивую циферку: rand(1,100)»
И любой институт за NAT-ом убъёт день экзамена, если рискнёт экзамен замутить через этот тест, да?
Методом, который я привёл — никто не воспользовался пока. Я его сам придумал, пока пытался оценить сходимость адаптивного метода. Что касается Ваших советов, они все по делу, спасибо.
Может проще ограничить количество прохождениq теста с одного IP?
Переборщики теста с динамическим IP радуются этому комментарию
Лучше тогда просто по авторизации. Один пользователь — один тест с интервалом растущим. Плюс каждому пользователю давать кроме стандартного набора ещё пару вопросов конкретно для этого аккаунта.
Алексей, спасибо за статью)) Засел за написание бота, который сможет пробить защиту)
Уберите капчу, она отпугнет людей, а не ботов.
Для ботов придумывайте стратегии их определения и нейтрализации.
Этим вы будете повышать не только свои умения/знания, но и чужие — ботописателей.
Капчи бояться — в Интернет не ходить!
Супер, очередной пример того, что человеческая интуиция постоянно делает ошибки на порядки, когда речь заходит о вероятностях.

10^4 прохождений с капчей — это 7 долларов на антигейт аккаунт, так что защита так себе ;) Отсутствие четкого фидбека — да, вариант, но тогда пузомерку с рейтингом придется убить.
Пол-цента за капчу, да, но послушай: это же надо значительно сильнее заморочиться :) Что касается пузомерки: её и так пришлось ограничить из-за хэд-хантеров, так что со временем топскор сделаем и всё.
С новыми тестами (у меня куплено уже под сотню новых) наверняка четкий фидбек уберу — это самое действенное.
С отсутствием четкого фидбэка можно добавить простейший бот-детектор, при срабатывании которого результат теста всегда будет отрицательный. Детектор должен быть именно что тупой, но zero false positive для реального user-agent.
Есть гипотеза, как можно модифицировать идею с рейтингом ответов. Пусть изначально все ответы имеют равный рейтинг 0,2. При каждом тесте ответ на конкретный вопрос выбирается случайным образом, вероятность выбора конкретного ответа равна его рейтингу… Если тест прошел «удачно», то рейтинг использованного ответа повышается (соответственно, рейтинги остальных ответов понижаются). Если тест прошел «плохо», то рейтинги использованный ответов понижаются. Причем чем лучше/хуже результат теста, тем сильнее повышаются/понижаются рейтинги. Есть предположение, что такой алгоритм будет сходиться быстрее, но это только предположение.
Также мне кажется, что тут могут неплохо генетические алгоритмы сработать, но с хитрой процедурой скрещивания, учитывающей только те гены (вопросы), которые были в конкретном тесте.
Отличные доподнения, спасибо! Насчет модификации: возможно, но у меня не было цели найти наиболее эффективный алгоритм, я просто хотел показать математически, как интуиция подводит :) Что касается генетических алгоритмов: именно с них я и начал, но там тяжело показать сходимость. Фактически я случайно придумал вот этот другой способ, и он оказался куда более наглядным.
Против расплывчатого фитбека на помощь приходит регрессионный анализ. Аналогично, решению СЛАУ, каждый вариант ответа — это случайная величина. Задача сводится к нахождению коэффициентов линейной регрессии, например, методом наименьших квадратов. Это ничуть не сложнее, чем искать решения линейного уравнения. Лично я бы начал писать своих ботов с этого метода.

Отличить же ботовода я предложил бы анализируя время ответа или поведение на сайте (что чуть сложнее).
Погоди. Если у тебя каждый вариант ответа — случайная величина, то скорее всего при четких баллах ты попадешь в интервал от 0 до 12. А теперь представь, что тебе вместо 0...12 будут отвечать всегда одно «не прошел». Какая регрессия? У тебя просто нет информации, никакой. Весь прикол не в том, что метод не сработает — сработает и тот же адаптивный — а в том, что требуется значительно бОльшее число испытаний, чтобы получить «разные» варианты.
Почему нет информации? Да же если на выходе будет всего два варианта (да/нет), то этот метод будет вполне эффективен. Если есть хоть какая-то корреляция между ответами и конечным результатом, то метод найдет коэффициенты.
Но конечно же, и это вполне очевидно, что для получения более ли менее вменяемого результата понадобиться проводить больше испытаний.
Но вопрос в том что сам метод (как и решение СЛАУ) очень прост. Также уверен что в данном случае он будет значительно эффективнее каких-нибудь генетических алгоритмов в чистом их виде.
Почти все все ответы будут «нет» = нет информации. Чтобы было «да» — нужно сильно больше испытаний. Можно так подобрать разделение на уровни, что ждать надо будет _очень_ долго. Но ты прав про регрессионный анализ, он не сложнее решения уравнений, и будет работать.
На самом деле для версии теста без каптчи есть еще более быстрый вариант:
Поскольку неверных ответов больше, чем верных, то мы можем искать именно неверные ответы, отвечая по одному ответу в каждом вопросе.

Запускаем первичный перебор тестов:
1. Если в результате мы получили 0 баллов, значит на все вопросы ответили неверно. Такие события будут происходить довольно часто: только сейчас в трех тестах выбирал только первые ответы и в одном набрал 0 баллов.
2. Если в результате мы получили > 0 баллов, значит где-то мы ответили правильно — такие результаты нам пригодятся.

После каждого теста, используя информацию об уже выявленных правильных ответах и статистику по 2му пункту (где тесты были > 0 баллов), мы сможем быстрее выяснить ответы по остальным вопросам.
Таким образом мы выявим ответы на вопросы, в которых правильным является 1 ответ.

Запускаем вторичный перебор тестов для выявления ответов на вопросы, в которых более 1 ответа:
Зная вопросы с одним ответом и используя статистику по 2ому пункту первичного перебора мы сможем адаптивным методом быстрее выявить ответы на «правильные вопросы с несколькими ответами».

В математику вдаваться не стал, но потребуется явно меньше 10^4 переборов.

Можно изначально руками пройти несколько тестов, выбирая заведомо неверные ответы, для получения 0 баллов. На такой «ручной» статистике данный метод отработает еще быстрее.
Проблема с тем тестом была в том, что 0 баллов никак не получалось набрать. Возможно там есть защита на этот случай, что если баллов меньше 7 — то выдавать случайное число от 0 до 7 (или другого минимального числа)
Как же это у меня получилось в 1 случае из трех?
Возможно я плохо пытался. Тогда вообще проблемы нету — держим базу неверных ответов и подбираем ответы на вопросы по-очереди. То есть в начале один вопрос перебираем а все остальные варианты берём неверные ответы.

Кстати вот пример дополнительной защиты — если пользователь набрал меньше 5 баллов. То не говорить ему сколько баллов, просто писать что-то вроде «вы не прошли».
Я как раз примерно это и описал в своем комментарии ;)
да, я в-общем сделал две вещи пока: капча + для маленького результата ничего не показываю.
Тогда метод с поиском неправильных ответов уже не прокатит, но у меня есть еще пара идей.
Это все варианты адаптивных методов, решение должно работать. Но думаю, что Вам только кажется, будто сходимость будет лучше. Именно потому, что «в математику вдаваться не стал».
Окей. Попробую реализовать данный метод, о результатах отпишусь здесь.
Спасибо, не знал что всё так просто вскрывается…
Вообще, идея для бота рейтить ответы фактически по степени влияния на цифру результата теста — это круто! Это как раз пример «взгляда с правильной стороны» и «решения задачи путём её переформулирования».
Спасибо за статью, с меня небольшое предложение относительно определения бота.
По своей сущности большинство ботов — парсят DOM и заполняют поля для ввода стандартными значениями. Можно сверстать страницу так, что форма будет включать скрытые посредством верстки поля, которые будут пропарсены ботом. Плюс к умным ботам, они могут определять какие поля являются обязательными (можно использовать этот факт). Вполне возможно данный аспект можно использовать и проверять наличие скрытых полей при проверке форм, пришедших от пользователя.
Я не владею информацией относительно того, можно ли определить фингерпринт браузера для бота, но для реального пользователя в некоем варианте это тоже может являться меткой на уникальность и проверкой на подлинность.
Вы правы, что такой метод определения ботов может сработать, но в нашем случае форма очень простая и всего одна, так что скорее всего бото-писатель напишет не код, который старается автоматом пробиться через форму (как это может сделать поисковый бот, например) — а будет запрограммирован так, чтобы передавать только нужные поля.
Sign up to leave a comment.