«Реверс-инжиниринг» клиентского приложения в образовательном центре

Привет, Хабр. Хочу поделиться историей из жизненного опыта. Несколько месяцев назад я записался на платные курсы по изучению языка программирования JavaScript в прекрасном городе Минск. Потратил около недели времени на подробное изучение отзывов о каждой из компаний на рынке, сравнивал цены на услуги и местоположение относительно моего дома. Наконец, выбрав «достойного» кандидата, направился к ним в офис для заключения договора. В общем, прошел я начальный инструктаж, получил расписание занятий и содержание всего курса и с радостью приступил к делу.

Курс был довольно качественный, преподаватели имели реальный опыт разработки на production проектах и очень старались объяснить максимально просто различные аспекты языка, но это история не об этом…

В конце двух месяцев занятий c частотой 4 дня в неделю по 4 часа, каждый студент обязан был пройти контрольный тест в виде 80 вопросов по предмету с множеством вариантов ответов. Компания обещала при условии успешной сдачи тестирования помочь трудоустроится в крупную компанию нашего города на позицию JavaScript Developer. Очень заманчиво.

Вот пример вопроса:
  1. Что выведет команда console.log() ?

(function() {
    var x = 1;

    function x() {};
    
    console.log(x);	
})();

И несколько вариантов ответа, оформленные примерно так:

image

На рисунке черные квадраты — это checkboxes. Вариантов ответов на все 80 вопросов может быть от 1 до всех, что есть в списке вариантов.

Я, как прилежный ученик, тут же бросился отвечать на них. Однако, остановившись на 3-4 вопросе, мне захотелось узнать, как работает эта система. Пролистав в самый низ страницы, я нажал кнопку «Done» и увидел следующее: все вопросы, на которые были даны неверные ответы — а это все оставшиеся без моих ответов — стали подсвечены красным цветом. Появилась красивая рамка и изменился background-color у родителя элемента вопроса. «О, валидация!», — подумал я и начал выяснять, как же она работает.

Открыл, в общем, FireBug, обновил страницу и нажал кнопку «Done» еще раз. Я увидел, что запрос на сервер не отправился, то есть валидация сугубо клиентская работает в данный момент. Затем я открыл список JavaScript файлов, которые подключены к странице (там, кстати, использовался Backbone + RequireJS), и нашел модуль под названием «validation.js».

Сперва я отправился на unminify.com, мне нужно было привести код к нормальному состоянию. После прочтения кода я нашел метод «validate» со следующим содержанием:

/*здесь был код с такой вот логикой*/
$(".questions").each(function(i,e){
   var a = [];
   $(e).find(":checkbox").each(function(index,elem){      
      if($(elem).val() % 31 == 0) {
         /*все окей, ответ как минимум правильный*/                
      } else {
         /*все плохо, ответ неверный*/
         a.push(index);
      }       
   });
   if (!a.length) {
    /*значит все ответы на вопрос правильные, вызываем функцию correctAnswer();*/
   } else {
    /*был как минимум один неверный ответ, вызываем функцию wrongAnswer();*/
   }
});

Далее посмотрел html-разметку всех чекбоксов:

<input class="ui-element-checkbox" type="checkbox" name="answer" value="2561">

Так вот, замечательное число в атрибуте «value» и было ключём к правильным ответам теста. Не трудно догадаться, что запрос на сервер будет выполнен только в том случае, если выбраны только правильные ответы.

Я написал небольшой скрипт, который пробегался по всем вопросам, в каждом конкретном вопросе находил элементы checkbox, брал их значение и делил на 31; если остаток 0 – выставляем атрибут ‘checked’ в true, если нет — идем дальше:

var parent = $(".questionnaire-text");
var answers = parent.find(".answers[data-type='checkboxes']");
answers.each(function(index,elem){
  var checkboxes = $(elem).find(":checkbox");
  checkboxes.each(function(i,e){
    if ($(e).val() % 31 === 0) {
      $(e).attr("checked","checked");
    }
  });
});   

Через мгновение увидел все правильные ответы на абсолютно все 80 вопросов теста. Я с радостью нажал кнопку «Done» и- о, чудо — в FireBug увидел отправленный запрос на удаленный сервер учебного центра, на который получил ответ с поздравлением об успешной сдаче теста на 100%.

Естественно, я не хотел быть уличенным в мошенничестве во время сдачи теста, поэтому посидел еще минуток 20-25 тихонько за компьютером, прежде чем сообщить куратору о готовности.

Сразу скажу, никто кроме меня на 100% не сдал этот тест. В общей сложности только 3 человека, включая меня, сдали тест положительно на более чем 75%. Остальные ребята не набрали и 50% правильных ответов.

После успешного окончания курсов я прошел собеседование в одну из компаний города Минска на должность JavaScript Developer, но мысль о той хитрости во время сдачи теста не давала мне покоя. В один прекрасный день я пришел в тот самый учебный центр и все им рассказал. Мне выразили благодарность за честность и подарили волейбольный мячик.

Вот такая история. Хочу посоветовать всем не боятся исследовать неизвестные области и постоянно находить легкие пути для решения трудных задач. Спасибо за внимание.

P.S. Приведенные примеры кода лишь частично описывают реальный функционал. Также история не моя личная, а моего очень хорошего друга, который попросил остаться инкогнито.
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 12

    –3
    Отчасти и поэтому мои кандидаты отвечают на вопросы с помощью ручки и бумажного носителя.
      +5
      «Поэтому» — это почему? Из-за некорректной работы вашей системы тестирования?
      –5
      У моей подруги с парнем!)
        0
        Вспоминается подобная история с экзаменом по администрированию серверов :D Найдена скуля на сайте с движком тестов, с базы вытянуты все правильные ответы = экзамен на 100 балов )
          –3
          >>Я увидел, что запрос на сервер не отправился
          Дальше не читал.
            +8
            Обычно score результатов теста не должен превышать 97%. Для этого в тест вводят неправильные вопросы (либо неправильные ответы). Score 100% для супервизора означает читинг в процессе теста.
              0
              Спасибо, как раз недавно сделали тестирование на работе.
              Хотя правильные ответы и не выводятся, а только балл в конце теста.
                0
                Спасибо. Периодически встречаю в тестах нарочно неправильные ответы…
                0
                но мысль о той хитрости во время сдачи теста не давала мне покоя. В один прекрасный день я пришел в тот самый учебный центр и все им рассказал

                Вот это называется: у человека есть совесть! Лучший контролер. От него не спрячешься и не убежишь. И только совесть позволяет существовать цивилизации, так как больше нет ничего, что неусыпно не удерживает большинство людей от аморальных и вредных обществу поступков.
                  +4
                  Ну, тот факт, что вы смогли хакнуть систему только подтверждает наличие обсуждаемого скилла. Так что можно считать, что не баг а фича!
                    0
                    Не факт. Можно уметь «вскрывать» клиентские JS-приложения, писать сложные букмарклеты с использованием методов map и reduce и при этом не знать ответы на «глупые» вопросы типа первого приведённого в статье или других из серии «как поведёт себя программа при применении того или иного приёма из разряда 'bad practice'».
                    0
                    Меня гложат сомнения, что автор самостоятельно сдал бы тест хотя бы на 75%.
                    Думаю качество вопросов от качества системы для тестирования сильно отличалось.

                    Only users with full accounts can post comments. Log in, please.