Как стать автором
Поиск
Написать публикацию
Обновить

Что за зверь такой — Pinokio? Досконально разбираем его подкапотную

Уровень сложностиПростой
Время на прочтение8 мин
Количество просмотров1.9K

Не так давно я выпустил первую часть своей статьи, в которой поднял проблему отсутствия портативных установщиков репозиториев и показал разницу между Pinokio и своей разработкой PortableSource. Что ж, в этой части мы залезем под капот Pinokio и узнаем, что же он за зверь такой и в чем причина его лагов.

ЧАСТЬ 1. Публичный репозиторий на github — open‑source ли? Или это просто обман?

Казалось бы, репозиторий размещен на github, следовательно имеет открытый исходный код? Только вот... В данном случае это лишь отчасти правда. Посмотрим на основную страничку:

выглядит как самый обычный GUI на node.js. но не все так просто
выглядит как самый обычный GUI на node.js. но не все так просто

Привет Node.JS разработчики, если вы читаете! А если вы не шарите за ноду, то тут есть одна странность - где папка src? Она, по неведомой причине, отсутствует. Или все таки причина известна? Пожалуй, погрузимся в дебри package.json:

Весьма странное поведение - Манки-Патчи! (Улика №1)

{
"name": "Pinokio",
"private": true,
"version": "3.28.0",
"homepage": "https://pinokio.co",
"description": "pinokio",
"main": "main.js",
"email": "cocktailpeanuts@proton.me",
"author": "https://twitter.com/cocktailpeanut",
"scripts": {
"start": "electron .",
"pack": "./node_modules/.bin/electron-builder --dir",
"eject": "hdiutil info | grep '/dev/disk' | awk '{print 1}' | xargs -I {} hdiutil detach {}{platform}"
},
"publish": [
{
"provider": "github",
"owner": "pinokiocomputer",
"repo": "pinokio"
}
],
"asarUnpack": [
"node_modules/go-get-folder-size//*", "node_modules/7zip-bin//", "node_modules/sweetalert2/**/",
"node_modules/@homebridge//*" ], "nsis": { "include": "build/installer.nsh" }, "extraResources": [ "./script/",
{
"from": "assets/icon_small.png",
"to": "assets/icon_small.png"
}
],
"protocols": [
{
"name": "pinokio",
"schemes": [
"pinokio"
]
}
],
"mac": {
"category": "utility",
"target": [
{
"target": "default",
"arch": [
"x64",
"arm64"
]
}
],
"hardenedRuntime": true
},
"linux": {
"maintainer": "Cocktail Peanut ",
"target": [
{
"target": "deb",
"arch": [
"x64",
"arm64"
]
},
{
"target": "rpm",
"arch": [
"x64",
"arm64"
]
},
{
"target": "AppImage",
"arch": [
"x64",
"arm64"
]
}
]
},
"win": {
"artifactName": "Pinokio-Installer.${ext}",
"target": [
{
"target": "nsis",
"arch": [
"x64"
]
}
]
}
},
"license": "MIT",
"dependencies": {
"electron-progressbar": "^2.2.1",
"electron-store": "^8.1.0",
"electron-updater": "^6.6.2",
"electron-window-state": "^5.0.3",
"pinokiod": "^3.28.0"
},
"devDependencies": {
"@electron/rebuild": "3.2.10",
"electron": "^23.1.2",
"electron-builder": "^26.0.18",
"electron-builder-notarize": "^1.5.2"
}
}

Увидели странности? И я увидел: какие-то мутные манки-патчи, почта на протон домене и непонятный пакет pinokiod в зависимостях. Не странно ли? Зачем автор использует патчинг, демон с закрытым кодом и, собственно, анонимную почту? Эти 3 зацепки показывают, что код из-за внешних модулей нестабилен, само ядро закрыто, а автор хочет остаться анонимным.

Ну окей, пройдем дальше и рассмотрим main.js:

const Pinokiod = require("pinokiod")
const config = require('./config')
const pinokiod = new Pinokiod(config)
let mode = pinokiod.kernel.store.get("mode") || "full"
//iprocess.env.PINOKIO_MODE = process.env.PINOKIO_MODE || 'desktop';
if (mode === 'minimal') {
  require('./minimal');
} else {
  require('./full');
}

Итак, точка входа — не исходники из папки src, а вызов демона pinokiod. После более глубокого анализа выяснилось, что его код все же доступен в отдельном репозитории (важное уточнение, которое я добавил в начало статьи). Однако, это не отменяет главного вопроса к архитектуре: почему фронтенд и бэкенд не являются двумя независимыми, связанными через API проектами, как это принято? Вместо этого мы видим монолитную конструкцию, где одно приложение поглощает другое. Это наталкивает на мысль, что дело не в сокрытии кода, а в чем-то более фундаментальном — в самой структуре проекта.

Часть 2. Лезем демону под капот и рассматриваем под микроскопом его внутренности.

Перейдем к самому интересному. Чтобы понять, как на самом деле работает Pinokio и почему его архитектура вызывает столько вопросов, нам нужно заглянуть внутрь дистрибутива, который получают пользователи. Мы проведем небольшой реверс-инжиниринг, чтобы вскрыть упакованное приложение и добраться до его реальной структуры.

Но для начала — важный юридический момент: наши действия полностью легальны. Проект распространяется под лицензией MIT (что подтверждается файлом LICENSE и записью в package.json), которая прямо разрешает нам исследовать, модифицировать и анализировать код.

Copyright 2023 Pinokio

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Итак, для начала нам надо установить парочку инструментов, благодаря которым мы сможем провести реверс, это Node.JS и самый обычный 7-zip. После быстренькой установки следуем инструкции:

Сначала, мы скачиваем вот этот релиз. Мы берем на препарацию Pinokio-3.9.0-win32.zip.

Теперь просто распакуем архив и обнаружим "чудо":

видим сетап, который и нужен нам
видим сетап, который и нужен нам

Не стоит кликать по нему два раза, ведь мы пришли не за этим. Просто следуйте инструкции ниже, которая покажет, как вытащить сердце - app.asar

необходимо перейти в $PLUGINSDIR
необходимо перейти в $PLUGINSDIR
нам нужен именно app-64.7z, забираем этот архив
нам нужен именно app-64.7z, забираем этот архив

Все, сетап больше нам не нужен и не интересен, ведь мы сняли этот первый слой луковой шелухи, теперь разархивируем архив и увидим вот такое наполнение папки:

архив нам больше не нужен. избавляемся от него.
архив нам больше не нужен. избавляемся от него.

Перейдем в папку resources и увидим заветный файл app.asar, ради которого эта операция и затевалась:

именно он нам и нужен!
именно он нам и нужен!

Немного усмирим коней и внесем ясность. Что же это за штука такая, app.asar? А это доказательство того, что ВСЯ логика написана на Node.JS и Electron. Помните лаги, баги, тупые ошибки? Вот их и первопричина, на которую можно будет взглянуть лично через пару действий! Ведь мы прямо сейчас будем данное чудо ДЕкомпилировать в понятный JS код, который уже могут почитать все. А знающие - ознакомиться с ним. Для этого открываем cmd, я пользуюсь таким лайфхаком:

Установим необходимую библиотеку для декомпиляции сего чуда, для этого мы и ставили node.js:

npm install -g asar

И с его помощью извлечем сердце, app.asar:

asar extract app.asar ./extracted

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

интересен ли нам main.js? абсолютно нет.
интересен ли нам main.js? абсолютно нет.

Наша главная цель - node_modules/pinokiod. Тот самый закрытый код, который внезапно стал открытым. С помощью наших легких усилий. Кстати, весьма интересные пакеты...

но они не так интересны, как сердце - pinokiod.
но они не так интересны, как сердце - pinokiod.

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

а вот и само чудо - pinokiod.
а вот и само чудо - pinokiod.

Давайте рассмотрим это по порядку. Тут весьма много интересного, ведь автор, зачем-то сделал и сервер и клиент в одной оболочке. Это весьма нелогично и непрактично, мешать в одном месте мед, мух и пчелы. Ведь это весьма сложно отлаживать, это порождает море багов в использовании и раздувает сборки до весьма больших размеров.

ну и франкештейн!
ну и франкештейн!

Мы не будем углубляться в каждую строчку кода, ведь цель этой статьи — не исчерпывающий аудит, а анализ рисков, видимых невооруженным глазом. И то, что мы увидели, вызывает серьезное беспокойство.

Давайте подведем итог. Даже при том, что код бэкенда оказался открыт (и я исправил эту ошибку в начале статьи), мы имеем дело с крайне опасным коктейлем:

  • Анонимный разработчик, который не несет никакой ответственности.

  • Использование манки-патчинга — техники, позволяющей программе изменять саму себя "на лету", что является кошмаром для безопасности.

  • Запутанная, монолитная архитектура, которая смешивает клиент и сервер, усложняет аудит и создает почву для новых уязвимостей.

Каждый из этих пунктов по отдельности — это желтый флаг. Все три вместе — это огромный красный флаг, который кричит об опасности.

В конечном счете, вопрос не в том, есть ли в Pinokio зловредный код прямо сейчас. Вопрос в том, насколько легко его туда добавить и насколько мы готовы доверять свои данные и свои компьютеры анонимному разработчику с таким подходом к архитектуре и безопасности. Я свой выбор сделал.

Анализ кода

Общее описание: pinokiod - это Node.js демон/сервер для платформы Pinokio, представляющий собой комплексную систему управления AI-приложениями и автоматизации. Версия: 3.9.0.

📁 Архитектура проекта :

Корневые файлы:

  • index.js - точка входа, экспортирует server модуль

  • package.json - конфигурация npm с 40+ зависимостями

  • worker.js - воркер процесс для асинхронных файловых операций

🖥️ Server (server/):

  • index.js - основной сервер класс (Express.js)

  • socket.js - WebSocket сервер для real-time коммуникации

  • views/ - EJS шаблоны для веб-интерфейса

  • public/ - статические ресурсы (CSS, JS, xterm.js)

  • ⚙️ Kernel (kernel/) - Ядро системы:

    Основные модули:

    • index.js - главный класс Kernel

    • environment.js - управление переменными окружения

    • shell.js - управление терминальными сессиями

    • script.js - выполнение и управление скриптами

    API модули (kernel/api/):

    • index.js - центральный API роутер

    • shell/fs/process/gradio/cloudflare/ - специализированные API

    Bin модули (kernel/bin/):

    • index.js - базовый класс для установки инструментов

    • python.jsconda.jsgit.jscuda.js - установщики

🔄 Pipe (pipe/): Система для создания публичных эндпоинтов.

📜 Script (script/): Автономный запуск сервера.


🔧 Ключевые функции

  • Управление окружением: Автоматическая установка Python, Conda, Git, CUDA.

  • Терминальный интерфейс: Веб-терминал через xterm.js.

  • Веб-интерфейс: Файловый менеджер, редакторы кода.

  • Интеграции: Git, Gradio, Cloudflare, HuggingFace.

  • Безопасность: Аутентификация для публичных эндпоинтов.

  • Мониторинг: Сбор системной информации (GPU, CPU, память).


📊 Технологический стек

  • Backend: Node.js, Express.js

  • Frontend: EJS, xterm.js, WebSocket

  • Терминал: node-pty

  • Git: isomorphic-git

  • Прокси: http-proxy


Вердикт: Это полнофункциональная платформа для разработки, развертывания и управления AI-приложениями с веб-интерфейсом и автоматизацией инфраструктуры.

Ты дочитал до этого момента, и теперь ты видишь весь этот ужас. Непрозрачная архитектура, где в одном флаконе смешаны клиент и сервер. Опаснейшие манки-патчи, позволяющие менять код на лету. И все это — от полностью анонимного разработчика.

А теперь сложи два и два. Зачем анониму использовать манки-патчинг в проекте со столь запутанной архитектурой? Не для того ли, чтобы в один прекрасный день с очередным обновлением вшить в свое детище стиллер, ратник или еще какую-нибудь пакость, которую будет почти невозможно отследить в этом хаосе? Вопрос больше не в том, закрыт ли код. Вопрос в том, насколько мы готовы доверять анониму, который выбирает такие сомнительные и опасные инструменты.

Хватит терпеть такое отношение к безопасности под вывеской "open-source". Проект, который лишь просто красив, а по факту медленный, баганый и построен на архитектурных костылях — это не тот open-source, который нам нужен. Я не доверю такому решению свою безопасность! И безопасность своих данных.

Итог прост: Pinokio — это красивая обертка с сомнительной и опасной начинкой. И единственно верный выбор — это софт, который не просто открыт, а спроектирован с уважением к пользователю и его безопасности. Софт, как PortableSource, который решает реальные проблемы (длинные пути через виртуальные диски, кастомный менеджер пакетов) и написан на Rust — как гарантия скорости и надежности, которой так не хватает Pinokio.

Теги:
Хабы:
-5
Комментарии3

Публикации

Ближайшие события