# AfterPack threat model: सुरक्षित surface

AfterPack का security-review दस्तावेज़: वह किस asset की रक्षा करता है, हर attacker class क्या recover करती है, एक secret कैसे बचता है, मौजूदा scope कहाँ ख़त्म होता है, और किन controls के साथ यह काम करता है।

Source: https://www.afterpack.dev/hi/docs/threat-model

AfterPack एक asset की रक्षा करता है: **वह JavaScript artifact जो आपकी build बनाती है**। यह उस artifact को इस तरह फिर से लिखता है कि उसे पढ़ना, fingerprint करना या patch करना attacker के लिए असली मेहनत हो, और एक build के लिए बनाए गए tools अगली build पर टूट जाएँ।

यह पेज security review में पढ़ने के लिए लिखा गया है। यह बताता है कि किस surface की रक्षा होती है, हर attacker class क्या recover करती है, किस बिंदु पर build-time control काम करना बंद कर देता है, और बाक़ी को कौन-से controls संभालते हैं।

## सुरक्षित surface

| किसकी रक्षा होती है | कौन-सा attack संभव नहीं रहता | कौन-सी property यह काम करती है |
|---|---|---|
| आपके ship किए bundle की पठनीयता | Bundle को किसी tool या model में paste करके अपना source वापस पा लेना | Identifiers rename किए जाते हैं, strings encode की जाती हैं, control flow flatten किया जाता है और identities fuse की जाती हैं, इसलिए bundle को पढ़कर अपने source तक वापस पहुँचने में असली मेहनत लगती है, जो हर build पर दोबारा करनी पड़ती है |
| आपके bundle की *संरचना* | एक बार deobfuscator, signature या patch script लिखकर हर release पर दोबारा इस्तेमाल करना | हर build के लिए नया [`seed`](https://www.afterpack.dev/hi/docs/config#seed), इसलिए एक build के patterns के लिए लिखे गए tools अगली build पर टूट जाते हैं |
| आपके implementation का attribution | यह साबित करना कि ship किया गया bundle आपका code, आपकी library या आपका algorithm है | नतीजे को आपके code से मिलाने से पहले static reader को हर build पर renamed & encoded recovery का काम दोबारा करना पड़ता है; provenance नष्ट करने वाली वे classes, जो इस मिलान को पूरी तरह हटा देतीं, आज नहीं बनतीं |
| String सामग्री जिससे आप तुलना करते हैं | किसी token या gate string के लिए bundle को grep करना | [String floor](https://www.afterpack.dev/hi/docs/config#strings-encode), और equality gate के लिए [non-materialization](#protecting-a-secret)। `light` पर numbers पढ़े जा सकते हैं |
| इस्तेमाल में artifact की integrity | एक check को patch करके patched build ship करना | नया [`seed`](https://www.afterpack.dev/hi/docs/config#seed) हर release में patch की जगह बदल देता है। [Self-integrity](#anti-tamper) केवल अपनी check table में किए गए बदलाव पकड़ता है |

नीचे की हर बात इन पाँच rows को स्पष्ट करती है: किसे हराना है, हर property कितनी दूर तक पहुँचती है, और वह कहाँ नहीं पहुँचती।

## Attacker classes

दो axes, एक scale नहीं। एक **[static attacker](https://www.afterpack.dev/hi/docs/reversal-classes#static-attacker-defined)** bytes पढ़ता है: grep, AST tooling, एक deobfuscator pass, या एक frontier model जो code को चलाए बिना समझाता है। एक **dynamic attacker** artifact को चलाता है: patched runtime में, built-ins को hook करके, या offline replay किए गए recorded execution trace के विरुद्ध। एक transform पढ़ने वाले के विरुद्ध मज़बूत और चलाने वाले के विरुद्ध कमज़ोर हो सकता है, और दोनों को एक मान लेना इस category का सबसे आम बढ़ा-चढ़ाकर किया गया दावा है।

नीचे की सीढ़ी attacker की क्षमता के क्रम में है। लागत दूसरी rows की तुलना में है, कोई absolute आँकड़ा नहीं।

| पायदान | Attacker | Scope | Attacker की लागत | नतीजा |
|---|---|---|---|---|
| **A0** | Static pattern tools: grep, AST matchers, deterministic deobfuscator passes | एक build | मामूली | जो plaintext में बचा है, वही recover होता है। मौजूदा deobfuscators grep से ज़्यादा कुछ नहीं निकालते ([मापे गए नतीजे](#measured-results))। |
| **A1** | एक blind model: एक बार पढ़ना, कोई execution नहीं, कोई tools नहीं | एक build | मामूली | जो पढ़ा, उसका ज़्यादातर हिस्सा reverse कर लिया: तीन छोटे programs पर इसने `light` पर तीनों, `medium` पर दो और `extreme` पर एक को पूरी तरह reverse किया, और जहाँ यह चलने वाला program दोबारा नहीं बना सका, वहाँ भी इसने ज़्यादातर planted secrets recover कर लिए ([मापे गए नतीजे](#measured-results))। |
| **A2** | Execution, tooling और budget वाला एक agentic model | एक build | कम, हर build पर | उस build के लिए हार: code चलाने से उसकी values सामने आ जाती हैं। उस build की बनावट पर बने tools अगली build के लिए दोबारा बनाने पड़ते हैं। |
| **A3** | AfterPack के अपने output के बड़े sample पर trained एक model | पूरा distribution, एक build नहीं | एक बार का निवेश, फिर हर build पर नगण्य | मापा नहीं गया। नीचे देखें। |
| **A4** | Instrumented dynamic analysis: hooked built-ins, recorded execution, heap snapshots | एक build, सस्ते में दोहराने योग्य | Analyst का समय, हर build पर | Strings के लिए नहीं टिकता: एक runtime hook ने हर preset पर 97 में से 96 recover कीं ([मापे गए नतीजे](#measured-results))। देखें [सीमा](#the-boundary)। |
| **A5** | एक privileged runtime: patched browser, JavaScript layer से नीचे native hooks | एक build | ऊँचा setup, फिर नगण्य | नहीं टिकता, client-side किसी भी चीज़ के लिए। |

पायदान क्षमता में cumulative हैं, संभावना में नहीं। A0 ship किए गए JavaScript पर होने वाले असली attacks के भारी बहुमत को कवर करता है: कोई free tool चलाता है या आपका bundle किसी chat window में paste कर देता है। A5 एक दुर्लभ, महँगा endgame है जिसका ज़्यादातर products को कभी सामना नहीं होता।

**A0 से A2 एक build पर attack करते हैं।** जब तक आप seed pin न करें, हर build का नया [`seed`](https://www.afterpack.dev/hi/docs/config#seed) बनावट बदल देता है, इसलिए एक build के लिए लिखा गया recognizer या patch अगली build के लिए दोबारा लिखना पड़ता है। यह values नहीं छिपाता: code जो भी इस्तेमाल करता है, उसे चलाने वाला पढ़ सकता है।

**A3 पूरे output distribution पर attack करता है।** पर्याप्त बड़े sample पर trained model per-build variance के प्रति invariant होना सीख लेता है, और आपका seed rotate करने से उसे कोई फ़र्क नहीं पड़ता। जो फिर भी मदद करता है वह है निशाना: [Pro](https://www.afterpack.dev/hi/docs/pro#what-pro-buys) आपके [mark किए regions](https://www.afterpack.dev/hi/docs/directives#what-you-can-set) पर भारी preset लगाता है और दो opt-in transform kinds जोड़ता है, [`transforms.selfIntegrity.enabled`](https://www.afterpack.dev/hi/docs/config#transforms-kind-enabled) और [`transforms.comparisonHardening.enabled`](https://www.afterpack.dev/hi/docs/config#transforms-kind-enabled)। जो सच में मायने रखता है उसे mark करें; देखें [Best practices](https://www.afterpack.dev/hi/docs/best-practices)।

**A4 और A5 static artifact को पूरी तरह छोड़ देते हैं।** [सीमा](#the-boundary) दोनों को कवर करती है।

### मापे गए नतीजे

Engine 0.2.2 के output से हर attacker ने क्या recover किया। अक्टूबर 2026 में मापा गया, planted secrets वाले पाँच programs और असली production bundles पर। Frontier model वाली row अक्टूबर 2026 में engine 0.2.6 पर किया गया एक अलग run है।

| Attacker | `light` | `medium` | `hard` और `extreme` |
|---|---|---|---|
| Pattern tools: webcrack, restringer, synchrony, terser | grep से ज़्यादा कुछ नहीं | grep से ज़्यादा कुछ नहीं | grep से ज़्यादा कुछ नहीं |
| 42 planted numbers के लिए grep | 42 | 18 | 18 |
| Output का static evaluation | 92–100% strings | behavior बनाए रखने वाले clean-up pass के बाद 96–98% strings | उसी pass के बाद 96–98% strings |
| किसी built-in पर 15 lines का runtime hook | 97 में से 96 strings | 97 में से 96 strings | 97 में से 96 strings |
| एक frontier model, blind, बिना tools, बिना execution | तीनों programs पूरी तरह reverse | 3 में से 2 पूरी तरह reverse; तीसरे ने 17 में से 12 secrets दे दिए, पर चलने वाला rebuild नहीं बना | सिर्फ़ `extreme`: 3 में से 1 पूरी तरह reverse (9 में से 9 secrets); बाकी दो ने 17 में से 12 और 3 में से 2 secrets दे दिए, पर चलने वाले rebuild नहीं बने |

Frontier model वाली row में Claude Opus 5.5 को सिर्फ़ obfuscated file मिली, और जिन 5 files को उसने मना किया, वे Claude Opus 4.8 को दी गईं; "पूरी तरह reverse" का मतलब है कि दोबारा बनाया गया code original वाले ही test vectors print करता है और उसमें हर planted secret मौजूद है। सीमाएँ: तीन programs का छोटा corpus, हर program और preset पर एक ही attempt, और attacker सिर्फ़ Claude।

## Obfuscation किसकी रक्षा करता है

AfterPack दो गुणों को लक्ष्य बनाता है। पहला है **लागत**: किसी build को reverse करने की लागत उससे ज़्यादा होनी चाहिए जिसकी वह रक्षा करता है। दूसरा है **release-cadence का फ़ायदा**: आपकी update की रफ़्तार उस रफ़्तार से तेज़ है जिससे attacker के tools अगली build पर लागू होना सीखते हैं। कोई भी obfuscator, AfterPack समेत, reversal को असंभव नहीं बनाता, और इस पेज की किसी बात को ऐसा दावा न समझें।

[डिफ़ॉल्ट preset](https://www.afterpack.dev/hi/docs/presets#the-default-is-light) identifiers को rename करता है और string literals को encode करता है। `medium` और ऊपर, AfterPack इससे ज़्यादा करता है: control flow को flatten किया जाता है, identities को fuse किया जाता है, और logic को ऐसे समतुल्य रूपों में दोबारा लिखा जाता है जिन्हें आम tools वापस नहीं समेट पाते। उस output को reverse करने वाला attacker एक चलता हुआ program recover कर सकता है, लेकिन केवल उस असली pattern-recognition के काम के बाद जिसकी लागत ये transforms लगाते हैं, और एक build की बनावट के लिए लिखा गया tool अगली build पर टूट जाता है। [Reversal classes](https://www.afterpack.dev/hi/docs/reversal-classes) इसे उन classes में बाँटता है जिनका सामना एक static reader करता है।

Per-build [`seed`](https://www.afterpack.dev/hi/docs/config#seed) default रूप से random है, इसलिए एक ही source की दो builds हर जगह संरचना में अलग निकलती हैं। Build N के patterns के लिए लिखे गए tools build N+1 पर टूट जाते हैं, जबकि build N से कोई जो values पढ़ चुका है, वे पढ़ी जा चुकी रहती हैं। यह गुण तभी काम आता है जब आप builds rotate करें; [Best practices](https://www.afterpack.dev/hi/docs/best-practices) और [Builds और CI](https://www.afterpack.dev/hi/docs/builds) बताते हैं कि rebuilds को release pipeline में कैसे जोड़ें।

इनमें से कुछ भी अपने आप में किसी secret को नहीं छिपाता। उसके लिए एक अलग mechanism चाहिए।

## एक secret की रक्षा

Secret किसी भी ऐसे program से निकल आता है जो आपके program जैसा व्यवहार करता है, उस program से भी जिसे एक static reader किसी protected region से recover करता है। Secret के आसपास के code को नया आकार देना इसके लिए कुछ नहीं करता।

Bytes पढ़ने वाले से secret की रक्षा **non-materialization** करता है, जिसे [Secrets कैसे बचते हैं](https://www.afterpack.dev/hi/docs/concepts#how-secrets-survive) में कवर किया गया है। इसे देने वाली setting, [`transforms.comparisonHardening.enabled`](https://www.afterpack.dev/hi/docs/config#transforms-kind-enabled), एक Pro setting है, डिफ़ॉल्ट रूप से बंद, और हर preset स्तर पर एक जैसा काम करती है।

जो आपका code चलाता है उसके विरुद्ध [सीमा](#the-boundary) लागू होती है। Per-build variance हर rotation पर secret को दोबारा निकालने की लागत बढ़ाता है। JavaScript engine पर लक्षित एक generic runtime hook की लागत फिर भी उतनी ही रहती है, क्योंकि वह AfterPack की संरचना पर निर्भर नहीं करता। [AfterPack कैसे काम करता है](https://www.afterpack.dev/hi/docs/concepts#how-secrets-survive) इसी mechanism को उसके साथ रखता है जो standard output पहले से करता है।

## सीमा

जो attacker आपका code एक instrumented runtime में चलाता है, वह किसी भी ऐसी value तक पहुँच सकता है जिसे code खुद इस्तेमाल करता है। अगर चलते program को उसकी ज़रूरत है, तो एक दृढ़ dynamic attacker उसे देख सकता है। AfterPack उस value को खोजना महँगा और उससे दूर [rotate](https://www.afterpack.dev/hi/docs/config#seed) करना सस्ता बनाता है। यह उसे unrecoverable नहीं बनाता।

> **Server-side authority को client से दूर रखें**
>
> Signing keys, लंबे समय तक चलने वाले credentials, और कोई भी चीज़ जिसे attacker दोबारा इस्तेमाल कर सके या बेच सके, server पर होनी चाहिए, चाहे आप कोई भी obfuscator इस्तेमाल करें।

यह सीमा केवल AfterPack की नहीं है। जैसे ही attacker runtime पर नियंत्रण कर लेता है, [हर build-time obfuscator](https://www.afterpack.dev/hi/docs/comparison) इसी दीवार से टकराता है। उस दीवार के पार AfterPack अगली release की बनावट बचाए रखता है: एक build के लिए बनाए गए tools उसके बाद वाली build के लिए दोबारा बनाने पड़ते हैं।

## Anti-tamper

Self-integrity, [`transforms.selfIntegrity.enabled`](https://www.afterpack.dev/hi/docs/config#transforms-kind-enabled), अपनी ही check table पर एक check जोड़ता है। यह केवल उस table में किए गए बदलाव को पकड़ता है। आपके code में कहीं और किया गया बदलाव, जैसे patch किया गया `return true`, पकड़ा नहीं जाता।

यह passive observation भी नहीं पकड़ता: values log करने वाला hook, heap read या native instrumentation उसकी जाँची जाने वाली किसी चीज़ को नहीं बदलते। यह एक Pro setting है, default रूप से बंद और global, और इसे जुड़ने के लिए `medium` या उससे ऊपर का code चाहिए, इसलिए `light` build में यह केवल उसी region के अंदर होता है जिसे उस स्तर तक बढ़ाया गया हो। [`preset=hard`](https://www.afterpack.dev/hi/docs/config#preset) इसे बंद छोड़ता है और इसके बजाय एक region को [complexity target](https://www.afterpack.dev/hi/docs/config#complexity) 12 तक ले जाता है, [string floor](https://www.afterpack.dev/hi/docs/config#strings-encode) चालू रखते हुए।

## AfterPack किसकी जगह नहीं लेता

AfterPack एक stack में एक control है, और security review को उसकी सीमाएँ दिखनी चाहिए। नीचे की हर row build-time control का मौजूदा scope और बाकी को कवर करने वाला control बताती है। Product के ship होने के साथ scope बदलता है; [public roadmap](https://www.afterpack.dev/hi/roadmap) ही वह एकमात्र जगह है जहाँ AfterPack बताता है कि आगे क्या आ रहा है।

| Control | आज AfterPack का योगदान | बाकी को क्या कवर करता है |
| --- | --- | --- |
| **Request-layer defense** (bots, scraping, abuse) | जो scraper आपके bundle से structured data चाहता है, उसे [पहले उसे reverse करना होगा](https://www.afterpack.dev/hi/docs/reversal-classes)। AfterPack artifact पर काम करता है और request को नहीं देखता। | एक challenge-response service (reCAPTCHA, hCaptcha, Arkose), साथ में IP, session या API key पर आधारित server-side rate limiting। |
| **Client integrity** (cheating, automation, patched clients) | [`preset=hard`](https://www.afterpack.dev/hi/docs/config#preset), [per-build-polymorphic](https://www.afterpack.dev/hi/docs/config#seed) client के विरुद्ध काम करने वाले cheat या automation लेखक को किसी ज्ञात offset को एक बार patch करने के बजाय हर release पर असली analysis दोबारा करना पड़ता है। AfterPack यह लागत बढ़ाता है; यह फ़ैसला नहीं करता। | Hits, state transitions और outcomes का server-authoritative validation, जिसमें client केवल उन फ़ैसलों को render करता है जो server पहले ही ले चुका है। |
| **Delivery integrity** (proxies, CDNs, extensions) | AfterPack अपने बनाए bytes की रक्षा करता है। यह उनके रास्ते को नियंत्रित नहीं करता, और browser की अपनी request-blocking API इस्तेमाल करने वाला extension किसी भी JavaScript के चलने से पहले तय कर लेता है कि क्या load हो। | Subresource Integrity (`integrity="sha384-…"`), ताकि browser ऐसे bundle को अस्वीकार करे जो आपके build किए hash से मेल न खाए, साथ में उस हर चीज़ का server-side validation जिसे कोई intermediary प्रभावित कर सके। |
| **Application security** (bugs, injection, broken auth) | Obfuscation source पढ़कर किसी flaw को खोजने की गति धीमी करता है। यह flaw को हटाता नहीं, और जो चलते program के ज़रिए उस तक पहुँचता है वह आपका source कभी पढ़ता ही नहीं। | Bug ठीक करें। [`npx afterpack@latest audit`](https://www.afterpack.dev/hi/docs/audit) एक live site को scan करके बताता है कि वह पहले से क्या leak कर रही है। |
| **Client के बारे में trust के फ़ैसले** | [Per-build polymorphism](https://www.afterpack.dev/hi/docs/config#seed) एक बार के patch को बार-बार दोहराई जाने वाली re-derivation लागत में बदल देता है। | [Server-authoritative validation](#not-a-substitute-for-server-authoritative-validation), नीचे। |

### Server-authoritative validation का विकल्प नहीं

ऊपर की हर row की जड़ एक ही है: एक license check, payment gate, entitlement rule, या feature flag जिसे सच में टिकना है, वह एक ऐसा फ़ैसला है जो client अपने बारे में खुद लेता है, और जो उस client को नियंत्रित करता है वह उसे जाली बना सकता है। यह client-side execution की property है, किसी खास obfuscator की कमी नहीं, और कोई भी build-time transform इसे बंद नहीं करता।

जो कुछ भी एक शत्रुतापूर्ण client के विरुद्ध टिकना चाहिए, जैसे licensing, payments, entitlements या match outcomes, उसका फ़ैसला server-side लें और client को केवल उसे दिखाने दें। AfterPack का योगदान [आर्थिक](#what-obfuscation-protects) है, और यह असली है: यह client पर चलने वाली चीज़ों पर attack करने की बार-बार की लागत बढ़ाता है।

## आगे

- [Attacker क्या recover कर सकता है](https://www.afterpack.dev/hi/docs/reversal-classes): static-attacker classes विस्तार से, diagram के साथ।
- [AfterPack कैसे काम करता है](https://www.afterpack.dev/hi/docs/concepts): standard output पहले से आपके bundle के साथ क्या करता है।
- [Protection Map](https://www.afterpack.dev/hi/docs/protection-map): अपनी build में जाँचें कि कौन-सी class किस लाइन पर लागू हुई।
- [Best practices](https://www.afterpack.dev/hi/docs/best-practices): क्या mark करें, क्या rotate करें, और क्या server-side रखें।
- [Privacy & data handling](https://www.afterpack.dev/hi/docs/privacy): आपकी मशीन से क्या बाहर जाता है, क्या store होता है, और कितने समय तक।
- [Audit](https://www.afterpack.dev/hi/docs/audit): एक live URL को उन leaks के लिए scan करें जिन्हें obfuscation पलट नहीं सकता।
- [Comparison](https://www.afterpack.dev/hi/docs/comparison): AfterPack उन tools से कैसे अलग है जिन्हें आप पहले से जानते हैं।
- [Tiers](https://www.afterpack.dev/hi/docs/tiers): Free पहले से कौन-से पायदान कवर करता है, और Pro क्या जोड़ता है।
