{"id":"MAL-2026-19145","kind":"package","aliases":["MAL-2026-19145"],"related":[],"title":"Malicious code in tailwindcss-hook-forms (npm)","description":"---\n_-= Per source details. Do not edit below this line.=-_\n\n## Source: amazon-inspector (d504fed314f875b17a90d039af71b0798636e5030373e5d959871dc356bc7bef)\nThe package impersonates @tailwindcss/forms: name, repository (tailwindlabs/tailwindcss-forms), author (@tailwindcss), README, CHANGELOG, and HTML are copied from the legitimate plugin, with a demo link to tailwindcss-hook-forms.vercel.app. src/index.js prepends a hand-rolled string-permutation decoder (spin() with magic constants NX/SX, splitLane/peel wrappers) that resolves the Function constructor via peel.constructor and immediately invokes a function compiled from a ~15KB opaque, obfuscated string literal, passing the host require into it. This fires whenever any consumer imports the package, running attacker-controlled code in the installer's Node.js process with full access to require, process, filesystem, and network. The subsequent code replicates the public API of @tailwindcss/forms as cover. The obfuscator scheme does not exist in the legitimate plugin and its only purpose is to conceal the executable body from review.","summary":null,"severity":"critical","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"tailwindcss-hook-forms","fixed":[],"affected":"= 0.5.2","ecosystem":"npm"}],"ecosystems":["npm"],"tags":["malicious","package"],"not_affected_if":[],"how_to_check":null,"fix":null,"status":"open","published_at":"2026-11-11T20:55:10+00:00","first_seen_at":"2026-11-11T21:29:24+00:00","triaged_at":"2026-11-11T21:30:27+00:00","updated_at":"2026-11-11T21:31:13+00:00","category":"package","confidence":null,"triage":null,"analyst_status":null,"analyst_note":null,"search":"'-19145':11A,14A '-2026':10A,13A '15kb':92C 'access':124C 'amazon':32C 'amazon-inspector':31C 'api':137C 'attack':113C 'attacker-control':112C 'author':42C 'bodi':161C 'changelog':45C 'code':2A,115C,133C 'compil':89C 'conceal':158C 'constant':73C 'constructor':81C 'consum':107C 'control':114C 'copi':49C 'cover':141C 'd504fed314f875b17a90d039af71b0798636e5030373e5d959871dc356bc7bef':34C 'decod':69C 'demo':56C 'detail':23C 'edit':26C 'execut':160C 'exist':147C 'filesystem':128C 'fire':104C 'form':7A 'forms':18A 'full':123C 'function':80C,88C 'hand':64C 'hand-rol':63C 'hook':6A,17A 'host':99C 'html':47C 'immedi':85C 'imperson':37C 'import':108C 'inspector':33C 'instal':118C 'invok':86C 'legitim':52C,150C 'line':29C 'link':57C 'liter':96C 'magic':72C 'mal':9A,12A 'malici':1A,19B 'name':39C 'network':130C 'node.js':120C 'npm':8A 'nx/sx':74C 'obfusc':94C,143C 'opaqu':93C 'packag':20B,36C,110C 'pass':97C 'peel.constructor':83C 'per':21C 'permut':68C 'plugin':53C,151C 'prepend':61C 'process':121C,127C 'public':136C 'purpos':155C 'readm':44C 'replic':134C 'repositori':40C 'requir':100C,126C 'resolv':78C 'review':163C 'roll':65C 'run':111C 'scheme':144C 'sourc':22C,30C 'spin':70C 'splitlane/peel':75C 'src/index.js':60C 'string':67C,95C 'string-permut':66C 'subsequ':132C 'tailwindcss':5A,16A,43C 'tailwindcss-hook-form':4A 'tailwindcss-hook-forms':15A 'tailwindcss-hook-forms.vercel.app':59C 'tailwindcss/forms':38C,139C 'tailwindlabs/tailwindcss-forms':41C 'via':82C 'whenev':105C 'wrapper':76C","nicknames":[],"mitigations":[],"who_affected":null,"tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":null,"audience":null,"plain_action":null,"pkeys":["tailwindcsshookforms"],"ptokens":["forms","hook","tailwindcss"],"labels":["critical","malicious","npm","package"],"campaign_type":null,"search_a":"'-19145':11A,14A '-2026':10A,13A 'code':2A 'form':7A 'forms':18A 'hook':6A,17A 'mal':9A,12A 'malici':1A 'npm':8A 'tailwindcss':5A,16A 'tailwindcss-hook-form':4A 'tailwindcss-hook-forms':15A","search_b":"'malici':19B 'packag':20B","search_c":"'15kb':92C 'access':124C 'amazon':32C 'amazon-inspector':31C 'api':137C 'attack':113C 'attacker-control':112C 'author':42C 'bodi':161C 'changelog':45C 'code':115C,133C 'compil':89C 'conceal':158C 'constant':73C 'constructor':81C 'consum':107C 'control':114C 'copi':49C 'cover':141C 'd504fed314f875b17a90d039af71b0798636e5030373e5d959871dc356bc7bef':34C 'decod':69C 'demo':56C 'detail':23C 'edit':26C 'execut':160C 'exist':147C 'filesystem':128C 'fire':104C 'full':123C 'function':80C,88C 'hand':64C 'hand-rol':63C 'host':99C 'html':47C 'immedi':85C 'imperson':37C 'import':108C 'inspector':33C 'instal':118C 'invok':86C 'legitim':52C,150C 'line':29C 'link':57C 'liter':96C 'magic':72C 'name':39C 'network':130C 'node.js':120C 'nx/sx':74C 'obfusc':94C,143C 'opaqu':93C 'packag':36C,110C 'pass':97C 'peel.constructor':83C 'per':21C 'permut':68C 'plugin':53C,151C 'prepend':61C 'process':121C,127C 'public':136C 'purpos':155C 'readm':44C 'replic':134C 'repositori':40C 'requir':100C,126C 'resolv':78C 'review':163C 'roll':65C 'run':111C 'scheme':144C 'sourc':22C,30C 'spin':70C 'splitlane/peel':75C 'src/index.js':60C 'string':67C,95C 'string-permut':66C 'subsequ':132C 'tailwindcss':43C 'tailwindcss-hook-forms.vercel.app':59C 'tailwindcss/forms':38C,139C 'tailwindlabs/tailwindcss-forms':41C 'via':82C 'whenev':105C 'wrapper':76C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-11T20:55:10+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"osv-malicious","external_id":"MAL-2026-19145","url":"https://osv.dev/vulnerability/MAL-2026-19145","severity":"critical","published_at":"2026-11-11T20:55:10+00:00","modified_at":"2026-11-11T21:15:16+00:00","first_seen_at":"2026-11-11T21:29:24+00:00","fetched_at":"2026-11-11T21:29:24+00:00","note":null}],"documents":[],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}