AfterPack — це захист JavaScript, що працює після збірки. Він бере бандл, який видає ваш інструментарій, і переписує його в щось, що людина чи AI-агент не може прочитати, знайти в ньому потрібне або змінити без непропорційних зусиль. Він підключається до вашої наявної збірки одним рядком або запускається над каталогом виводу взагалі без плагіна.
Чому фіксовані шари обфускації не працюють
Більшість обфускаторів постачають дві речі, якими може скористатися зловмисник: стос шарів, застосованих один за одним, і заздалегідь заготовлені структури, які інструмент упізнає з першого погляду (масив рядків, навіть зашифрований, власний інтерпретатор VM, упізнаваний завантажувач декодера). Рецепт відновлення механічний: визначити шар або структуру за сигнатурою, зняти її, повторювати, доки не проявиться оригінал. webcrack і restringer роблять саме це, за мікросекунди.
AfterPack не постачає стосу шарів і готового декодера. Кожна збірка має іншу форму, тож інструменти, написані під шаблони однієї збірки, ламаються на наступній. Той, хто запускає ваш код, усе одно може прочитати значення, які він використовує. Порівняння з цими інструментами винесено на окрему сторінку.
AI-агенти змінили загрозу
Передова модель не просто підсумовує мініфікований код: агенти на кшталт Claude Code тепер деобфускують результат традиційних обфускаторів. В одному публічному експерименті агент розібрав і javascript-obfuscator, і комерційний інструмент (JScrambler) до читабельної логіки приблизно за десять хвилин (запуск описано в нашому блозі).
Перейменування, масив рядків і кілька шарів більше не дають захисту: це саме ті шаблони, з якими ці інструменти й моделі справляються найкраще. Модель загроз показує, який супротивник долає яку техніку. Проти шаблонних інструментів досі працює нова форма в кожній збірці: розпізнавач, написаний під одну збірку, доводиться переписувати для наступної.
Що вже робить стандартна обфускація
AfterPack працює після вашого бандлера, на зібраному результаті, і ніколи не зачіпає ваш вихідний код, через плагін для фреймворку або CLI після збірки. Швидкий старт є п'ятихвилинною версією.
Free застосовує все це:
- Кодує ваші рядкові літерали. За будь-якої додатної цільової складності мінімальне кодування рядків увімкнене, тож рядковий літерал переписується у вибраний сідом декодер під час виконання замість того, щоб лежати в артефакті текстом. Це увімкнено за замовчуванням, і це найбільша відмінність від мініфікованого коду. Прологи директив, операнди порівняння з
typeof, імена властивостей, потрібні рантайму, та імена експортів залишаються читабельними, а кілька рядкових значень із вихідного коду можуть залишитися всередині сильно мініфікованих сторонніх бандлів; збірка повідомляє, скільки їх уціліло, а Protection Map перелічує їх. - Переписує вашу логіку в еквівалентні форми, які стандартні інструменти не можуть згорнути назад: змішана булево-арифметична логіка, непрозорі предикати, байткодова VM для цілочислових виразів. Статичний читач усе ще може дійти назад до вашого оригіналу ціною реальних зусиль, а інструмент, написаний під форми однієї збірки, ламається на наступній.
transforms.<kind>.enabledвмикає та вимикає окремі сімейства. - Перебудовує потік керування та структуру: сплощення потоку керування, мертві гілки, поглиблення областей видимості, переплетення перехресних залежностей.
- Змінює все на кожній збірці завдяки поліморфізму для кожної збірки (див. нижче).
Стандартний варіант без конфігурації — light: мінімальне кодування рядків і перейменовані ідентифікатори, без структурного роздування. Підвищення пресету до medium або вище додає описану вище структурну роботу; читабельність рядків уже на своєму мінімумі незалежно від пресету. Усе це працює на кожному тарифі, зокрема Free; межу між Free і Pro описано на сторінці Тарифи.
Нова програма на кожній збірці
AfterPack виводить результат із сіда для кожної збірки, який за замовчуванням випадковий. Дві збірки одного й того самого вихідного коду виходять структурно різними: інші імена, інші кодування, інша форма всюди.
Починаючи з medium, це більше, ніж косметичне перетасування. AfterPack змінює структуру самої програми, а не лише її текст: потік керування сплощується і перевпорядковується, значення обчислюються заново при кожному використанні замість того, щоб зберігатися, а частини бандла, які були незалежними, виходять переплетеними одна з одною. Постачається функціональний еквівалент того, що ви написали, інша програма, яка поводиться так само, а сід вирішує, який саме еквівалент ви отримаєте цього разу.
Тож інструменти, написані під шаблони однієї збірки, ламаються на наступній, а місце для патча доводиться шукати заново в кожному релізі. Той, хто запускає код, усе одно може прочитати значення, які він використовує. Часті релізи щоразу повторюють цю ціну. Збірки й релізи пояснюють, як зробити це звичкою.
Для відтворюваного результату, заради влучань у кеш або аудиту, закріпіть сід за допомогою --seed=git у CLI або seed: "git" у плагіні. Обидва варіанти виводять його з вашого коміту. Див. Збірки та релізи.
Що зловмисник може насправді відновити
Не кожна трансформація підвищує ціну відновлення однаково. AfterPack розподіляє свій захист за класами відновлення; знаючи, який із них покриває ділянку, ви знаєте, з чим піде зловмисник.
Це класи для статичного зловмисника: вони описують, з чим стикається той, хто читає байти, grep, інструменти для AST або LLM, яка пояснює код, не запускаючи його. Зловмисник, який запускає артефакт в інструментованому рантаймі, є окремим, сильнішим випадком; його розглянуто нижче в розділі Межі та на сторінці Модель загроз.
Збірка на будь-якому пресеті залишається в класі «Перейменовано й закодовано» в усьому бандлі; важчий пресет виконує більше цієї роботи, а не переходить до іншого класу. Protection Map розфарбовує кожен токен за його складністю й називає клас коду, який ви виділили.
Перевизначення для ділянок, preset=hard і preset=extreme, підвищують цільову складність ділянки і примусово вмикають для неї мінімальне кодування рядків, зосереджуючи ту саму роботу там, де ви цього просите.
Як уберегти секрети
Захист секрету використовує інший механізм, ніж перебудова вашого коду. Секрет (API-ключ, сід ліцензії, порогове значення) присутній у будь-якій програмі, яка поводиться так само, тож перебудова коду навколо нього його не приховує.
Від статичного читача або LLM, що читає код наосліп, секрет приховує нематеріалізація: значення ніколи не з'являється в результаті. transforms.comparisonHardening.enabled забезпечує її для літерала, з яким порівнює ваш код, переписуючи порівняння в перевірку одностороннього дайджесту, тож постачається лише дайджест. preset=extreme на секретному літералі робить відновлення дорогим, але літерал усе ще присутній у результаті.
Зловмисник, який запускає ваш код в інструментованому рантаймі, може дістатися будь-якого секрету, яким користується сам код. Жоден обфускатор, що працює під час збірки, цього не змінює: якщо запущеній програмі потрібне значення, наполегливий динамічний зловмисник може його спостерігати. Нематеріалізація перемагає статичного читача та LLM, що читає код наосліп, і підвищує ціну повторного видобування при кожній ротації. Вона не робить клієнтський секрет невідновлюваним. Цінні секрети мають зберігатися на сервері, де клієнт їх ніколи не тримає.
Межі
Перевірка ліцензії в ділянці /* @afterpack preset=hard */, яка часто виходить у релізах зі змінним сідом, не варта інженерних годин на злам до виходу наступного релізу. Для більшості продуктів це правильна планка.
Захист економічний. За необмеженого часу будь-який клієнтський код можна певною мірою відновити. Мета полягає в тому, щоб підняти ціну вище за цінність і змусити цю ціну повторюватися з кожним релізом. Коли актив вартує більше за будь-які зусилля з відновлення, тримайте його на сервері, де клієнт його ніколи не тримає. AfterPack посилює таку архітектуру; він її не замінює. Посібник із найкращих практик пояснює, як витрачати захист там, де це важливо.
Далі
- Класи відновлення: таблиця трьох класів докладно, для кожної трансформації.
- Модель загроз: драбина супротивників від A0 до A5 і вісь «статичний проти динамічного».
- Protection Map: перегляд по токенах, що доводить, який клас покрив який рядок.
- Найкращі практики: що позначати, що не чіпати і як ротувати збірки.
- Тарифи: повна межа між Free / Pro / Team / Enterprise.
- Швидкий старт: встановіть плагін і випускайте захищений результат за кілька хвилин.
- Фреймворки: плагін для вашого стека або шлях через CLI, коли плагіна немає.
- Конфігурація: кожен згаданий вище ключ і через який інтерфейс його можна задати.
- Пресети: драбина
minify/light/medium/hard/extreme. - Директиви: граматика маркерів, що стоїть за
preset=hardіskip.