Это баг или фича Lingvist

Введение


Привет хабровоинам.

Сегодня я напишу статью о небольшой уязвимости сервиса lingvist. Моя первая статья на Хабре, поэтому как принято писать, кхм… цитирую «помидорами просьба не кидать».

Все началось с того ( чавкая вставной челюстью ) когда я решил поизучать анг. язык.
Нашел данный сервис, зарегистрировался и все бы ничего, но сервис лингвист из-за незнания моего уровня прошаренности в анг.яз, без калибровочного теста начал давать ну совсем простые слова, вроде dog, i, you and other easy words.

Вообщем решил 100 — 200 слов вдруг вспомнилась поговорка:
«хороший программист — ленивый программист» ©.

А ведь действительно и началось.

Разведка html


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




Предположив что сразу после ввода неправильного (или правильного) слова,
ajax(ом) подгружается правильный ответ и вставляется в какой-нибудь placeholder,
начал инспектировать код:





Ну и ладно подумал я и решил что алгоритм будет такой:

  • Эмулирую нажатие кнопки «проверка»
  • Как только получаем правильное слово парсим его
  • Спарсенное слово вставляем в input для ответа
  • И снова эмулирует нажатие на отправку ответа

(все это в цикле через setTimeout)

Тем самым получаем много слов в словаре, а значит меньше элементарных, утомительных словечек и привет, увеличение словарного запаса!

Написание скрипта


По какой то причине JQuery на сайте не сработал и пришлось писать все на нативном js.

Сперва весь код:

setInterval(function(){
    var selectorAnswer= document.getElementsByClassName("word-container")[0].childNodes;
    selectorAnswerArr = [];
    for (var i = 0; i < selectorAnswer.length; i++) {
        var letter = selectorAnswer[i].innerHTML;
        selectorAnswerArr.push(letter);
    }
    answerStr = selectorAnswerArr.join(",").replace(/,/g, "");
    document.getElementsByClassName("answer-input")[0].value = answerStr;
    document.getElementsByClassName("next")[0].click();
    console.warn("Разгадали слово: " + answerStr );
}, 1000);


Краткий разбор строк:

  1. setInterval(function() {}, 1000)
    Повторение вложенного кода раз в секунду.
  2. var selectorAnswer= document.getElementsByClassName(«word-container»)[0].childNodes;
    Селектор в который вложены span с буквами правильного слова
  3. selectorAnswerArr = [];
    Массив для будущего ответа.
  4. for (var i = 0; i < selectorAnswer.length; i++) {})
    цикл, который перебирает вложенные блоки в .word-container (то есть буквы правильного слова).
  5. var letter = selectorAnswer[i].innerHTML;
    узнаем буквы правильного слова
  6. selectorAnswerArr.push(letter);
    Толкаем правильные буквы в конец массива selectorAnswerArr
  7. answerStr = selectorAnswerArr.join(",").replace(/,/g, "");
    Собираем из нашего массива с буквами единое целое и убираем запятые через регулярку.
  8. document.getElementsByClassName(«answer-input»)[0].value = answerStr;
    Подставляем в значение input для ввода данных
  9. document.getElementsByClassName(«next»)[0].click();
    Эмулируем проверку нашего слова
  10. console.warn(«Разгадали слово: » + answerStr );
    Просто служебная информация в консоли

Take this! (надеюсь правильно написал).
P.S. Скрипт проверял только на браузере Chrome за кроссбраузерностью не гнался.

А теперь вишенка!


Как вы, возможно, заметили, в скрипте есть одна ошибка,
в начале скрипта должна выполняться эмуляция нажатия на кнопку,
что бы мы могли получить ответ от сервера в виде правильного слова.

Но на мое удивление скрипт отработал как надо!
Совпадение?

Полез в инспектор в раздел Network и тадааам:





Сайт во время первой загрузки на клиенте отдает все правильные ответы,
сделано это скорее всего с целью ускорить проверку ответа, другими словами мы можем
с 100% вероятность предугадать любое слово, такие дела!




Эй Хабр, надеюсь моя статья была полезна тебе, следующих статьях расскажу о заезженной теме том, как с болью и потом делалась игра на js.

Если где то ошибся или у вас есть дополнения, пишите мне будет очень интересно почитать.
Метки:
javascript, html, тестирование веб-приложений

Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.