Summary
Togoder Security scanned the npm package @metamask/sdk-install-modal-web@0.32.1 on Oct 4, 2026. An AI review of 41 source files produced 8 medium, 16 low severity findings. The overall verdict is medium: the findings flag risky but common patterns (dynamic code, unsafe defaults, broad file or network access) rather than confirmed malware.
Findings 24
Global script execution
NPS-844EC424CA52
The code calls appGlobals.globalScripts() during initialization, which may execute arbitrary scripts loaded from external sources. The implementation is not visible in this file.
Wallet-related terminology
NPS-E10B8BDC2216
The component names (mm-install-modal, mm-pending-modal, mm-select-modal) and attributes (otpCode, sdkVersion, link) suggest this is related to MetaMask or a cryptocurrency wallet SDK. While legitimate crypto wallets exist, malicious packages often target wallet interactions.
External network request / dynamic resource loading
NPS-5038CAC5357D
The SimpleI18n class fetches translation JSON files at runtime from a hardcoded third-party GitHub raw content URL (https://raw.githubusercontent.com/MetaMask/metamask-sdk/refs/heads/gh-pages/locales/<locale>.json). While this is a legitimate MetaMask SDK behavior for localization, it constitutes an outbound network request to an external server initiated automatically on component initialization and renders the UI dependent on external content. If that repository or GitHub account were compromised, the fetched data is directly merged into the translations object and rendered into the DOM via the t() function. This is a supply-chain risk and remote dynamic resource loading, not previously vetted code.
Missing strict CSP / transport verification on remote fetch
NPS-D1B01CE05C1A
The fetch call to the external GitHub URL does not verify a content hash, signature, or origin beyond a static URL string. There is no integrity checking (e.g., SRI) when loading remote translation data, meaning any modification of the upstream gh-pages repository would inject arbitrary strings into the rendered wallet modal (UI spoofing / phishing content injection).
External network request with raw.githubusercontent.com
NPS-559507610F0D
The code fetches translation JSON files from 'https://raw.githubusercontent.com/MetaMask/metamask-sdk/refs/heads/gh-pages/locales' based on the user's browser locale. While the default URL points to the official MetaMask SDK repository, the baseUrl is fully configurable via the constructor config object. If an attacker or malicious caller passes a custom baseUrl, this class will fetch and execute arbitrary JSON content from an attacker-controlled endpoint, which is then used as translations via the t() method. There is no integrity verification (SRI), no URL allowlist, and no validation that the fetched JSON is a plain translation object. Because translations are rendered into the DOM by the consuming app, this creates a potential injection/data-exfiltration vector if an attacker controls the baseUrl or compromises the remote JSON source.
Unvalidated/fetch of remote JSON content
NPS-8DC53F615831
The response from fetch() is passed directly to response.json() and assigned to this.translations with no schema validation, size limits, or sanitization. A malicious or compromised locale file could return arbitrary nested objects/strings. Downstream, t() returns these values verbatim and consumers may render them as HTML (innerHTML), enabling stored/client-side XSS. Additionally, numeric/array values would silently fall through getNestedTranslation, but strings are passed through unescaped.
Use of innerHTML with externally-derived content
NPS-31FFB3CBFA25
The QR code SVG generated from this.link is injected via innerHTML into the shadow DOM. While encodeQR from @paulmillr/qr is expected to produce safe SVG, using innerHTML with content derived from an external property introduces risk if the encoder output is ever influenced or if the library is replaced/compromised, potentially enabling XSS/HTML injection.
Dynamic network request to external CDN
NPS-B49FB2CFC6EE
The SimpleI18n class fetches translation JSON files from a hardcoded GitHub CDN URL (https://raw.githubusercontent.com/MetaMask/metamask-sdk/refs/heads/gh-pages/locales) at runtime. While this is a legitimate localization mechanism for MetaMask SDK, dynamically fetching and injecting external content introduces a supply-chain risk: if the remote repository or CDN is compromised, malicious translations could be injected into the UI. The response is also assigned directly into the translations object used for rendering, without schema validation.
dynamic_import
NPS-7B7E7C0B4B8C
The code uses dynamic import/require with computed bundle IDs (e.g., require(./${bundleId}.entry.js)). However, the bundle IDs are sourced from static component metadata within the package itself, not from external input, limiting risk.
Dynamic component loading
NPS-9D97CC10D7F7
The code loads external component scripts via bootstrapLazy with a reference to 'mm-install-modal_3.cjs'. While this is a standard pattern for Stencil-based web components, the loaded component could contain malicious logic since its content is not verified in this file.
Dynamic HTML injection via innerHTML
NPS-BEE9D7728A34
The component uses index.h('div', { id: 'sdk-mm-qrcode', class: 'center', innerHTML: svgElement }) where svgElement is produced by encodeQR() from the link property. If link is attacker-influenced and the QR library produced attacker-controlled SVG markup, innerHTML would execute it. In practice encodeQR generates fixed SVG structure, so immediate exploitability is low, but using innerHTML with a computed string is a code smell that could become an XSS vector if the input API ever changes.
Server-side style data leak via locale selection
NPS-9CC20AB12FDF
The code sends the user's browser locale preference to an external GitHub raw content host (or any configured baseUrl) on each init for non-English locales. This leaks browser environment details (navigator.language/languages) to a third-party endpoint. This is a minor privacy concern, not exfiltration of credentials.
Dependency trust concern
NPS-68417630D620
The component imports a third-party QR encoding library (@paulmillr/qr) to generate SVG from a potentially external link. Third-party dependencies performing encoding operations on untrusted input should be validated, though no malicious behavior is evident in this file itself.
dynamic-import
NPS-B281F60B08C0
The loadModule function uses dynamic import() with a computed bundleId from component metadata. However, this is standard Stencil lazy-loading behavior: bundle IDs are hardcoded in the generated metadata and the final fallback imports a template literal ./${bundleId}.entry.js. No external user input reaches the import path, and no obfuscation or anomalous string construction is present.
dom-html-injection
NPS-22CD418F6883
styleElm.innerHTML = style and styleElm.innerHTML += SLOT_FB_CSS are used to inject CSS text into style elements. The style content originates from the component bundle's own compiled styles, not from external/attacker-controlled input. The runtime also handles CSP nonces via queryNonceMetaTagContent and setNonce, which is standard Stencil CSP support.
Obfuscated/short minified identifiers
NPS-3D34AA1583A9
Imports use obfuscated aliases (b, s, g) and file names with content hashes (index-4b8a94c9.js, app-globals-0f993ce5.js). These are typical of minified bundler output but reduce code auditability and could hide malicious behavior in the referenced files.
Top-level code execution on import
NPS-BCDAF3E45B5D
The module defines defineCustomElements which is auto-executed or invoked at import time by Stencil runtime. It calls globalScripts() (from app-globals-0f993ce5.js) and bootstrapLazy() which dynamically loads and registers custom elements. This means code runs automatically when the module is imported, without explicit user invocation.
Dynamic module loading with computed input
NPS-75997355AA8F
bootstrapLazy from index-4b8a94c9.js is a Stencil-generated lazy loader that dynamically imports component bundles based on the custom element tag names defined in the metadata array. While the tags here are hardcoded, the loader mechanism may fetch and execute additional JS chunks at runtime, expanding the trust boundary beyond this file.
Use of innerHTML for SVG injection
NPS-7934EC924B2F
The rendered QR code SVG (generated by the bundled @paulmillr/qr library) is injected via innerHTML in multiple modals (InstallModal, SelectModal). If the link prop passed to the component is ever attacker-controlled and contains malicious payloads that the QR encoder reflects, this could lead to DOM-based XSS. In the current code the QR library only encodes into an SVG attribute context, but the pattern of using innerHTML with runtime-generated content is a code-smell that warrants attention.
Bundled third-party QR library code review note
NPS-AC07C7C840ED
The file embeds a substantial copy of the @paulmillr/qr library. Static analysis of the embedded code did not reveal eval, Function constructor, child_process, filesystem access, credential harvesting, crypto-mining, wallet-draining, or obfuscated payloads. The code performs pure in-memory QR encoding. No backdoor or exfiltration behavior was observed.
Custom element polyfill
NPS-7DC8B4AF4E4D
The code is a standard Custom Elements polyfill for older browsers (widely known as the 'webcomponents-loader' / document-register-element style shim). It patches window.HTMLElement to support Reflect.construct for custom element subclassing. This is a well-known, legitimate polyfill pattern and contains no data exfiltration, credential harvesting, dynamic code execution, process spawning, or filesystem manipulation.
Re-export
NPS-5691556120EA
The final statement export * from '../esm/loader.js' is a static ES module re-export to the ESM build of the same package. Static string specifier, no dynamic import with computed input.
dynamic import
NPS-89185D423E12
The code uses a dynamic import with a computed path: import(./${r}.entry.js${''}). This is part of the Stencil runtime's lazy loading mechanism. The variable 'r' is derived from component metadata and is not attacker-controlled. No external input is used.
External translation fetch
NPS-AD3E30087B50
The code fetches translation JSON files from a hardcoded GitHub raw URL (https://raw.githubusercontent.com/MetaMask/metamask-sdk/refs/heads/gh-pages/locales) based on the browser language. This is a legitimate feature for loading localized UI strings, not data exfiltration, but it is a network request to an external host at runtime.
Files reviewed
| File | Verdict | What the reviewer saw |
|---|---|---|
| dist/cjs/loader.cjs.js | medium | This appears to be a legitimate Stencil-based component loader for what looks like a MetaMask wallet interface, but it dynamically loads external code and executes global scripts, which could pose security risks if those dependencies are compromised. |
| dist/cjs/mm-install-modal_3.cjs.entry.js | medium | The code is a fairly standard MetaMask SDK modal bundle with no credential harvesting, mining, shell execution, or backdoor patterns, but it performs unverified runtime fetches of translation data from an external GitHub URL and uses innerHTML for QR SVG insertion, which are minor security concerns rather than clear malicious behavior. |
| dist/collection/components/misc/simple-i18n.js | medium | No credential theft, obfuscation, shell/exec, or wallet-draining patterns detected, but the class performs unvalidated remote fetch of translation JSON from a configurable URL which could enable injection or data leaks if the baseUrl is attacker-controlled. |
| dist/collection/components/mm-select-modal/mm-select-modal.js | medium | No clear malicious patterns; main concern is innerHTML injection of QR SVG data and third-party QR library trust in a MetaMask-style wallet selector component. |
| dist/esm/loader.js | medium | No direct malicious patterns are present, but the file uses a lazy module loader that executes external bundles at import time, which is a moderate supply-chain concern requiring review of the referenced dependency files. |
| dist/esm/mm-install-modal_3.entry.js | medium | The analyzed MetaMask install/pending/select modal bundle contains no credential harvesting, code execution, shell spawning, or exfiltration behavior, but it does dynamically fetch translation JSON from an external GitHub URL at runtime, which represents a modest supply-chain risk. |
| dist/cjs/app-globals-3a1e7e63.js | safe | No malicious patterns detected |
| dist/cjs/index-e2e1ee7a.js | safe | This is a standard Stencil runtime bundle with no malicious patterns detected; dynamic imports are internal and expected. |
| dist/cjs/index.cjs.js | safe | The file contains only a 'use strict' directive and a source map reference, with no executable logic or malicious patterns. |
| dist/cjs/sdk-install-modal-web.cjs.js | safe | No malicious patterns detected; the code is a standard Stencil client bootstrap for a web component library. |
| dist/collection/components/misc/AdvantagesListItem.js | safe | No malicious patterns detected |
| dist/collection/components/misc/CloseButton.js | safe | The file is a simple Stencil SVG close button component with no network, filesystem, process, or dynamic execution behavior. |
| dist/collection/components/misc/ConnectIcon.js | safe | No malicious patterns detected; the file contains a static SVG icon rendered via Stencil's h() function with no external data access, dynamic execution, or network/file operations. |
| dist/collection/components/misc/HeartIcon.js | safe | No malicious patterns detected |
| dist/collection/components/misc/Icon.js | safe | No malicious patterns detected |
| dist/collection/components/misc/InstallIcon.js | safe | No malicious patterns detected; the file only renders a static SVG icon with no network, filesystem, or process activity. |
| dist/collection/components/misc/LockIcon.js | safe | The file is a simple, stateless Stencil SVG icon component with no network, filesystem, process, or dynamic execution behavior. |
| dist/collection/components/misc/Logo.js | safe | No malicious patterns detected |
| dist/collection/components/misc/MetamaskExtensionImage.js | safe | No malicious patterns detected; the file only defines a static SVG rendering component using Stencil's h() function with no external calls, dynamic code execution, or file/network access. |
| dist/collection/components/misc/SDKVersion.js | safe | No malicious patterns detected |
| dist/collection/components/misc/WalletIcon.js | safe | No malicious patterns detected |
| dist/collection/components/misc/tracking-events.js | safe | No malicious patterns detected |
| dist/collection/components/mm-install-modal/mm-install-modal.js | safe | No malicious patterns detected; the code is a benign Stencil UI component for displaying an installation modal with QR code generation and analytics emission. |
| dist/collection/components/mm-pending-modal/mm-pending-modal.js | safe | No malicious patterns detected in the analyzed Stencil component file |
| dist/collection/components/widget-wrapper/widget-wrapper.js | safe | No malicious patterns detected |
Show 16 more files
| File | Verdict | What the reviewer saw |
|---|---|---|
| dist/collection/index.js | safe | No malicious patterns detected |
| dist/esm/app-globals-0f993ce5.js | safe | The file contains only an empty arrow function declaration and export with no malicious patterns detected. |
| dist/esm/index-4b8a94c9.js | safe | This is the standard Stencil v4.22.2 web-components runtime (sdk-install-modal-web namespace) with only benign dynamic-import and CSS-injection patterns typical of the framework; no exfiltration, credential harvesting, obfuscation, process spawning, or install-time hooks were detected. |
| dist/esm/index.js | safe | The file contains only a source map directive and no executable or malicious code. |
| dist/esm/sdk-install-modal-web.js | safe | No malicious patterns detected; this is standard Stencil-generated browser bootstrap code for a web component library. |
| dist/index.cjs.js | safe | No malicious patterns detected |
| dist/index.js | safe | No malicious patterns detected |
| dist/loader/cdn.js | safe | No malicious patterns detected |
| dist/loader/index.cjs.js | safe | No malicious patterns detected |
| dist/loader/index.es2017.js | safe | This is a simple re-export statement that re-exports all named exports from '../esm/loader.js', containing no suspicious or malicious patterns. |
| dist/loader/index.js | safe | The file is a benign Custom Elements polyfill with a static ES module re-export; no malicious patterns were identified. |
| dist/sdk-install-modal-web/index.esm.js | safe | The file contains only a source map reference comment and no executable code, so no malicious patterns were detected. |
| dist/sdk-install-modal-web/p-4739b8e2.js | safe | The file is a standard Stencil runtime bundle for web components; no malicious patterns such as data exfiltration, credential harvesting, or backdoor installation were detected. |
| dist/sdk-install-modal-web/p-da7cdd88.entry.js | safe | This appears to be legitimate MetaMask SDK UI modal code (install/connect/pending modals with QR rendering); no malicious patterns such as exfiltration, credential harvesting, obfuscation, or shell execution were found. |
| dist/sdk-install-modal-web/p-e1255160.js | safe | No malicious patterns detected |
| dist/sdk-install-modal-web/sdk-install-modal-web.esm.js | safe | No malicious patterns detected; the code is a standard Stencil.js web component bootstrap with no exfiltration, obfuscation, or risky runtime behavior. |
Scanned versions of @metamask/sdk-install-modal-web
| Version | Verdict | Files | Scanned |
|---|---|---|---|
| 0.32.1 | Needs review | 41 | Oct 4, 2026 |
Frequently asked questions
Is @metamask/sdk-install-modal-web safe to use?
No confirmed malware was found in @metamask/sdk-install-modal-web@0.32.1, but the review flagged 8 medium, 16 low severity findings for risky patterns worth checking before you rely on it.
Does @metamask/sdk-install-modal-web contain malware?
No malware was identified in @metamask/sdk-install-modal-web@0.32.1 when Togoder Security scanned it on Oct 4, 2026. A new version can still introduce malicious code, so scan the exact versions in your lockfile.
How was @metamask/sdk-install-modal-web checked?
Togoder Security downloaded the published npm package and had an AI model read its 41 source files, looking for install scripts, credential access, network exfiltration, obfuscation, backdoors and crypto-wallet theft. The results are cached by file hash and shown here.
How do I scan @metamask/sdk-install-modal-web together with the rest of my dependencies?
Upload your lockfile at https://security.togoder.click/scan or call the API documented at https://security.togoder.click/api-docs. Files that have already been scanned, like the ones in @metamask/sdk-install-modal-web@0.32.1, cost nothing.