Summary
Multiple medium-severity security findings across both SDKs related to secret handling, build artifacts, and input validation.
1. Private Key Retained in Memory Without Zeroing (Both SDKs)
Files:
python/numbersprotocol_capture/crypto.py:48-63
ts/src/crypto.ts:41
Both SDKs receive the Ethereum private key as an immutable string. The key persists in memory until garbage collected, appearing in heap dumps, core dumps, or memory inspection tools. Neither SDK attempts to minimize the lifetime of key material.
Suggested fix: Accept private key as Uint8Array/bytearray that can be zeroed after use. Alternatively, support a "bring your own signer" callback pattern: sign?: { signer: (message: string) => Promise<string>; address: string }.
2. API Token Exposed via Python __repr__ / Debugger Inspection
File: python/numbersprotocol_capture/client.py:131-158
The Capture class stores the token as self._token without a custom __repr__(). The token appears in vars(capture), capture.__dict__, and framework traceback reporters (e.g., Sentry, cgitb).
Suggested fix: Implement __repr__() that masks the token: Capture(token='***...abc', base_url='...').
3. Source Maps Included in Production npm Package
Files: ts/tsup.config.ts:8, ts/tsconfig.json:14
Both sourcemap: true settings cause .map files to be published to npm, exposing full original TypeScript source to anyone who installs the package. While the SDK is open source, this increases package size and aids vulnerability discovery.
Suggested fix: Set sourcemap: false or 'hidden' in tsup.config.ts. Exclude *.map from package.json files array.
4. customMetadata Accepts Arbitrary Unsanitized JSON (TypeScript)
Files: ts/src/client.ts:305-306, ts/src/types.ts:58
The update() method accepts customMetadata: Record<string, unknown> and serializes it directly via JSON.stringify. This allows deeply nested objects (JSON bomb DoS), excessively large strings, and potential stored XSS payloads if the server renders metadata in a web context.
Suggested fix: Add max serialized size check (e.g., 10KB). Restrict value types to Record<string, string | number | boolean>.
5. Overly Broad Exception Swallowing (Python)
Files: python/numbersprotocol_capture/client.py:213-217, 700-707, 759-766, python/numbersprotocol_capture/crypto.py:99-108
Multiple except Exception: pass blocks silently swallow errors during error response JSON parsing and crypto operations. This hides security-relevant errors like malformed responses, truncated data, or unexpected server behavior.
Suggested fix: Log caught exceptions at debug level instead of silently swallowing them. At minimum, preserve the original error context.
6. Client-Side fileUrl Scheme Validation Missing (TypeScript)
File: ts/src/client.ts:499-500
The searchAsset method forwards fileUrl to the backend without validating the URL scheme. While server-side SSRF is tracked in #15, adding client-side defense-in-depth (rejecting file://, metadata endpoints) would prevent misuse.
Suggested fix: Validate parsed.protocol is http: or https: before sending.
Generated by Health Monitor with Omni
Summary
Multiple medium-severity security findings across both SDKs related to secret handling, build artifacts, and input validation.
1. Private Key Retained in Memory Without Zeroing (Both SDKs)
Files:
python/numbersprotocol_capture/crypto.py:48-63ts/src/crypto.ts:41Both SDKs receive the Ethereum private key as an immutable string. The key persists in memory until garbage collected, appearing in heap dumps, core dumps, or memory inspection tools. Neither SDK attempts to minimize the lifetime of key material.
Suggested fix: Accept private key as
Uint8Array/bytearraythat can be zeroed after use. Alternatively, support a "bring your own signer" callback pattern:sign?: { signer: (message: string) => Promise<string>; address: string }.2. API Token Exposed via Python
__repr__/ Debugger InspectionFile:
python/numbersprotocol_capture/client.py:131-158The
Captureclass stores the token asself._tokenwithout a custom__repr__(). The token appears invars(capture),capture.__dict__, and framework traceback reporters (e.g., Sentry, cgitb).Suggested fix: Implement
__repr__()that masks the token:Capture(token='***...abc', base_url='...').3. Source Maps Included in Production npm Package
Files:
ts/tsup.config.ts:8,ts/tsconfig.json:14Both
sourcemap: truesettings cause.mapfiles to be published to npm, exposing full original TypeScript source to anyone who installs the package. While the SDK is open source, this increases package size and aids vulnerability discovery.Suggested fix: Set
sourcemap: falseor'hidden'intsup.config.ts. Exclude*.mapfrompackage.jsonfilesarray.4.
customMetadataAccepts Arbitrary Unsanitized JSON (TypeScript)Files:
ts/src/client.ts:305-306,ts/src/types.ts:58The
update()method acceptscustomMetadata: Record<string, unknown>and serializes it directly viaJSON.stringify. This allows deeply nested objects (JSON bomb DoS), excessively large strings, and potential stored XSS payloads if the server renders metadata in a web context.Suggested fix: Add max serialized size check (e.g., 10KB). Restrict value types to
Record<string, string | number | boolean>.5. Overly Broad Exception Swallowing (Python)
Files:
python/numbersprotocol_capture/client.py:213-217, 700-707, 759-766,python/numbersprotocol_capture/crypto.py:99-108Multiple
except Exception: passblocks silently swallow errors during error response JSON parsing and crypto operations. This hides security-relevant errors like malformed responses, truncated data, or unexpected server behavior.Suggested fix: Log caught exceptions at debug level instead of silently swallowing them. At minimum, preserve the original error context.
6. Client-Side
fileUrlScheme Validation Missing (TypeScript)File:
ts/src/client.ts:499-500The
searchAssetmethod forwardsfileUrlto the backend without validating the URL scheme. While server-side SSRF is tracked in #15, adding client-side defense-in-depth (rejectingfile://, metadata endpoints) would prevent misuse.Suggested fix: Validate
parsed.protocolishttp:orhttps:before sending.Generated by Health Monitor with Omni