Summary
Togoder Security scanned the npm package @safe-global/safe-apps-sdk@9.1.0 on Oct 4, 2026. An AI review of 63 source files produced 8 medium, 8 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 16
Insecure postMessage target origin
NPS-B2DA09EB4A9A
The send() method calls window.parent.postMessage(request, '*'), broadcasting messages to any origin. If the allowedOrigins restricts incoming messages, outgoing messages still go to '*', which could leak request data to a malicious parent frame. This is a security weakness, though typical for this SDK pattern.
insufficient origin validation default
NPS-D56DB7D4F2F0
allowedOrigins defaults to null. In isValidMessage, when allowedOrigins is not an array, validOrigin remains true, so messages from arbitrary origins are accepted as long as they originate from window.parent. This weakens sender validation and may allow spoofed responses/commands.
wildcard postMessage target origin
NPS-5D75A9861D2F
The send() method uses window.parent.postMessage(request, '*'), broadcasting messages to any origin. Combined with an ambient listener for incoming messages, this can leak request payloads to unintended or compromised parent frames and enables cross-origin message injection if the parent is untrusted.
Permission Escalation
NPS-FAD7B2DD4580
The decorator automatically requests permissions when a method requiring permissions is called and the permission is not already granted. This could lead to unintended permission elevation if the requestPermissions method does not properly validate or prompt the user.
Origin validation bypass when allowedOrigins is null
NPS-9F579593B14B
If allowedOrigins is null (the default), isValidMessage skips origin validation entirely (validOrigin remains true), meaning messages from any origin are accepted provided they come from window.parent and have a version >= 1. This weakens the trust boundary.
Wildcard postMessage target origin
NPS-FFF268D80E0F
The send method posts messages to window.parent using '*' as the targetOrigin, allowing any origin to receive the message payload. If sensitive data is ever included in requests, it could be leaked to a malicious parent frame.
Cryptographic signing functionality
NPS-3520B689F7C1
This class provides methods to sign arbitrary messages and EIP-712 typed data, as well as send transactions, via a communicator (likely a browser extension or iframe). While not inherently malicious, these are the exact primitives a wallet drainer or phishing app would need. The safety depends entirely on the implementation of Communicator (not shown here) and on caller/consumer behavior. No validation is performed on the destination chain, gas, or recipients in send(), so a malicious caller could craft transactions to drain funds if this library is bundled into a hostile dApp.
Dynamic message signing surface
NPS-CA666F80BED7
signMessage accepts an arbitrary string with no whitelist, domain binding, or user-visible confirmation logic in this file. A malicious integration could use it to obtain signatures over attacker-controlled payloads (e.g., SIWE/off-chain authorizations) leading to account takeover if the user blindly approves.
Overly permissive incoming message validation when allowedOrigins is null
NPS-01F091159F7A
When allowedOrigins is null (the default), validOrigin remains true for all origins, so any parent frame can send messages that will be processed. Combined with source === window.parent check, this limits exposure, but if embedded in an attacker-controlled iframe parent it allows message injection.
Debug logging of incoming messages
NPS-D501F11FAEF4
In debug mode, message origin and data are logged via console.info. This could expose sensitive payload data in logs if enabled in production, but it is opt-in and not malicious.
prototype pollution via version field access
NPS-545AE8913F2A
isValidMessage directly accesses data.version and data.version.split('.') after checking typeof data.version !== 'undefined'. If data is crafted (e.g., version as a function or object with malicious toString), this could throw or be abused. More importantly, no strict schema validation is performed on message data before dispatch.
global listener without teardown or allowlist enforcement
NPS-38F06FBCEBEA
The constructor unconditionally adds a window 'message' listener in browser contexts. There is no removal API or limit on the number of listeners. Any page embedding this SDK repeatedly can accumulate listeners and receive attacker-controlled messages that pass the weak validation path.
Insecure Error Handling
NPS-0161CB7E924E
The error thrown when permissions are rejected may not provide sufficient information for debugging or auditing, and the constant PERMISSIONS_REQUEST_REJECTED is used without context.
Regex-based origin validation
NPS-36FC36BD594E
Origin validation uses user-supplied RegExp objects via .test() without anchoring, which can lead to unintended matches (e.g. 'https://evil.com.attacker.net' matching a regex like /https:\/\/evil.com/).
Debug logging of incoming message payloads
NPS-34630A2646AA
When debugMode is enabled, the full incoming message data and origin are logged via console.info, which could expose sensitive payload contents in logs.
Missing input validation on transaction targets
NPS-80D7E01C39F1
The send method accepts txs and params opaquely and forwards them without sanitizing recipient addresses, values, or calldata. If this is used as a wallet SDK, the absence of checks means it will happily sign/submit whatever the caller provides. No address-rewriting detection is present, but also no defensive validation.
Files reviewed
| File | Verdict | What the reviewer saw |
|---|---|---|
| dist/cjs/communication/index.js | medium | The file implements a postMessage-based Safe Apps SDK communicator with no exfiltration, credential harvesting, obfuscation, process spawning, or install-time execution, but uses postMessage('*') for outgoing messages and permissive default origin validation, which are minor security weaknesses rather than malicious patterns. |
| dist/esm/communication/index.js | medium | The code is not overtly malicious, but it has insecure postMessage practices including wildcard target origins and weak/default-open origin validation that could enable message spoofing or data leakage in cross-origin contexts. |
| dist/esm/decorators/requirePermissions.js | medium | The code contains a permission request mechanism that may automatically escalate privileges without explicit user consent, posing a medium risk. |
| src/communication/index.ts | medium | The code is a postMessage communication library with no malicious behavior, but it has security weaknesses: wildcard targetOrigin in postMessage, optional/no origin validation by default, unanchored regex origin checks, and debug logging of payloads. |
| src/txs/index.ts | medium | No outright malicious patterns (no exfiltration, no credential harvesting, no eval/exec, no install-time hooks) are present in this file, but it exposes powerful signing and transaction-sending primitives whose safety fully depends on the unseen Communicator implementation and consuming application. |
| dist/cjs/communication/messageFormatter.js | safe | No malicious patterns detected |
| dist/cjs/communication/methods.js | safe | No malicious patterns detected |
| dist/cjs/communication/utils.js | safe | No malicious patterns detected |
| dist/cjs/decorators/requirePermissions.js | safe | No malicious patterns detected; the code is a standard decorator that checks and requests wallet permissions. |
| dist/cjs/eth/constants.js | safe | No malicious patterns detected |
| dist/cjs/eth/index.js | safe | No malicious patterns detected; the code is a straightforward Ethereum JSON-RPC client wrapper with no data exfiltration, credential harvesting, obfuscation, or dynamic code execution. |
| dist/cjs/index.js | safe | No malicious patterns detected; the code is standard TypeScript CommonJS export boilerplate with only relative module imports. |
| dist/cjs/safe/index.js | safe | No malicious patterns detected in the Safe SDK client wrapper; it only performs expected RPC calls and signature validation for Safe smart accounts. |
| dist/cjs/safe/signatures.js | safe | No malicious patterns detected in the provided JavaScript file. |
| dist/cjs/sdk.js | safe | No malicious patterns detected |
| dist/cjs/setupTests.js | safe | No malicious patterns detected; the file only polyfills TextEncoder using Node's util module at import time. |
| dist/cjs/txs/index.js | safe | No malicious patterns detected |
| dist/cjs/types/gateway.js | safe | No malicious patterns detected |
| dist/cjs/types/index.js | safe | No malicious patterns detected; this is standard TypeScript-generated CommonJS re-export boilerplate with no runtime side effects beyond module re-exports. |
| dist/cjs/types/messaging.js | safe | No malicious patterns detected |
| dist/cjs/types/permissions.js | safe | No malicious patterns detected |
| dist/cjs/types/rpc.js | safe | No malicious patterns detected |
| dist/cjs/types/sdk.js | safe | No malicious patterns detected; file contains only a simple type guard function for EIP-712 typed data. |
| dist/cjs/version.js | safe | No malicious patterns detected |
| dist/cjs/wallet/index.js | safe | No malicious patterns detected; the code is a standard wallet permission management module with no data exfiltration, credential harvesting, obfuscation, or suspicious behavior. |
Show 38 more files
| File | Verdict | What the reviewer saw |
|---|---|---|
| dist/esm/communication/messageFormatter.js | safe | Cleared by Jev triage; no further analysis needed |
| dist/esm/communication/methods.js | safe | No malicious patterns detected; the file only defines string enums for communication method names. |
| dist/esm/communication/utils.js | safe | Cleared by Jev triage; no further analysis needed |
| dist/esm/eth/constants.js | safe | No malicious patterns detected |
| dist/esm/eth/index.js | safe | No malicious patterns detected |
| dist/esm/index.js | safe | No malicious patterns detected in the re-export index file |
| dist/esm/safe/index.js | safe | No malicious patterns detected; the code is a legitimate Safe wallet SDK implementation using standard blockchain communication patterns. |
| dist/esm/safe/signatures.js | safe | No malicious patterns detected |
| dist/esm/sdk.js | safe | No malicious patterns detected in the provided SafeAppsSDK file; it is a straightforward SDK class wrapper with no suspicious imports, network calls, or execution of external code. |
| dist/esm/setupTests.js | safe | No malicious patterns detected |
| dist/esm/txs/index.js | safe | The code is a clean client-side wrapper for transaction-related methods that validates inputs and delegates all communication to an injected communicator object, with no malicious patterns detected. |
| dist/esm/types/gateway.js | safe | No malicious patterns detected |
| dist/esm/types/index.js | safe | No malicious patterns detected; the file only re-exports modules via standard ESM export statements. |
| dist/esm/types/messaging.js | safe | No malicious patterns detected; the file only imports a local module and contains a source map reference. |
| dist/esm/types/permissions.js | safe | Cleared by Jev triage; no further analysis needed |
| dist/esm/types/rpc.js | safe | No malicious patterns detected |
| dist/esm/types/sdk.js | safe | Cleared by Jev triage; no further analysis needed |
| dist/esm/version.js | safe | Cleared by Jev triage; no further analysis needed |
| dist/esm/wallet/index.js | safe | No malicious patterns detected in this wallet permission management module. |
| src/communication/messageFormatter.ts | safe | Cleared by Jev triage; no further analysis needed |
| src/communication/methods.ts | safe | This file contains only enum declarations for method names and no executable code, network calls, or suspicious patterns. |
| src/communication/utils.ts | safe | Cleared by Jev triage; no further analysis needed |
| src/decorators/requirePermissions.ts | safe | No malicious patterns detected; this is a standard permission-checking decorator for Ethereum wallet interactions. |
| src/eth/constants.ts | safe | This file only defines a constant mapping of Ethereum JSON-RPC method names and contains no executable code, network activity, or suspicious patterns. |
| src/eth/index.ts | safe | The code is a standard Ethereum JSON-RPC client implementation with no malicious patterns detected. |
| src/index.ts | safe | No malicious patterns detected in this re-export barrel file. |
| src/safe/index.ts | safe | This is a legitimate Safe (formerly Gnosis Safe) SDK module that implements message signing, EIP-712 typed data hashing, and 1271 signature validation via RPC calls with no malicious patterns detected. |
| src/safe/signatures.ts | safe | Cleared by Jev triage; no further analysis needed |
| src/sdk.ts | safe | No malicious patterns detected |
| src/setupTests.ts | safe | The file only polyfills the global TextEncoder using Node's built-in util module, with no malicious patterns detected. |
| src/types/gateway.ts | safe | No malicious patterns detected |
| src/types/index.ts | safe | No malicious patterns detected |
| src/types/messaging.ts | safe | No malicious patterns detected |
| src/types/permissions.ts | safe | No malicious patterns detected; the file only defines TypeScript types and a standard error class for permission handling. |
| src/types/rpc.ts | safe | No malicious patterns detected |
| src/types/sdk.ts | safe | No malicious patterns detected; the file contains only type definitions, interface declarations, and a simple type guard. |
| src/version.ts | safe | Cleared by Jev triage; no further analysis needed |
| src/wallet/index.ts | safe | No malicious patterns detected; the code is a standard wallet permission client that validates inputs and delegates to a communicator abstraction. |
Scanned versions of @safe-global/safe-apps-sdk
| Version | Verdict | Files | Scanned |
|---|---|---|---|
| 9.1.0 | Needs review | 63 | Oct 4, 2026 |
Frequently asked questions
Is @safe-global/safe-apps-sdk safe to use?
No confirmed malware was found in @safe-global/safe-apps-sdk@9.1.0, but the review flagged 8 medium, 8 low severity findings for risky patterns worth checking before you rely on it.
Does @safe-global/safe-apps-sdk contain malware?
No malware was identified in @safe-global/safe-apps-sdk@9.1.0 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 @safe-global/safe-apps-sdk checked?
Togoder Security downloaded the published npm package and had an AI model read its 63 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 @safe-global/safe-apps-sdk 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 @safe-global/safe-apps-sdk@9.1.0, cost nothing.