Worked example · 2022-07
Premint NFT-allowlist platform front-end JavaScript injection — Ethereum — 2022-07-17
Summary
Premint is an NFT-mint-allowlist-coordination platform operating in the NFT ecosystem since 2021. Its primary function is to let NFT projects collect, verify, and manage allowlist registrations from prospective minters — an operational layer that sits between the project's launch announcement and the eventual mint event. Holders register on Premint by signing a wallet message (intentionally not an on-chain transaction, just a signed message used for verification) to claim allowlist eligibility for a given drop; for some workflows, holders also interact with mint flows or claim flows mediated through Premint's interface.
On 2022-07-17, an attacker injected malicious JavaScript into the Premint front-end. The injected code displayed a pop-up to visitors prompting them to "verify" their wallet, framed in the visual style of a Premint-native flow. Holders who proceeded with the verification were prompted to sign a transaction that, in practice, executed setApprovalForAll against a series of high-value NFT contracts (BAYC, Goblintown, Otherdeed, others), granting an attacker-controlled operator address standing authority to transfer the holder's NFTs across those contracts. The attacker's downstream drainer infrastructure then executed transferFrom loops against the approved tokens before holders revoked.
Per CertiK's contemporaneous post-incident write-up [certikpremint2022], the initial enumeration was ~314 NFTs valued at ~$375K. Subsequent enumeration in the days following raised the count to ~320 NFTs and the value to ~$420K, including 6 BAYC, 2 Mutant Apes, multiple Goblintown items, and assorted Otherdeed and other items. The exact JavaScript-injection vector — supply-chain compromise of a third-party JS dependency, build-pipeline compromise, hosting-side compromise, or insider action — was discussed in industry coverage but not fully resolved in the public record at the per-incident level.
Premint published a public statement acknowledging the compromise, identified the malicious script and removed it, and committed to additional front-end security controls (subresource integrity for third-party scripts, build-pipeline review, content-security-policy hardening). The platform continued to operate post-incident.
For OAK's purposes the Premint case sits at a three-way intersection: T4.002 (front-end-side compromise as the entry vector, extending the T4.002 framing to NFT operator-grant solicitation), T4.005 (the on-chain extraction was a setApprovalForAll-class drainer flow), and T12.002 (the narrative bait was a counterfeit-mint framing distributed through a trusted NFT-utility platform). The case is a clean worked example because each of the three Techniques is loadbearing — removing any one collapses the case description into a partial picture.
Timeline (UTC)
| When | Event | OAK ref |
|---|---|---|
| Pre-2022-07-17 | Premint operates as an established NFT-mint-allowlist coordination platform; holders develop interaction familiarity with the platform's signing prompts | (operator setup) |
| 2022-07-17 (early UTC) | Attacker injects malicious JavaScript into the Premint front-end; the precise injection vector is debated in public coverage but has not been fully disclosed | T4.002 entry-vector compromise |
| 2022-07-17 (during attack window) | Visitors to the Premint front-end see an injected pop-up framed as a wallet "verification" flow; holders who proceed sign a setApprovalForAll transaction granting authority to an attacker-controlled operator address |
T12.002 narrative bait + victim-side authorisation |
| 2022-07-17 (during and post window) | Attacker's drainer infrastructure executes transferFrom loops against approved tokens; ~314 NFTs drained at first count |
T4.005 extraction |
| 2022-07-17 (within hours) | Premint detects the compromise; identifies and removes the malicious JavaScript; publishes a public statement | (operator response) |
| 2022-07-17 onward | Industry forensics (CertiK, others) publish on-chain trace and victim-list reconstruction | (forensic transparency) |
| Days following | Final tally settles at ~320 NFTs and ~$420K loss as additional victim wallets are enumerated | (loss assessment) |
| Days–weeks following | Premint commits to additional front-end security controls; community discussion focuses on subresource integrity and CSP hardening for NFT-utility platforms | (Mitigation refinement) |
What defenders observed
- The injected pop-up was framed as a Premint-native flow. The injection's UX presentation was deliberately consistent with Premint's existing visual style; visitors did not see an obvious off-brand or visually-anomalous prompt. This is the structural property of a front-end-side compromise that distinguishes T4.002 from a search-engine-result phishing dApp or a Discord-link phishing dApp: the trust the holder is extending is to the legitimate platform's domain and visual identity, and the holder's residual signal-of-suspicion (URL bar, brand-recognition heuristics) is exactly aligned with the legitimate platform. The defender lesson is that front-end-side compromise defeats the holder's URL-and-brand-recognition heuristic by construction; this is what makes the T4.002 surface particularly dangerous and what makes platform-side controls (SRI, CSP, build-pipeline integrity) the load-bearing Mitigation layer.
- The on-chain extraction was the standard T4.005 drainer flow. Once the holder signed the
setApprovalForAll, the attacker-controlled operator address held standing authority to transfer all tokens of that contract owned by the holder. The drainer infrastructure then executedtransferFromloops at a pace that, for most affected holders, completed before they noticed and revoked. The on-chain extraction graph identifies the operator-address cluster cleanly; the post-incident analysis at CertiK enumerated the affected wallets and extracted the cohort. - The injection vector was not fully disclosed in the public record. Industry discussion focused on three candidate vectors — third-party JavaScript supply-chain compromise (a malicious update to a JS dependency Premint loaded), build-pipeline compromise (an attacker who gained CI / deploy access pushing a malicious build), and hosting-side compromise (an attacker modifying the served bundle at the hosting layer) — without a definitive public resolution at the per-incident level. The defender lesson does not depend on which vector applied: each of the three is independently load-bearing as a front-end-side surface that platforms in this position must defend, and a v0.x OAK update on T4.002's Mitigation layer should treat all three as part of the standard front-end-side-compromise threat model.
- Detection latency at the platform side was hours; revocation latency was bounded by individual holder action. Premint detected, removed, and announced within hours of the start of the window. By that point, holders who had signed the malicious approval already had standing authority granted to the drainer operator. Each affected holder's revocation window was bounded by individual action (per-contract
setApprovalForAll(operator, false)revocations), and many holders did not revoke before the drainer completed extraction. The asymmetry is structural and identical in shape to the Yuga / BAYC cluster (/examples/2022-04-bored-ape-discord-wave.md); the platform-side detection-and-statement window does not unwind the per-holder authorisation grant. - The cohort context was a busy NFT-drainer year. July 2022 sat in the middle of an active drainer-service year that included Monkey Drainer's run (2022–early-2023) and the cohort-level NFT-phishing volume documented at scale by Chainalysis. The Premint case was one of the higher-loss individual incidents of that year and the only one in which the entry vector was front-end-side compromise of an NFT-utility platform; most contemporaneous T4.005 incidents originated from Discord-side or social-media-side phishing flows.
What this example tells contributors writing future Technique pages
- T4.002 generalises beyond fungible-token permit solicitation to NFT operator-grant solicitation. The current T4.002 page at
/techniques/T4.002-compromised-frontend-permit-solicitation.mdframes the Technique around fungible-token permit signatures (EIP-2612-class). The Premint case demonstrates that the same predicate — front-end compromise solicits an authority-grant from the visitor — applies cleanly to NFT operator grants (setApprovalForAll). Contributors writing future T4.002 pages should generalise the framing or, in a v0.x update, propose a sibling sub-Technique under T4 covering NFT-side front-end-compromise approval-solicitation. The Mitigation surface (SRI, CSP, build-pipeline integrity, third-party-script audit) is identical across the fungible and NFT sub-cases. - NFT-utility platforms are a third-party trust layer that warrants explicit treatment in T4.002 and T11. The Premint case is the canonical worked example for a non-marketplace, non-wallet, non-mint-contract third-party platform whose compromise propagates to holder-loss across the platform's user base in a single event. The OAK Tactic surface for this — the analogue of T11.001's third-party-signing-vendor compromise framing, applied to NFT-utility-platform operators — is currently absorbed into T11's parent scope. A v0.x sub-Technique under T11 covering NFT-utility-platform operator compromise (analogous to T11.001 covering Fireblocks-class third-party-signing-vendor compromise) is a concrete expansion candidate; Premint anchors that case.
- Counterfeit-mint narrative bait can be distributed through a non-counterfeit platform. The standard T12.002 framing is that a counterfeit collection or counterfeit-mint page is hosted at an attacker-controlled domain. The Premint case demonstrates that the narrative of the counterfeit mint can be injected into a legitimate platform's front-end while the technical extraction is an approval drainer — the holder is not interacting with a counterfeit dApp, they are interacting with an authentic Premint URL whose contents have been weaponised. Contributors writing future T12.002 examples should preserve the distinction between counterfeit-collection-at-attacker-domain (the standard T12.002 case) and counterfeit-mint-narrative-at-legitimate-domain-via-front-end-compromise (the Premint sub-pattern). The two share the narrative-bait layer but have entirely different Mitigation surfaces — canonical-contract allowlists protect against the former but do nothing for the latter.
- Front-end security for NFT-utility platforms is a discrete defender practice and is currently under-treated in the OAK Mitigations layer. The Premint case shows that subresource integrity for third-party JS, Content Security Policy hardening, build-pipeline integrity controls, and third-party-script audit cadence are first-class Mitigations for NFT-utility-platform operators. Contributors writing the v0.x Mitigation entries for T4.002 should consider explicit subresource-integrity-and-CSP guidance with Premint as the canonical worked example, alongside the Curve DNS-hijack case (
/examples/2022-08-curve-dns-hijack.md) which is the canonical worked example for the DNS-side sub-pattern of T4.002.
Public references
[certikpremint2022]— CertiK contemporaneous incident analysis with on-chain trace, victim list, and ~314 NFTs / ~$375K initial figure.[premintpostmortem2022]— Premint platform's own statement on the compromise, mitigation steps, and post-incident security commitments.[chainalysisnftcounterfeit2022]— Chainalysis cohort framing situating Premint in the broader 2022 NFT-rug-and-phishing cohort.[chainalysis2022nft]— Chainalysis 2022 NFT industry retrospective; cohort-scale framing.
Citations
[certikpremint2022]— primary forensic write-up; ~314 NFTs / ~$375K initial figure.[premintpostmortem2022]— Premint platform statement; vector discussion and Mitigation commitments.[chainalysisnftcounterfeit2022]— cohort framing.[chainalysis2022nft]— primary NFT retrospective.
Discussion
Premint is OAK's canonical worked example for front-end-side compromise of an NFT-utility platform at v0.1. The case lives at a three-way intersection of T4.002 (entry vector), T4.005 (on-chain extraction), and T12.002 (narrative bait), and is the cleanest available case for the v0.x argument that T4.002's framing should be generalised from fungible-token permits to NFT operator grants, and that a T11.NN sub-Technique covering NFT-utility-platform operator compromise is a discrete expansion candidate.
The case carries additional analytical weight as the worked example for two structural observations about NFT-cohort attacks: (a) the load-bearing trust layer is often a non-marketplace, non-wallet, non-mint-contract third-party platform whose compromise propagates across the platform's user base, and (b) the narrative-bait layer (counterfeit-mint framing) and the technical-extraction layer (approval drainer) are independent and combinable across host surfaces. The Premint case demonstrates the combination of "counterfeit-mint narrative + approval-drainer extraction" hosted on a legitimate platform's compromised front-end; the Yuga / BAYC cluster (/examples/2022-04-bored-ape-discord-wave.md) demonstrates the same combination hosted on attacker-controlled dApps reached via compromised operator channels; the Frosties case (/examples/2022-01-frosties.md) demonstrates a different combination ("rug-pull narrative + treasury-exit extraction") with no third-party-platform involvement. The three together span the load-bearing entry-vector surfaces for NFT-cohort attacks at v0.1, and contributors writing future NFT-cohort worked examples should be explicit about which entry-vector layer the case sits in.
The pairing with the Curve DNS-hijack case (/examples/2022-08-curve-dns-hijack.md) is the most useful within-OAK cross-reference for the front-end-side-compromise sub-pattern. Curve and Premint are both 2022-cohort front-end-side-compromise cases on Ethereum-adjacent DeFi / NFT infrastructure, but they sit at different layers of the front-end-side surface: Curve is the DNS-hijack sub-pattern (T4.002 with the compromise at the DNS / nameserver layer), Premint is the JavaScript-injection sub-pattern (T4.002 with the compromise at the front-end-bundle layer). The Mitigation surface differs accordingly: Curve's lesson is registrar / nameserver hardening, Premint's lesson is subresource integrity and build-pipeline integrity. Together the two cases provide a complete v0.1 worked-example coverage of the T4.002 surface.
For OAK's broader credibility, the Premint case adds NFT-utility-platform-layer worked example to a corpus that otherwise treats NFT attacks as either marketplace-side (Magic Eden y00ts), Discord-side (Yuga / BAYC), or wallet-side (the broad T4.005 cohort), without explicit treatment of the third-party-platform layer in between. Premint is the case that fills that gap and that anchors the v0.x argument for promoting NFT-utility-platform compromise to first-class status in the T11 sub-Technique surface.