Подлавливаем пользователя на вводе в консоли в Google Chrome

    Привет. Решил написать про небольшую фичу хрома, которую случайно обнаружил однажды. Как её использовать — решайте сами.

    Сразу покажу пример, чтобы не мусолить (тестировал на последнем Хроме, который у меня был):

    var gn = Object.getOwnPropertyNames.bind(Object)
    
    var f = function(o) {
        if(f.caller && f.caller.toString && 
           f.caller.toString().indexOf('object&&ArrayBuffer.isView(o)&&o.length>9999') > 0) {
            console.log(f.caller)
        }
        return gn(o);
    }
    Object.getOwnPropertyNames = f
    

    Если начать что-то вводить в консоль после запуска кода выше, то при вводе в консоль начнет выпадать какая-то функция.

    Вот эта:

    (function getCompletions(type) {
        var object;
        if (type === 'string')
            object = new String('');
        else if (type === 'number')
            object = new Number(0);
        else if (type === 'boolean')
            object = new Boolean(false);
        else
            object = this;
        var result = [];
        try {
            for (var o = object; o; o = Object.getPrototypeOf(o)) {
                if ((type === 'array' || type === 'typedarray') && o === object && ArrayBuffer.isView(o) && o.length > 9999)
                    continue;
                var group = {
                    items: [],
                    __proto__: null
                };
                try {
                    if (typeof o === 'object' && o.constructor && o.constructor.name)
                        group.title = o.constructor.name;
                } catch (ee) {}
                result[result.length] = group;
                var names = Object.getOwnPropertyNames(o);
                var isArray = Array.isArray(o);
                for (var i = 0; i < names.length; ++i) {
                    if (isArray && /^[0-9]/.test(names[i]))
                        continue;
                    group.items[group.items.length] = names[i];
                }
            }
        } catch (e) {}
        return result;
    }
    )
    

    Очевидно, что с ее помощью гугл Хроум выдает нам саггешены, которые будут показаны в выпадающем меню при вводе текста в консоли.

    image
    Можете смело переопределять возвращаемые функцией Object.getOwnPropertyNames значения, и вставлять туда всякий мусор, если захотите. Так же вы просто можете реагировать на ввод пользователя в консоли. (В примере мы просто выводим ту самую функцию хрома).

    image

    Все :)

    image

    Репозиторий вот
    Поделиться публикацией

    Похожие публикации

    Комментарии 37
      0
      А какие плюсы от этой этой фичи?
        +1
        Можете смело переопределять возвращаемые функцией Object.getOwnPropertyNames значения, и вставлять туда всякий мусор, если захотите. Так же вы просто можете реагировать на ввод пользователя в консоле. (В примере мы просто выводим ту самую функцию хрома).

        Если сайт твой и, может, ты не любишь, когда твой сайт отлаживают, можешь выключать консоль через это:
        while(1);

        А в целом я не знаю, почему так сделано, и как еще этим можно воспользоваться.
          +1
          Ну так консоль рисуется тем же движком что рендерит сайты. Хотя по-хорошему стоило б её изолировать как остальной интерфейс браузера, а не делать частью страницы.
          0
          Целых три — lol, kek и azaaza.
          +1
          Что помешает
          остановить ваш код в дебаггере?
          image


          Даже без дебаггера, ваш код сразу виден, может дело в 58 версии?
          Скрин
          image
            +1

            Мой код очень легко остановить в дебагере, потому что его никто не обфрусцировал.
            Если ты хочешь основательно прятать свой код, то можно его обфрусцировать, динамически менять, подкачивать как попало и т.д.
            Тут я это не описовал, потому что статья не про это.


            На счет "код виден" я не очень понял, что имеете ввиду, показывая скриншот.
            На нем показано, как моя программа вывела функцию, которую использует хром, чтобы получить сагешены

              +1
              Прошу прощения, не посмотрел код. Ожидал что будет как на скрине у вас:
              image
              Подумал что это браузер ) Надо завязвать писать комменты после бессонной ночи.

              По теме — возможно этот способ дополнит ваш код?
              Revisiting Disable JavaScript Execution From Console


                0
                Так можно вставлять белеберду:
                var gn = Object.getOwnPropertyNames.bind(Object)
                
                var f = function(o) {
                    if(f.caller && f.caller.toString && 
                       f.caller.toString().indexOf('object&&ArrayBuffer.isView(o)&&o.length>9999') > 0) {
                        return ['azaza', 'kek', 'lol']
                    }
                    return gn(o);
                }
                Object.getOwnPropertyNames = f
                

                Может, можно дополнить, но в целом, это на ваше усмотрение, думаю.
                Оба трюка не сильно взаимосвязаны, как понял.
                +1
                «Обфускация» же.
                0
                Есть способы нехило подвесить браузер. Некоторые даже нельзя остановить дебаггером.
                Например, можно одновременно загрузить все шрифты, установленные в системе. Правда, тут нужно использовать Flash, без него список шрифтов получить нельзя (разве только жестко вшить).
                  0
                  Сам недавно случайно наткнулся, что при скачивании большого количества файлов с помощью javascript браузер виснет и падает. Правда в хроме нужно иногда разрешить сайту скачивать много файлов, но это не всегда помогает, т.к. хром качает их в фоне. Протестировать можно здесь: https://iliakonnov.github.io/chromeCrash/index.html
                +1
                Видел примерно такую «тихую» реализацию:
                var oldf=console.log;
                console.log=function(){
                store.push(arguments);
                oldf.apply(console, arguments);
                };
                


                Подозреваю, что можно чуток допилить, переопределив console.log на пустую функцию и будет счастье. Ну то есть не очень понятно в чём именно это счастье, но будет.
                  0

                  Можно извратиться, и перехватывать все на свете, но так никто не делает.

                    0
                    А у нас примерно так и сделано.
                    После того, как мы пару раз забыли удалить вызовы console.log() и выкатили релиз, где у юзеров файрфокса всё поломалось из-за отсутствия у них console, мы переопределяем объект console и все его функции в продуктивной версии.
                      0

                      Ну зачем же с именно переопределять-то?


                      if (!window.console) window.console = { log: function() {} };
                        +3
                        Это в какой версии ФФ было?
                        Я с 11 года пишу (отлаживаю во всех более-менее встречающихся браузерах), и ни разу не сталкивался, чтобы где-то кроме IE могло не быть console.
                          +1
                          Не знаю версию, но это точно был Firefox и версия скорей всего больше 2.0, возможно до 3.6., я не помню уже за давностью лет.
                          Но история коммитов всё помнит: 11.11.11 в 9:37 я коммитнул переопределение консоли :)

                          A стажем меня не надо пугать, я писал и отлаживал ещё под Mozilla, который не Firefox :-)
                            +2
                            Пугать? Что Вы! Я только отметил, что в 11 году, когда я начал заниматься этим профессионально и у меня на машине появились все актуальные браузеры (две версии FF, две версии Оперы, Гугл, IE, естественно, кажется, Сафари для винды, но могу уже не помнить), подобная проблема нигде кроме ИЕ не встречалась.
                              0
                              а в document.title для IE «по быстрому» отладчик не прикручивали? :)
                        +2
                        Изменять suggestions, конечно, прикольно, но чтобы просто обнаружить факт открытия консоли — есть способ попроще. console.log(x.y), где «х» — это объект у которого навешен геттер на поле «у». Как только сработал геттер — значит юзер открыл devtools :)
                          0

                          Я немного запyтался. Идея с гетерами мне понятна, но я не очень понял про значение console.log(x.y)

                            +1
                            Блин, сейчас проверил — а уже, походу, зафиксили. Жаль. Ещё прошлым летом работало, я писал небольшую игру и защищал её разными извращёнными способами, этим в том числе. Если вкратце — было так: по факту console.log срабатывала не в момент вызова, а в момент открытия консоли. Иными словами, если написать console.log, в самом начале большого кода, то срабатывал он всё равно только после того как devtools был открыт.
                            Если я всё правильно помню — то рабочим был примерно вот такой вот код:

                            var test = {};
                            
                            Object.defineProperty(test, "console", {
                              get: function() {
                                alert('You are dirty hacker!');
                              }
                            });
                            
                            console.log(test.console);
                            
                              +10
                              А, нет, не зафиксили, это меня память подвела)

                              Рабочий код выглядел вот так (честно стырен со стековерфлоу)

                              var element = new Image();
                              Object.defineProperty(element, 'id', {
                                get: function () {
                                  alert('Devtool has been opened!');
                                }
                              });
                              console.log('%cHello', element);
                              

                                0
                                Спасибо, вкурил.
                              +1

                              Если писать console.log(x.y), то поле y будет получено сразу же. Что бы отловить именно обращение к полю из консоли, надо писать console.log(x)

                              –3
                              image
                                +2
                                Я чисто случайно нашел эту фичу.
                                А троллейбус мы всегда знаем, как собрать.
                                Думаешь, фича никому не будет интересна совсем?
                                0

                                А меня вот интересует другое. Как можно (и можно ли вообще) вырезать принудительные точки останова по ключевому слову debugger;. Натыкался на такую защиту от отладки на некоторых сайтах — постоянно в «цикле» (по setTimeout(), кажется) динамически генерируется функция, снова устанавливающая тот же самый таймер и содержащая инструкцию debugger;. Соответственно, мало того, что от такой «защиты» сайт очень скоро начинал безбожно тормозить и подвешивать интерфейс браузера, так ещё и в инструменты разработчика было не зайти, поскольку они безусловно останавливались на инструкции debugger;, пропустить которую нет никакой возможности. Так вот, есть ли какой-то способ отключить её к чертям хотя бы в каком-то браузере?

                                  0

                                  Есть же кнопка «Deactivate breakpoints (Ctrl+F8)» в хром-дев-тулзах.

                                    0

                                    Она работает только с теми точками останова, что поставил сам, через инструменты разработчика. Если в коде встречается инструкция debugger;, отладчик останавливается (останавливался, когда я последний раз смотрел) на ней независимо от состояния этой кнопки.

                                      0

                                      Странно, нам помогала (есть любители наставить debugger в коде при отладке).

                                        0

                                        Может быть, уже что-то и изменилось. Я довольно давно смотрел, тогда не работало.

                                  +1
                                  Детектить факты захода юзера а девтулз полезно, например, когда нужно бороться с хитрожопыми читерами в браузерных играх. Только вот детектить нужно максимально скрытно и ни в коем случае не реагировать явно на такого рода действия пользователя. Просто ставим галочку в скрытой части профиля пользователя, и имеем её в виду как дополнительный штрих при поиске более надёжных свидетельств читерства.
                                    –1

                                    Угу. Посмотрел сертификат SSL — записали в читеры! :-)

                                      +2
                                      Хреновый способ, имхо, будто читы без захода в консоль не работают, можно написать дополнение для браузера, можно модифицировать движок или просто перехватывать и подменять трафик. Чем городить такие «защиты» лучше перенести большую часть логики на сервер.
                                        0
                                        Вы не поняли суть моего комментария, как и mayorovp. Я не предлагал только по факту захода в консоль определять читеров. Ни один признак в этом вопросе не должен быть однозначно определяющим и обязательным. Это всегда бесконечное противостояние брони и пули, в котором обе стороны вынуждены постоянно придумывать что-то новое и окончательной победы не будет.
                                        Я предлагал факт, частоту и характер использования консоли тихо добавлять в поведенческий портрет пользователя наряду с максимальным количеством разных других признаков. По совокупности этих признаков различные эвристики (которые со временем будут добавляться, изменяться и устаревать) проклассифицируют пользователей по степени риска читерства. В любом случае нужны дополнительные проверки и правила.
                                      +1
                                      Пока смотрела как все вышеописанное работает в консоли, случайно обнаружила масштабирование для devtools. С учетом того, что у меня все страницы выставлены на 150%… это прелесть)
                                      Почаще бы такие случайности!

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

                                      Самое читаемое