
Проект OSINT, который исследует, как извлекать данные из React
Этот инструмент представляет собой быстрый и грязный пользовательский скрипт для Tampermonkey, который копает на пару уровней вглубь любой React-страницы и ищет одну или несколько фраз, заданных пользователем.
Инструмент позволяет легко найти нужное место в DOM, где React прикрепляет большие куски JSON-данных.
Поиск этих мест вручную может быть очень трудоёмким, так как способ хранения и передачи данных сильно зависит от разработчика, версии React и сложности конкретного сайта.
Этот пользовательский скрипт призван значительно упростить этот процесс.
Ниже приведено видео работы скрипта.

Для получения дополнительной информации о том, как и почему это работает, обратитесь к руководству по той же теме в другом месте этого репозитория.
Скопируйте пользовательский скрипт из этого репозитория и следуйте инструкциям в документации Tampermonkey по установке скрипта.
Суть в том, что вы выбираете Create a new userscript, удаляете весь шаблонный код, который предлагает Tampermonkey, вставляете пользовательский скрипт и нажимаете сохранить. После этого всё готово.
После установки пользовательский скрипт добавляет в контекстное меню правой кнопки мыши две кнопки, которые должны быть активны на всех сайтах, использующих React (если вы найдёте сайт, где это не так - пожалуйста, сообщите мне):
reactPropsreactFiberЭто можно увидеть ниже.

Кнопки названы в честь двух внутренних свойств, которые React прикрепляет к HTML-узлам в обычном DOM. React использует их для внутренней передачи данных, построения страницы, синхронизации состояния страницы со своей виртуальной моделью DOM (VDOM), для реакции на действия пользователя и т.д.
Именно через эти свойства мы также можем получать и массово извлекать сырые данные. Причём огромное количество данных, которые иначе не доступны в DOM.
Чтобы воспользоваться инструментом, просто откройте консоль JavaScript в инструментах разработчика и выберите один из двух вариантов. Если один не даёт данных - попробуйте другой. Как уже было сказано, то, что работает, сильно зависит от конкретного сайта.
В этом примере я ищу данные о видео TikTok Института SANS. В качестве входных данных я указал одну из фраз - four days - найденную под первым из видео:

Вводимые данные приводятся к нижнему регистру, а пробелы по краям обрезаются перед сравнением с содержимым, прикреплённым в качестве свойств к HTML-узлам, так что просто вводите то, что хотите.
При желании можно использовать несколько фраз - просто разделите их запятой. Если вы хотите нацелиться на несколько видео в примере с TikTok, это может быть four days,congratulations,thank you.
Скрипт использует OR, а не AND в качестве оператора поиска.
Также можно использовать подстановочный знак *, который выгрузит всё.
Однако небольшое предупреждение:
Поиск с помощью * может привести к краху ваших инструментов разработчика, поскольку это легко может выгрузить десятки тысяч строк данных. Поэтому используйте эту возможность только в крайнем случае. Особенно на Facebook вы будете погребены под данными, если так сделаете.
В целом полезно искать определённые имена пользователей / идентификаторы пользователей, которые, как вы знаете, должны присутствовать - или если вы знаете, что где-то там есть свойство с именем videoData, просто используйте его.
При запуске скрипта на TikTok (reactProps) в консоль JavaScript выводится куча данных - а также они копируются в буфер обмена. Внизу вы увидите количество совпадений, которые дали шаблоны поиска (в данном случае 5).

Если вы хотите изучить JSON-данные, просто вставьте их в редактор - желательно в тот, который поддерживает JSON и подсветку синтаксиса. Так будет гораздо проще их просматривать.
Однако действительно полезная функция - если вы планируете создавать инструменты на основе React для конкретного сайта - это не выгрузка в буфер обмена. Помимо выгрузки данных, скрипт также записывает в журнал и HTML-узел, который дал совпадение, и точный путь к свойству, по которому найдено совпадение.

Эта функция решает одну из реальных проблем при попытке сопоставить VDOM React с обычным DOM, с которым мы - в отличие от VDOM - можем взаимодействовать с помощью обычного JavaScript.
В данном случае вывод сообщает нам, что нужные данные прикреплены в качестве свойств, среди прочего, к HTML-узлу <div class="css-x6y88p-DivItemContainerV2 e19c29qe8"> как свойство по пути: __reactProps$xunlb5k9rwt | children | 1 | props.
Обладая этим знанием, мы теперь точно знаем, с какого узла - и по какому пути - можно получить данные.
| - это просто выбранный мной разделитель. При преобразовании этого в скрипт замените его на точечную нотацию, например __reactProps$xunlb5k9rwt.children[1].props - или нотацию с квадратными скобками, например ["__reactProps$xunlb5k9rwt"]["children"][1]["props"].

Как отмечалось в руководстве по React в другом месте этого репозитория, часть __reactProps содержит строку из 10 символов, которая генерируется случайным образом при каждой загрузке страницы.
Обратитесь к руководству за рабочим примером того, как извлечь нужный ключ из одного из HTML-узлов.
На самом деле скрипт углубляется на пару уровней в каждое свойство выбранной категории (__reactFiber или __reactProps) и пытается преобразовать всё внутри в JSON (JSON.stringify()). Если объекты внутри содержат циклические ссылки (а многие будут), их нельзя разобрать как JSON. Попытка преобразования вызовет ошибку, которая перехватывается, и цикл просто игнорирует это и продолжает работу.
В настоящее время скрипт также просматривает свойства только для тегов <div> и <article>. Если вы обнаружите, что по этой причине что-то упускается, пожалуйста, сообщите мне. Это очень незавершённая работа.
Скрипт также не рекурсирует очень глубоко в свойства. Во-первых, я не мастер рекурсии. Во-вторых, мне не очень интересны вещи, глубоко вложенные в свойства, поскольку построение чего-либо на их основе с большей вероятностью сломается даже из-за незначительных изменений на платформах, на которые можно ориентироваться. По моему опыту, данные обычно можно найти рядом с HTML-узлом.
Этот скрипт предназначен только для образовательных целей. Не злоупотребляйте им. Ведите себя прилично. Будьте добры. И не нарушайте законов.