Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
curl -fsSL https://raw.githubusercontent.com/audit0/Offload/main/scripts/install.sh | zsh
```

Команда скачивает последний релиз с GitHub, сверяет SHA-256, целостность подписи и идентификатор приложения, а если установлен `gh` — ещё и подтверждение сборки GitHub (что архив собран workflow этого репозитория). Затем ставит OffLoadAI в «Программы» и запускает. Прежнюю версию, которая называлась Offload, установщик закрывает и убирает; настройки, ключ Pro, журнал и сейф остаются как были. `sudo` не нужен.
Команда скачивает последний релиз с GitHub, сверяет SHA-256, целостность подписи и идентификатор приложения, а если установлен `gh` — ещё и подтверждение сборки GitHub (что архив собран workflow этого репозитория). Затем ставит OffLoadAI в «Программы» и запускает. Открытый OffLoadAI установщик сначала закрывает; если идёт копирование, программа спросит, прервать ли его, а не закрылась — установка отменяется, ничего не тронув. Новая версия копируется рядом и встаёт на место прежней в последний момент, так что прерванная установка оставляет прежнюю версию. Прежнюю версию, которая называлась Offload, установщик закрывает и убирает; настройки, ключ Pro, журнал и сейф остаются как были. `sudo` не нужен.

Хотите сначала прочитать установщик — это разумно для любой команды вида `curl | zsh`:

Expand Down
6 changes: 3 additions & 3 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ OffLoadAI переносит и удаляет файлы, поэтому без

**Открытые файлы.** Пока файлы открыты в другом приложении, перенос запрещён. Проверка идёт при плане и ещё раз — перед копированием и перед удалением оригинала: план может часами стоять в окне подтверждения. Если проверить не удалось при плане, OffLoadAI требует явного подтверждения, а не считает, что всё чисто. Архив на диске, который удаляется после «Зашифровать перенесённое» или «Вернуть и удалить с диска», тоже должен быть закрыт и не меняться с начала копирования, иначе он остаётся на месте.

**Внешние программы запускаются без оболочки.** Аргументы передаются массивом, поэтому пробелы, кавычки, `;`, `$()` и обратные кавычки в путях не становятся командами. Системные программы (`hdiutil`, `lsof`, `du`, `ssh-keygen`) берутся только из `/usr/bin`, `/bin`, `/usr/sbin`, `/sbin`; переменная `PATH` не используется.
**Внешние программы запускаются без оболочки.** Аргументы передаются массивом, поэтому пробелы, кавычки, `;`, `$()` и обратные кавычки в путях не становятся командами. Системные программы (`hdiutil`, `lsof`, `du`, `ssh-keygen`) берутся только из `/usr/bin`, `/bin`, `/usr/sbin`, `/sbin`; переменная `PATH` не используется. Окружение запущенным программам передаётся только нужное — `PATH` из известных каталогов, домашняя папка, язык и куда подключаться Docker; свои `RESTIC_PASSWORD` или `ANTHROPIC_API_KEY` человека до restic и Claude Code не доходят и не подменяют введённый пароль или вход.

**Файлы назначения не перезаписываются.** Они открываются с `O_EXCL | O_NOFOLLOW`: подложенная символическая ссылка на месте копии не приведёт к записи в чужой файл. Это касается и спутников архива — списка сумм `.sha256` и прав `.modes.json`: они пишутся так же и до переименования архива, а имя архива выбирается свободным вместе с ними. Служебные файлы с внешнего диска (журнал, списки, метки копирования) читаются без перехода по ссылкам, только если это обычный файл нужного размера: ссылка на `/dev/zero` или FIFO на их месте не подвешивает программу. Исходные файлы открываются с `O_NOFOLLOW`: если файл подменят ссылкой между проверкой и копированием, чтение не уйдёт по ней.

Expand Down Expand Up @@ -79,10 +79,10 @@ OffLoadAI переносит и удаляет файлы, поэтому без
- **Копия заголовка** — три блока метаданных BitLocker по 64 КБ, снятые с закрытого образа (права — только владельцу). Восстанавливается она на закрытый образ и проверяется открытием паролем; не подошла — прежние метаданные возвращаются, а на время работы они лежат рядом с образом.
- **Сжатие сейфа.** TRIM через образ VHDX до файла не доходит, поэтому «Вернуть место на диск» переписывает сейф заново: новый образ с тем же паролем, копирование со сверкой, и только потом замена. После этого старые копии заголовка к сейфу не подходят — OffLoadAI об этом говорит.
- **Корзина.** Удаляемое уходит в Корзину Windows так же, как из Проводника; OffLoadAI запоминает, куда легло каждое, и возвращает или удаляет насовсем только то самое (по номеру файла). То, что больше Корзины (Windows удалила бы это насовсем, не спросив), в Корзину не отправляется вовсе.
- **Внешние программы** запускаются без оболочки; системные (`powershell`, `tar`, `ssh-keygen`, `defrag`) — только из `System32`, сторонние (`docker`, `zstd`, `restic`) — из известных каталогов. Сценарии PowerShell, которые OffLoadAI запускает для разметки дисков, секретов не содержат.
- **Внешние программы** запускаются без оболочки; системные (`powershell`, `tar`, `ssh-keygen`, `defrag`) — только из `System32`, сторонние (`docker`, `zstd`, `restic`) — из известных каталогов. Окружение у них, как на Mac, — только нужное: каталоги Windows, профиль, временная папка, настройки Docker и VirtualBox (до этой версии передавалось всё окружение, и свой `RESTIC_PASSWORD` человека подменял пароль, введённый в OffLoadAI). Сценарии PowerShell, которые OffLoadAI запускает для разметки дисков, секретов не содержат.
- **Установка** командой `irm … | iex` сверяет SHA-256 и, если есть `gh`, подтверждение сборки. `OffLoadAI.exe` не подписан сертификатом: при запуске файла, скачанного браузером, Windows SmartScreen попросит подтвердить запуск. Файлы, скачанные установщиком PowerShell, отметки «из интернета» не получают.
- **Ограничения, которых нет на Mac:** сейфу нужна Windows 10/11 Pro, Enterprise или Education (в Home нет BitLocker); символические ссылки при переносе Windows создаёт только администратору или в режиме разработчика — без этого перенос папки с ними отклоняется заранее (точки соединения создаются всегда); журнал и база решений лежат в `%LOCALAPPDATA%\Offload` и защищены правами профиля и BitLocker системного диска, если он включён.

## Security (English summary)

Report vulnerabilities privately via **Security → Report a vulnerability**. OffLoadAI deletes an original only after a byte-for-byte SHA-256 verified copy and a check that the source did not change; refuses to move app-registered bundles and app data; runs external tools without a shell and system tools only from system directories; cross-checks two independent traversals (`readdir` and `fts`) before deleting anything; trashes a redundant duplicate only after re-comparing it byte-for-byte with the copy that stays (one copy of every file always stays, library media, bundles, git projects, APFS clones, not-downloaded iCloud files, encrypted .dmg and .iso images are never removed); cleanup acts only on your explicit "yes" to each question: deletion is offered only for regenerable caches from a fixed list (not caches of running apps), Docker build cache and dangling images (never tagged images, volumes or containers), redundant duplicate copies, and installers older than a week (only by their own answer, never by "Allow all"); UTM virtual machines are never deleted — that is done in UTM itself; everything it deletes except Docker images goes to the Trash with one-click "put back" (permanent deletion only on request, only of what this run trashed); learns habits from your own answers only on this Mac (a habit never adds anything to a deletion question; "Forget my decisions" clears them); never overwrites destination files or follows symlinks when reading sources (`O_EXCL | O_NOFOLLOW`); applies restored permissions only to paths that were actually restored; passes the vault password to `hdiutil` via stdin; treats the on-drive journal as untrusted; validates Docker volume names and runs helper containers with `--network none --log-driver none`; refuses to touch a non-local Docker context; verifies Docker volume archives by per-file content hashes; restores only into a volume it created itself; locks the vault root to the owner (`700`); flushes copies with `F_FULLFSYNC` and verifies them bypassing the page cache. The optional AI assistant is the only part that goes online: it runs only with consent given per backend (Anthropic via Claude Code or an API key, local Ollama, or the OffLoadAI server, which also receives the Pro key with the buyer's name) and revocable at any time; it sends paths relative to home, sizes, dates and rule marks — the beginning of small text files only if you turn that on, and never for spreadsheets, key files or text that looks like a password, token, card number or recovery phrase; its advice is re-checked by the same rules (it can suggest deleting only regenerable caches and installers older than a week, anything else only moving to the vault), re-checked again before trashing, and every action is your click. Known limitations: ad-hoc signing without notarization, checksum-from-same-release in the curl installer, heuristic secret detection for open backups and for assistant previews (off by default). The Windows version (`windows/`) keeps the same rules with Windows mechanisms: `CREATE_NEW` + reparse-point-safe opens, `FlushFileBuffers` and unbuffered verification, two traversals (`FindFirstFileEx` and .NET enumeration), Restart Manager for open files, a BitLocker (XTS-AES-256) VHDX vault whose encryption is verified from the image header before opening and by BitLocker itself after, password passed to BitLocker via WMI, administrator rights only for an elevated vault helper process reached over an ACL-restricted, peer-verified named pipe, and the Windows Recycle Bin with identity checks.
Report vulnerabilities privately via **Security → Report a vulnerability**. OffLoadAI deletes an original only after a byte-for-byte SHA-256 verified copy and a check that the source did not change; refuses to move app-registered bundles and app data; runs external tools without a shell, with only the environment they need (your own `RESTIC_PASSWORD` or `ANTHROPIC_API_KEY` never reaches restic or Claude Code), and system tools only from system directories; cross-checks two independent traversals (`readdir` and `fts`) before deleting anything; trashes a redundant duplicate only after re-comparing it byte-for-byte with the copy that stays (one copy of every file always stays, library media, bundles, git projects, APFS clones, not-downloaded iCloud files, encrypted .dmg and .iso images are never removed); cleanup acts only on your explicit "yes" to each question: deletion is offered only for regenerable caches from a fixed list (not caches of running apps), Docker build cache and dangling images (never tagged images, volumes or containers), redundant duplicate copies, and installers older than a week (only by their own answer, never by "Allow all"); UTM virtual machines are never deleted — that is done in UTM itself; everything it deletes except Docker images goes to the Trash with one-click "put back" (permanent deletion only on request, only of what this run trashed); learns habits from your own answers only on this Mac (a habit never adds anything to a deletion question; "Forget my decisions" clears them); never overwrites destination files or follows symlinks when reading sources (`O_EXCL | O_NOFOLLOW`); applies restored permissions only to paths that were actually restored; passes the vault password to `hdiutil` via stdin; treats the on-drive journal as untrusted; validates Docker volume names and runs helper containers with `--network none --log-driver none`; refuses to touch a non-local Docker context; verifies Docker volume archives by per-file content hashes; restores only into a volume it created itself; locks the vault root to the owner (`700`); flushes copies with `F_FULLFSYNC` and verifies them bypassing the page cache. The optional AI assistant is the only part that goes online: it runs only with consent given per backend (Anthropic via Claude Code or an API key, local Ollama, or the OffLoadAI server, which also receives the Pro key with the buyer's name) and revocable at any time; it sends paths relative to home, sizes, dates and rule marks — the beginning of small text files only if you turn that on, and never for spreadsheets, key files or text that looks like a password, token, card number or recovery phrase; its advice is re-checked by the same rules (it can suggest deleting only regenerable caches and installers older than a week, anything else only moving to the vault), re-checked again before trashing, and every action is your click. Known limitations: ad-hoc signing without notarization, checksum-from-same-release in the curl installer, heuristic secret detection for open backups and for assistant previews (off by default). The Windows version (`windows/`) keeps the same rules with Windows mechanisms: `CREATE_NEW` + reparse-point-safe opens, `FlushFileBuffers` and unbuffered verification, two traversals (`FindFirstFileEx` and .NET enumeration), Restart Manager for open files, a BitLocker (XTS-AES-256) VHDX vault whose encryption is verified from the image header before opening and by BitLocker itself after, password passed to BitLocker via WMI, administrator rights only for an elevated vault helper process reached over an ACL-restricted, peer-verified named pipe, and the Windows Recycle Bin with identity checks.
Loading