Про MAX и всю хуйню

Страницы: 1 ...  7 8  ОТВЕТИТЬ НОВАЯ ТЕМА
Lenovatan автор 2 сен 2026 в 01:57
Виноградный велосипед  •  На сайте 11 лет
Сообщений: 2 966
Цитата (Репликатор @ 2 сен 2026 в 01:55)
Цитата (Lordex @ 1 сен 2026 в 23:27)
Вроде девушка, а ругаешься покруче многих ЯПовцев

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

Иди нахуй. Мне нихера не нужно. я просто поделилась радостью. А такие ебланы как ты , задрочили коменты
Все комментарии:
BattlePorQ 2 сен 2026 в 01:58
Парасьонах  •  На сайте 17 лет
0
Цитата (Lenovatan @ 2 сен 2026 в 01:55)
Ты в мультиках не снимался?

Как-то не приглашали пока. Хотя если вдруг сложится - не откажусь. Всё же красавец, два метра харизмы и это вот всё.
Lenovatan автор 2 сен 2026 в 01:59
Виноградный велосипед  •  На сайте 11 лет
-4
Цитата (BattlePorQ @ 2 сен 2026 в 01:58)
Цитата (Lenovatan @ 2 сен 2026 в 01:55)
Ты в мультиках не снимался?

Как-то не приглашали пока. Хотя если вдруг сложится - не откажусь. Всё же красавец, два метра харизмы и это вот всё.

ага и ЯПовский 45. иди не пизди
Репликатор 2 сен 2026 в 02:01
Приколист  •  На сайте 5 месяцев
-1
Цитата (Lenovatan @ 2 сен 2026 в 01:57)
Цитата (Репликатор @ 2 сен 2026 в 01:55)
Цитата (Lordex @ 1 сен 2026 в 23:27)
Вроде девушка, а ругаешься покруче многих ЯПовцев

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

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

Задрочил комменты тут главный еблан - это ты. А я вот сейчас оставил только второй.
leretbor 2 сен 2026 в 02:01
Юморист  •  На сайте 9 лет
0
Цитата (Lenovatan @ 2 сен 2026 в 01:54)
Цитата (leretbor @ 2 сен 2026 в 01:53)
Цитата (Lenovatan @ 2 сен 2026 в 01:51)
Цитата (leretbor @ 2 сен 2026 в 01:49)
заметьте, после этого сообщения:

《《
хаааа, поплыл....

Реалити-шоу «Беременна в 16» изначально было создано в США. Оно выходило на канале MTV с 2009 по 2014 год.
kinopoisk.ru
ru.ruwiki.ru
gorbilet.ru
Позже аналогичное шоу появилось в Украине в 2012 году.

а то, женщина, мать трёх детей, живу в Ростове БУГАГА
》》

товарищ уже не посылает на банку!
вообще не рыпается ответить!
до этого трёхэтажным матом крыл, а тут притих!

Вопрос, почему?

потому что ты еблан. не понял еще? хуй из жопы вынь, мож тогда прочухаешь свободу мысли

слушай, хотел спросить у тебя, ты же в этом разбираешься, как я вижу, МАХ не очень хороший мессенджер, да?
ГЫ

Ты настолько упорот что еще не понял?

чего там по ящику после "беременна в 16" идёт в Ростове?
Телемарафон «Единые новости» ?
или
«От пацанки до панянки»
BattlePorQ 2 сен 2026 в 02:03
Парасьонах  •  На сайте 17 лет
0
Цитата (Lenovatan @ 2 сен 2026 в 01:59)
ага и ЯПовский 45. иди не пизди

Не, серьёзно, ни разу в мультиках сниматься не предлагали.
mpishi 2 сен 2026 в 02:07
Поваренок  •  На сайте 9 лет
1
могу еще послопить

# MaxLight: что программа делает сверх того, о чём написано

**Аудит исходного кода — приватность и права пользователя**

| | |
|---|---|
| Репозиторий | `ComradeBingo/MaxLight` |
| Коммит | `411a87d` (v2.0.4), ветка `main` |
| Объём | 5 916 строк кода (.cs / .xaml / .js), 31 файл |
| Дата аудита | 02.09.2026 |
| Ревизия | 2 — все находки первой редакции перепроверены, добавлено 13 новых |

Обёртка web.max.ru на WPF + WebView2. Скрытой передачи данных наружу нет. Зато часть заявленных защит в коде отсутствует, два действия с системой пользователя выполняются без его согласия, а канал обновлений сломан для части установленной базы.

**Итог в четырёх числах:**

- **0** — скрытых сетевых адресов, телеметрии и сторонних SDK. Наружу уходят только `web.max.ru`, `api.github.com` и GitHub Releases.
- **5** — заявленных функций, которых в коде нет или которые никогда не вызываются.
- **2** — действия с системой без согласия: автозапуск и завершение чужих процессов Edge.
- **1** — сломанный канал доставки исправлений: у пользователей версий 2.1.0–2.3.1 обновления не придут никогда.

---

## 1. Недокументированное вмешательство в систему

Действия, которые программа выполняет за пределами своего окна и о которых нет ни слова ни в README, ни в интерфейсе.

### #1 · КРИТИЧНО — При выходе принудительно убивает процессы Edge и WebView2, включая чужие

При закрытии приложение перебирает *все* процессы в системе и вызывает `Kill()` для каждого, чьё имя содержит `msedge`, `WebView2` или `MicrosoftEdge` и который стартовал позже MaxLight. Проверки на родительский процесс нет — `StartTime > currentProcess.StartTime` это не проверка родства.

На практике под удар попадают: открытый после MaxLight браузер Microsoft Edge со всеми вкладками, а также любое приложение на движке WebView2 — новый Outlook, Teams, панели Office, множество сторонних программ. **Убийство без сохранения — это потеря несохранённых данных пользователя в чужих приложениях.**

Код продублирован в двух местах и срабатывает по трём сценариям: выход через трей, закрытие окна и — что не очевидно — **смена настроек прокси**, где приложение само себя перезапускает через `Process.Start` + `Environment.Exit(0)`, попутно вызвав `TrayManager.Dispose()`. То есть пользователь, поменявший порт прокси, закрывает себе Edge. При штатном выходе оба блока отрабатывают друг за другом, то есть система обходится дважды.

> `MainWindow.xaml.cs:445–462` · `TrayManager.cs:283–320` · триггер перезапуска: `MainWindow.xaml.cs:404`

### #2 · КРИТИЧНО — Автозапуск Windows включается сам и включается заново после выключения

При открытии окна настроек метод `LoadAutoStartState()` читает ключ `HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run`, и если ключа нет — **сам записывает его** и ставит галочку. Пользователь просто открыл настройки; согласия никто не спрашивал.

Хуже то, что это неустранимо штатными средствами: снятая галочка удаляет ключ, но при следующем открытии настроек ключ снова отсутствует — и программа снова прописывает себя в автозагрузку. Настройка, которую пользователь выключил, молча возвращается. Про автозапуск README не упоминает вообще.

Дополнительно: ветка «ключ есть» тоже безусловно выставляет `IsChecked = true`, так что состояние «выключено» этот экран показать не может в принципе. Запись в реестр при этом идёт по двум путям сразу — из XAML-обработчика `ChkAutoStart_CheckedChanged` и из подписки `AutoStartToggled` в `MainWindow`, причём вторая вычисляет новое значение инверсией текущего состояния реестра, а не состояния галочки.

> `SettingsWindow.xaml.cs:85–103` (LoadAutoStartState) · `160–174` (обработчик) · `176–197` (SaveAutoStart) · `MainWindow.xaml.cs:402`

### #3 · ВЫСОКИЙ — Запрос аватарки уходит мимо прокси: деанонимизация при включённом прокси

Настройка прокси применяется только к WebView2 (аргумент `--proxy-server`). Картинку аватара для всплывающего уведомления скачивает отдельный `HttpClient` без какой-либо прокси-конфигурации, то есть напрямую с реального IP-адреса пользователя.

Получается сценарий, обратный ожиданиям: пользователь включил прокси именно чтобы скрыть адрес, но **каждое входящее сообщение порождает прямой запрос к серверу мессенджера с настоящего IP**. URL берётся из DOM страницы (`img.src`) и никак не ограничен доменом: абсолютный адрес уходит в запрос как есть, к домену `web.max.ru` дописывается только относительный путь.

Побочно: `HttpClient` создаётся заново на каждое уведомление и тут же уничтожается — классический источник исчерпания сокетов при потоке сообщений.

> `NotificationWindow.xaml.cs:93–99` · `WebView2Handler.cs:53–57`

### #4 · ВЫСОКИЙ — Любая внешняя ссылка запускается через ShellExecute без проверки схемы

Всё, что не относится к `max.ru` и `oneme.ru`, передаётся в `Process.Start(UseShellExecute = true)` как есть. Список разрешённых схем отсутствует, подтверждения нет. Ссылка из сообщения со схемой вроде `file:`, `ms-msdt:`, `search-ms:` или любым зарегистрированным в системе обработчиком запускается одним кликом.

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

> `WebView2Handler.cs:84–120` (OnNewWindowRequested)

### #5 · СРЕДНИЙ — Выход из аккаунта молча стирает PIN-код

Кнопка «Выйти из аккаунта» вызывает `ClearAuthData()`, где вместе с токеном обнуляется и `PinHash` — с комментарием «на всякий случай пин-код тоже сносим». Диалог подтверждения об этом не сообщает, README тоже.

Пользователь, который выходил из аккаунта чтобы перелогиниться, после этого остаётся без установленной им защиты и не получает об этом уведомления.

> `ConfigManager.cs:313–321` · `SettingsWindow.xaml.cs:322–332`

### #6 · СРЕДНИЙ — При каждом старте запускается `dotnet` из неквалифицированного пути

Перед показом окна приложение вызывает `Process.Start` с `FileName = "dotnet"` и `UseShellExecute = false`. Полный путь не указан, поэтому Windows разрешает имя по стандартному порядку поиска: **сначала каталог самого приложения, затем текущий рабочий каталог**, и только потом системные папки и `PATH`. Подложенный в любую из этих папок `dotnet.exe` выполняется при каждом запуске MaxLight. Каталог установки (`%LocalAppData%\MaxLight\current\`) доступен на запись самому пользователю, а рабочим каталогом становится та папка, из которой открыли ярлык или файл.

Сама проверка при этом бессмысленна: код, который её выполняет, уже исполняется на .NET 10 — иначе он бы не запустился. Зато она даёт ложноотрицательный результат, если рантайм установлен, а CLI `dotnet` в `PATH` отсутствует: приложение откажется стартовать и предложит скачать то, что уже стоит.

> `Program.cs:68–86` (проверка и диалог) · `Program.cs:176–200` (IsDotNetRuntimeInstalled)

---

## 2. Защиты и функции, которых в коде нет

Пункты из README и окна «О программе», которые не подтверждаются исходным кодом. Это не «реализовано слабо» — это отсутствует либо никогда не выполняется.

### #7 · КРИТИЧНО — Блокировка трекеров не работает: обработчик написан, но не подключён

Метод `OnWebResourceRequested`, который должен отдавать 204 на запросы с трекерными подстроками, **нигде не подписан на событие** `CoreWebView2.WebResourceRequested`, и `AddWebResourceRequestedFilter` не вызывается ни разу. Без фильтра событие не возбуждается в принципе. Массив `_trackingKeywords` и весь метод — мёртвый код.

Это центральное заявленное преимущество продукта: в сравнительной таблице README стоит «MAX — 8 трекеров слежения / MaxLight — трекеры заблокированы», в окне «О программе» — пункт «🛡️ Блокировка трекеров». **Фактически весь трафик страницы, включая аналитику, проходит без изменений.** Вдобавок список ключевых слов в README (`apptracer`, `sdk-api`, `crashtoken`…) не совпадает со списком в коде — документация описывает несуществующую версию фильтра.

> `WebView2Handler.cs:24–30` (список) · `WebView2Handler.cs:374–375` (обработчик) · подписки нет во всём проекте (проверено `grep -rn "WebResourceRequested"` — единственное вхождение это само объявление)

### #8 · КРИТИЧНО — Раздела «Защита от XSS» не существует: ни CSP, ни санитизации

README отводит отдельный раздел под «внедрение специальных скриптов защиты в WebView2», «санитизацию ввода» и «CSP-заголовки». Поиск по всем файлам репозитория (`.cs`, `.js`, `.xaml`, `.md`) по подстрокам `csp`, `content-security`, `sanitiz`, `xss`, `escapehtml` даёт **ноль совпадений**.

Единственная функция экранирования в проекте — `EscapeJsString` для подстановки токена в JS-строку, к защите отображаемого контента отношения не имеющая.

> `README.md` §«Безопасность» · `grep -rni` по .cs/.js/.xaml/.md — 0 результатов

### #9 · ВЫСОКИЙ — Блокировка рекламного баннера не работает: класс никогда не создаётся

Удаление баннера (`.infobar…`) живёт в классе `PageModifier`. Выражения `new PageModifier(...)` в проекте нет: поле `_pageModifier` объявлено и трижды проверяется на `null`, но никогда не инициализируется. Все 321 строка файла и обе зарегистрированные модификации DOM не выполняются.

Вместе с классом мертва и вторая его половина — `InterceptClicksViaJavaScriptAsync`, перехват кликов по ссылкам и подмена `window.open`. То есть отключён не только баннер, но и единственный слой, который отсекал схемы `javascript:` до передачи ссылки наружу (см. #4).

Пункт «🚫 Блокировка рекламного баннера» указан в окне «О программе» как действующая функция.

> `PageModifier.cs` (весь файл) · `WebView2Handler.cs:17, 339, 368, 390` · `AboutWindow.xaml`

### #10 · СРЕДНИЙ — «Счётчик непрочитанных сообщений» считает не непрочитанные сообщения

JS-парсер честно вычисляет количество непрочитанных, суммируя числа в бейджах, и шлёт результат в C# сообщением `unread_count`. В C# это сообщение **явно проигнорировано** — `case "unread_count": // Игнорируем`. Функция `sendUnreadCount()` в скрипте, вместе с логикой пересчёта бейджей в `MutationObserver`, — мёртвый код.

Реально в трее и на иконке в панели задач показывается внутренний счётчик `_unreadCount`, который увеличивается на единицу при каждом *показанном всплывающем окне* и обнуляется при активации главного окна. То есть это счётчик пропущенных уведомлений, а не непрочитанных сообщений: он не видит сообщения, пришедшие при активном окне, сбрасывается от простого клика по окну и режется собственным антиспамом (не чаще одного уведомления в 2 секунды — и в JS, и в C#).

README дополнительно обещает «указание количества непрочитанных сообщений при наведении курсора на трей» — подсказка трея содержит только строку «Max Light — есть новые сообщения», без числа.

> `MessageHandler.cs:56–57` (игнорирование) · `MessageHandler.cs:136` (реальный счётчик) · `messageInterceptor.js:507–530` (мёртвая функция) · `TrayManager.cs:165` (подсказка)

### #11 · СРЕДНИЙ — Режим «инкогнито» держится не на инкогнито, а на временной папке

Аргумент `--incognito` передаётся в `AdditionalBrowserArguments`, но WebView2 такой режим не поддерживает и аргумент игнорирует. Приватность в реальности обеспечивает другое: профиль каждый раз кладётся в новую папку с GUID-именем.

Важнее расхождение в жизненном цикле этой папки. README: «временная папка для работы удаляется автоматически после завершения работы». В коде удаление (`SafeCleanupOldSessions`) выполняется **при следующем запуске**. До него профиль со всей историей сессии лежит в папке установки; если приложение больше не запускать или удалить — данные остаются на диске навсегда.

> `WebView2Handler.cs:53–56, 243–253, 255–261`

---

## 3. Хранение данных, токен и PIN

Механизм описан в README верно по смыслу — приложение перехватывает токен авторизации и переживает его между сессиями. Неверны детали, от которых зависит оценка риска.

### #12 · ВЫСОКИЙ — Данные лежат не в реестре, а в JSON-файле рядом с программой

README: «все чувствительные данные (токен, deviceId, PIN-код) хранятся в зашифрованном виде в реестре Windows». Фактически всё это — `config.json` в каталоге на уровень выше исполняемого файла (для установленной версии это `%LocalAppData%\MaxLight\config.json`), в portable-режиме — прямо в папке программы. В реестр пишется только ключ автозапуска.

Разница существенна: файл виден в проводнике, копируется вместе с папкой portable-версии, попадает в бэкапы и в синхронизацию облачных дисков — а пользователь по описанию ожидает защищённое системное хранилище.

> `ConfigManager.cs:29–55` (GetConfigPath) · `README.md` §«Шифрование данных»

### #13 · ВЫСОКИЙ — При сбое шифрования токен молча записывается открытым текстом

Обёртка над DPAPI построена так: `catch { return plainText; }`. Если `ProtectedData.Protect` по любой причине не сработает (перемещаемый профиль, повреждённый ключ, нестандартная конфигурация), **токен авторизации уходит в config.json в чистом виде**, а приложение продолжает работать как ни в чём не бывало — ни исключения, ни записи, ни предупреждения пользователю.

Расшифровка симметрично возвращает шифротекст при ошибке, так что состояние «шифрование отвалилось» внешне неотличимо от нормального. Побочный эффект: обработчик ошибок расшифровки в `LoadConfig`, который должен был обнулять испорченный токен, недостижим — `DecryptString` исключение не пробрасывает, а возвращает строку, и в `localStorage` уезжает шифротекст вместо токена.

> `ConfigManager.cs:227–252` (EncryptString / DecryptString) · `ConfigManager.cs:131–143` (недостижимый catch)

### #14 · СРЕДНИЙ — «AES-256» — это DPAPI с публичной энтропией из открытого кода

README и окно «О программе» обещают «зашифрованное хранилище (AES-256)». Под этим — `ProtectedData.Protect` с областью `CurrentUser` и энтропией `"MaxLight_Secure_Store_2024"`, захардкоженной в открытом исходном коде.

Это штатная и разумная для десктопа схема, но её граница защиты стоит ровно там, где граница учётной записи Windows: **любой процесс, запущенный от имени того же пользователя, расшифровывает токен пятью строками кода**, зная энтропию из GitHub. От вредоносного ПО в профиле пользователя это не защищает — а формулировка «AES-256» создаёт впечатление обратного.

> `ConfigManager.cs:225` (Entropy) · `AboutWindow.xaml`

### #15 · ВЫСОКИЙ — PIN-код не защищает данные и снимается блокнотом

PIN проверяется только внутри интерфейса; токен лежит в том же `config.json` и от PIN никак не зависит. Достаточно удалить из файла поле `PinHash` — и приложение стартует с сохранённой сессией без единого вопроса.

Сам хэш — `SHA-256` без соли и без растяжения, PIN ограничен 4–6 цифрами: полный перебор всего пространства занимает секунды. Кроме того README расходится с кодом сразу трижды: заявлено «3 попытки» — в коде 5; «блокировка» — на деле просто закрытие приложения, после перезапуска снова 5 попыток; «проверка при каждом запуске» — **PIN спрашивается только если сохранён токен**, иначе приложение молча предлагает задать новый.

> `PinEntryWindow.xaml.cs:10, 68–108` · `ConfigManager.cs:327–373` · `MainWindow.xaml.cs:102–161`

### #16 · СРЕДНИЙ — PIN переустанавливается без знания текущего, если нет сохранённого токена

Диалог смены PIN в настройках сделан правильно: он требует ввести текущий PIN перед заменой. Но ветка старта в обход него: если сохранённого токена нет, `MainWindow_Loaded` **безусловно** показывает окно установки PIN и по кнопке «Сохранить» вызывает `SavePinCode`, перезаписывая существующий `PinHash` без всякой проверки.

Сценарий достижим: пользователь задал PIN при первом запуске и не завершил авторизацию, либо вышел из аккаунта (см. #5). Практический ущерб невелик именно потому, что PIN и так ничего не защищает (#15), но заявленная модель «PIN меняется только по предъявлении старого» ломается.

> `MainWindow.xaml.cs:106–128` · сравнить с `PinSettingsDialog.xaml.cs:22–33`

### #17 · НИЗКИЙ — Последние 4 символа токена пишутся в конфиг открытым текстом

Помимо `EncryptedToken` в `config.json` сохраняется поле `TokenPreview` — «...» плюс последние четыре символа токена в чистом виде. Функциональной нагрузки в текущем коде у поля нет: нигде, кроме собственного пересохранения, оно не читается. Это чистая утечка фрагмента секрета в незашифрованную часть файла.

> `ConfigManager.cs:182–184, 519`

---

## 4. Обновления как канал доверия

### #18 · ВЫСОКИЙ — Версия откачена назад: часть пользователей больше не получит ни одного обновления

История версий в `MaxLight.csproj` идёт так: `2.0.0 → 2.1.0 → 2.3.0 → 2.3.1` (все 21.08.2026), затем коммит «v2.0.0: переход на NET10» от 24.08 **сбрасывает `AssemblyVersion` обратно на 2.0.0**, и дальше нумерация идёт заново — 2.0.1, 2.0.2, 2.0.3, 2.0.4.

Velopack сравнивает версии семантически и предлагает только более новую. Для всех, кто установил сборку из линии 2.1.0–2.3.1, актуальный релиз 2.0.4 — это версия *ниже* установленной. **Обновление им не будет предложено никогда**, а кнопка «Проверить обновления» в настройках честно ответит «Обновлений нет». Единственный выход — ручная переустановка, о необходимости которой пользователь не узнает.

Это не косметическая проблема: канал доставки исправлений для части установленной базы закрыт молча и бессрочно.

> `MaxLight.csproj:12` (`AssemblyVersion`) · история: `6a7627e` (2.3.1) → `0dd1af0` (2.0.0) · `UpdateChecker.cs:186–197` (IsNewerVersion)

### #19 · СРЕДНИЙ — Фоновое автообновление без подписи кода: тихий канал выполнения кода

Velopack проверяет GitHub Releases через 5 секунд после старта и далее каждые 6 часов, скачивает и применяет обновление в фоне с перезапуском. README подаёт это так: «целостность файлов (SHA1) при обновлении контролируется Velopack».

SHA1 берётся из того же `releases.json`, что и сам пакет, и подтверждает лишь отсутствие повреждений при скачивании — но не подлинность автора. Подписи кода в проекте нет. **Кто получит контроль над репозиторием или аккаунтом сопровождающего, тихо выполнит произвольный код на машинах всех пользователей при ближайшем запуске.** Это свойство архитектуры, а не ошибка реализации, — но пользователь, читающий про «контроль целостности», понимает написанное иначе.

Отдельно: README §5 утверждает, что парсер «зашит в .exe файл, чтобы избежать внесения изменений злоумышленниками». Скрипт действительно упакован как `EmbeddedResource`, но исполняемый файл не подписан и его целостность ничем не проверяется — встраивание ресурса не является защитой от модификации.

> `UpdateChecker.cs:20, 35, 97–142, 144–202` · `README.md` §«Система обновлений», §5

### #20 · СРЕДНИЙ — Утерян принятый фикс атомарного сохранения конфига

24.07.2026 в проект был принят PR #4 (`2120351`, слит в `d2a1e49`): запись `config.json` через временный файл + `File.rерlасе`, резервная копия `.bak`, сохранение битого файла как `.corrupt-<дата>` и межпроцессный мьютекс вокруг load/save. Причина в описании коммита названа прямо: «File.WriteAllText не атомарен, при гонке старого и нового процесса во время рестарта Velopack файл обрезается, а LoadConfig на битом JSON молча возвращал пустой конфиг (терялись Auth/Pin/настройки)».

В коммите `c7b64a6` «Полная замена на версию 2.0.0» история была переписана, и весь этот код исчез. **В текущей версии снова `File.WriteAllText` без временного файла, без резервной копии и без межпроцессной блокировки**, а `LoadConfig` на исключении по-прежнему тихо подставляет пустой `ConfigData`. Тот самый баг «после обновления слетела авторизация» вернулся вместе с сохранением конфига в каталог, который Velopack перезаписывает при рестарте.

> `ConfigManager.cs:210` (запись) · `ConfigManager.cs:152–157` (сброс на пустой конфиг) · утраченная реализация: `git show 2120351`

### #21 · НИЗКИЙ — Лицензии MIT в актуальной ветке нет

README заявляет «открытый исходный код, MIT лицензия» и делает из этого пункт сравнения с официальным клиентом. Файла `LICENSE` в ветке `main` нет, в ветке `master` тоже, заголовков лицензии в исходниках нет.

При этом текст MIT в репозитории когда-то был: он лежит в самом первом коммите `dbec7d4` («Initial commit», MIT License, Copyright © 2026 Comrade Bingo), который после нескольких перезаписей истории перестал быть предком какой-либо ветки. То есть намерение автора зафиксировано документально, а формально пользователь прав на использование и распространение кода не получает — по умолчанию действует «все права защищены». Правится возвратом одного файла: `git show dbec7d4:LICENSE > LICENSE`.

> ветка `main`: `README.md`, `.gitignore`, `MaxLight2.slnx`, `MaxLight2/` — `LICENSE` отсутствует · `git log --all -- LICENSE` → только `dbec7d4`

---

## 5. Portable-режим и одновременные экземпляры

### #22 · СРЕДНИЙ — Четыре разных определения portable-режима, и «главное» из них самое узкое

Проверка «портативная ли это сборка» написана в проекте четыре раза, независимо и с разными правилами:

| Место | `--portable` | `.portable` рядом с exe | `.portable` в родительской папке | `.portable` в `%LocalAppData%\MaxLight` |
|---|:-:|:-:|:-:|:-:|
| `ConfigManager.CheckPortableMode` | ✔ | ✔ | — | — |
| `Program.Main` | ✔ | ✔ | ✔ | — |
| `MainWindow.IsPortableMode` | ✔ | ✔ | ✔ | — |
| `SettingsWindow.IsPortableMode` | ✔ | ✔ | ✔ | ✔ |

Узнаёт о родительской папке — а именно там маркер и оказывается в раскладке Velopack — весь проект, **кроме `ConfigManager`**. В результате в такой сборке приложение считает себя portable в интерфейсе и в логике автозапуска, но `ConfigManager` считает режим обычным. Практическое следствие: `GetDownloadPath()` возвращает `%UserProfile%\Downloads` вместо папки `Downloads` внутри портативного каталога — то есть «портативная» версия оставляет файлы в профиле пользователя, чего от неё как раз и не ждут.

> `ConfigManager.cs:57–68` · `Program.cs:23–33` · `MainWindow.xaml.cs:63–80` · `SettingsWindow.xaml.cs:40–66`

### #23 · СРЕДНИЙ — Второй экземпляр стирает рабочий профиль первого

Мьютекс единственного экземпляра в portable-режиме не ставится сознательно. При этом `SafeCleanupOldSessions()` при старте удаляет из `WebView2Sessions` **все** подпапки, кроме собственной. Запуск второй копии портативной версии уничтожает живой профиль WebView2 уже работающей первой — вместе с её сессией.

Тот же мьютекс обходится любым аргументом командной строки, содержащим подстроку `--apply` (проверка на признак обновления Velopack сделана через `Contains`, без разбора аргументов), — то есть и в обычной установленной версии.

> `WebView2Handler.cs:243–253` · `Program.cs:35–41, 43–47`

### #24 · НИЗКИЙ — В portable-режиме проверка обновлений всегда молчит

`UpdateChecker` принимает флаг `isPortable` в конструктор, сохраняет в поле `_isPortable` и **больше нигде его не использует**. Фоновый и ручной опрос запускаются одинаково, но `UpdateManager` в неустановленной сборке выбрасывает исключение, которое перехватывается и уходит в `Debug.WriteLine`. Наружу это выглядит как «Обновлений нет» — независимо от того, вышла новая версия или нет. Диалог обновления при этом умеет дописывать пометку «(Portable)», то есть сценарий предполагался, но не доведён.

> `UpdateChecker.cs:15, 30` · `MainWindow.xaml.cs:377–380`

---

## 6. Мёртвый код и расхождения внутри самого проекта

### #25 · НИЗКИЙ — Защитные проверки в JS-парсере не срабатывают никогда

`messageInterceptor.js` в семи местах проверяет `window._tokenParserActive` и `window._maxLightTokenInterceptorInstalled`, чтобы не разбирать чаты, пока активен перехватчик токена. Ни одного из этих флагов не существует: C#-скрипт перехвата выставляет только `window._maxLightTokenInterceptorOriginalSetItem`. Все семь проверок всегда ложны, парсер работает и во время перехвата токена. Признак расхождения версий скрипта и хоста.

> `messageInterceptor.js:140, 223, 285, 313, 330, 347` · `WebView2Handler.cs:377` (реально выставляемый флаг)

### #26 · НИЗКИЙ — Перехватчик токена восстанавливается после каждой перезагрузки страницы

`StopTokenParser()` возвращает оригинальный `localStorage.setItem` и сбрасывает `_tokenParserActive`, но сам скрипт остаётся зарегистрированным через `AddScriptToExecuteOnDocumentCreatedAsync` и заново подменяет `setItem` при любой навигации или перезагрузке. Снять его повторно уже нельзя — флаг сброшен, и `StopTokenParser` выходит по первой строке. Токен перезахватывается и пересохраняется при каждой перезагрузке страницы.

> `WebView2Handler.cs:70, 265–270`

### #27 · НИЗКИЙ — `VelopackApp.Build().Run()` вызывается последним, а не первым

Точка входа Velopack, обрабатывающая хуки установки, удаления и первого запуска, вызвана после инициализации `ConfigManager`, после мьютекса и после диалога о .NET-рантайме. Документированное требование Velopack — вызывать её как можно раньше в `Main`. Побочный эффект уже наблюдаем в коде: `ConfigManager.EnsureConfigExists()` стоит первой строкой `Main` и создаёт `config.json` в том числе при запусках, которые Velopack делает для своих хуков.

> `Program.cs:21, 89`

### #28 · НИЗКИЙ — `README.md` внесён в `.gitignore`

Начиная с коммита `349e157` (v1.1.8) файл `README.md` перечислен в `.gitignore`. Документ уцелел только потому, что уже был под версионным контролем и правило на отслеживаемые файлы не действует. Побочный эффект: в свежем клоне правка README не показывается как изменение до явного `git add -f`, а новый файл с этим именем создать «как обычно» не получится. Единственный документ, по которому проект оценивают снаружи, помечен как игнорируемый.

> `.gitignore:11`

---

## 7. Заявлено и фактически

Сводка расхождений README и окна «О программе» с кодом на коммите `411a87d`.

| Заявлено | Фактически в коде | |
|---|---|---|
| Трекеры заблокированы (8 трекеров) | Обработчик не подключён, фильтр не установлен — фильтрации нет | **Нет** |
| Защита от XSS, санитизация ввода, CSP-заголовки | В коде отсутствует полностью | **Нет** |
| Блокировка рекламного баннера | `PageModifier` никогда не создаётся | **Нет** |
| Счётчик непрочитанных сообщений | Сообщение `unread_count` игнорируется; считаются показанные уведомления | **Нет** |
| Число непрочитанных в подсказке трея | Подсказка без числа: «есть новые сообщения» | **Нет** |
| Хранение в реестре Windows | `config.json` на диске рядом с программой | Иначе |
| AES-256 через Windows Crypto API | DPAPI CurrentUser, энтропия опубликована в исходниках | Иначе |
| PIN: 3 попытки до блокировки | 5 попыток; «блокировка» = закрытие, при перезапуске счётчик сбрасывается | Иначе |
| PIN проверяется при каждом запуске | Только при наличии сохранённого токена | Иначе |
| Временная папка удаляется после завершения работы | Удаляется при следующем запуске; иначе остаётся на диске | Иначе |
| Целостность обновлений контролируется SHA1 | SHA1 из того же манифеста; подписи кода нет | Слабее |
| Парсер «зашит в .exe, чтобы избежать изменений» | Ресурс внутри неподписанного exe; целостность не проверяется | Слабее |
| Обновление при каждом запуске | Для версий 2.1.0–2.3.1 обновлений не будет никогда (версия откачена) | **Сломано** |
| MIT лицензия | Файла `LICENSE` ни в одной ветке нет (есть в утерянном первом коммите) | **Нет** |
| Требуется .NET Framework 4.7.2 | `net10.0-windows`; без .NET Runtime 10 приложение не стартует | Устарело |
| Автозапуск — не упомянут | Включается сам при открытии настроек и возвращается после выключения | **Скрыто** |
| Завершение чужих процессов — не упомянуто | `Kill()` всех msedge / WebView2 при выходе и при смене прокси | **Скрыто** |

---

## 8. Что проверено и претензий не вызывает

Отдельно стоит сказать, чего в коде *нет* — это главный положительный итог аудита.

- **Скрытых сетевых адресов нет.** Полный перечень исходящих соединений, подтверждённый сплошным поиском по URL в исходниках: `web.max.ru` (сам мессенджер и аватарки), `api.github.com` и GitHub Releases (обновления и описание версии), `dotnet.microsoft.com` (открывается в браузере, если нет рантайма), `github.com/ComradeBingo/MaxLight` (кнопка в окне «О программе»). Ни аналитики, ни телеметрии, ни сторонних SDK. Сетевых клиентов в проекте ровно два `HttpClient`, оба перечислены выше.
- **Парсер сообщений ничего не отправляет наружу.** `messageInterceptor.js` читает из DOM имя, текст и аватар только для локального всплывающего уведомления и передаёт их исключительно в C#-хост через `chrome.webview.postMessage`. Никаких fetch/XHR/WebSocket в скрипте нет.
- **Перехват токена документирован.** Подмена `localStorage.setItem` для получения `__oneme_auth` прямо описана в README (пункт 3) как механизм «авторизация один раз» — это заявленное поведение, а не скрытая функция. Восстановление токена в страницу выполнено с двойным экранированием и собирает корректный JSON — ошибки внедрения здесь нет.
- **История git чистая по секретам.** Ключей, паролей и собранных бинарников самого приложения в коммитах нет; крупные объекты в истории — NuGet-пакеты старой .NET Framework-версии проекта (`packages/`, до 21 МБ на объект). История переписывалась минимум трижды: в репозитории четыре независимых корневых коммита.
- **Отладочные логи не пишутся на диск.** `Debug.WriteLine` печатает префикс токена и содержимое конфига, но в Release-сборке эти вызовы вырезаются компилятором. Риск существует только для отладочных сборок.
- **Реестр используется минимально** — единственный ключ, к которому обращается программа, это `Run` для автозапуска (см. #2).
- **Зависимостей всего три**, все от известных поставщиков и с фиксированными версиями: `Hardcodet.NotifyIcon.Wpf` 2.0.1, `Microsoft.Web.WebView2` 1.0.4129.50, `Velopack` 1.2.0.

---

## 9. Что чинить в первую очередь

1. Убрать массовое завершение процессов Edge/WebView2 — закрывать только собственный экземпляр WebView2 через `Dispose` хоста (#1).
2. Не включать автозапуск самостоятельно: состояние читать из реестра как есть, а запись выполнять только по клику пользователя, и одним путём, а не двумя (#2).
3. Поднять версию выше `2.3.1` (например, `2.4.0`) и выпустить релиз — иначе потерянная часть пользователей не получит ни одно из перечисленных исправлений (#18).
4. Вернуть атомарное сохранение конфига из принятого PR #4 — `git show 2120351` (#20).
5. Привести README и окно «О программе» в соответствие с кодом — либо подключить фильтр трекеров и `PageModifier`, либо убрать эти пункты из описания (#7, #8, #9, #10).
6. Подписать `HttpClient` для аватарок теми же настройками прокси, что и WebView2, либо грузить картинку внутри страницы (#3).
7. Добавить белый список схем (`http`, `https`, `mailto`) перед `Process.Start` (#4).
8. Указать полный путь к `dotnet.exe` или убрать проверку рантайма целиком — она всё равно выполняется уже внутри работающего .NET 10 (#6).
9. Убрать `catch { return plainText; }` — при сбое DPAPI отказывать в сохранении токена и сообщать пользователю (#13).
10. Исправить описание PIN, не удалять PIN при выходе из аккаунта, требовать текущий PIN при замене и не обещать защиту данных, которую PIN не даёт (#5, #15, #16).
11. Свести четыре реализации определения portable-режима в одну (#22).
12. Вернуть файл `LICENSE`: `git show dbec7d4:LICENSE > LICENSE` (#21).

---

## Границы аудита

Аудит выполнен по исходному коду коммита `411a87d` ветки `main`, статически; дополнительно просмотрена вся доступная история git (49 коммитов, 4 корневых). Опубликованные в разделе Releases бинарники не проверялись и не сопоставлялись с исходниками — воспроизводимой сборки в проекте нет, поэтому соответствие исполняемого файла этому коду на веру не принимается и не подтверждается. Динамического анализа (запуск, трассировка трафика) не проводилось. Ссылки на строки соответствуют коммиту `411a87d` и в ревизии 2 сверены заново.

Это сообщение отредактировал mpishi - 2 сен 2026 в 02:16
BattlePorQ 2 сен 2026 в 02:10
Парасьонах  •  На сайте 17 лет
1
Цитата (mpishi @ 2 сен 2026 в 02:07)
### #1 · КРИТИЧНО — При выходе принудительно убивает процессы Edge и WebView2, включая чужие

Ну то есть оно ещё и под Винду.
А нам втирают про незасирание "системы" )))
mpishi 2 сен 2026 в 02:27
Поваренок  •  На сайте 9 лет
1
Цитата (BattlePorQ @ 2 сен 2026 в 02:10)
Цитата (mpishi @ 2 сен 2026 в 02:07)
### #1 · КРИТИЧНО — При выходе принудительно убивает процессы Edge и WebView2, включая чужие

Ну то есть оно ещё и под Винду.
А нам втирают про незасирание "системы" )))

пофиг. ты завершил работу, а папка с __oneme_auth осталась. ну json без всякой фигни. иными словами, достаточно спереть папку и можно что-то вымутить. но надо разбираться предметно.

самое главное, что ты не можешь проверить сборку .exe ;) типа, если автора ломанули со всеми 2FA, то .exe на github можно выложить новый.

это всё нейрослоп и надо разбираться предметно.

подозрительно, что автор не чекнул эту потеху нейронкой.
jkl2002 2 сен 2026 в 02:46
Ярила  •  На сайте 13 лет
0
Поставил этого Маха в песочнице Shelter.
Пользуюсь редко, остальное время этот Мах у меня в заморозке вне рабочего профиля андроида.
AlexWizard 2 сен 2026 в 03:20
Ярила  •  На сайте 3 года
0
Цитата (mpishi @ 2 сен 2026 в 02:07)
могу еще послопить

# MaxLight: что программа делает сверх того, о чём написано

**Аудит исходного кода — приватность и права пользователя**

| | |
|---|---|
| Репозиторий | `ComradeBingo/MaxLight` |
| Коммит | `411a87d` (v2.0.4), ветка `main` |
| Объём | 5 916 строк кода (.cs / .xaml / .js), 31 файл |
| Дата аудита | 02.09.2026 |
| Ревизия | 2 — все находки первой редакции перепроверены, добавлено 13 новых |

Обёртка web.max.ru на WPF + WebView2. Скрытой передачи данных наружу нет. Зато часть заявленных защит в коде отсутствует, два действия с системой пользователя выполняются без его согласия, а канал обновлений сломан для части установленной базы.

**Итог в четырёх числах:**

- **0** — скрытых сетевых адресов, телеметрии и сторонних SDK. Наружу уходят только `web.max.ru`, `api.github.com` и GitHub Releases.
- **5** — заявленных функций, которых в коде нет или которые никогда не вызываются.
- **2** — действия с системой без согласия: автозапуск и завершение чужих процессов Edge.
- **1** — сломанный канал доставки исправлений: у пользователей версий 2.1.0–2.3.1 обновления не придут никогда.
[........]

Дружище, ну зачем на такую всерьёз-то? brake.gif
Вот я не поленился, прочёл всю ветку - всё стало ясно.
Понравился пост? Ещё больше интересного в ЯП-Телеграм и ЯП-Max!
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии. Авторизуйтесь, пожалуйста, или зарегистрируйтесь, если не зарегистрированы.
11 Пользователей читают эту тему (1 Гостей и 2 Скрытых Пользователей) Просмотры темы: 4 064
8 Пользователей: ФОРМАЛИН, здесьник, lukinda, LasochkaBel, AlexWizard, Kozya4444, Грошык, norman1976
Страницы: 1 ...  7 8  ОТВЕТИТЬ НОВАЯ ТЕМА

 
 

Активные темы



Наверх