Skip to content

security: private key signer callback, token masking, source map removal, metadata limits, exception logging, URL scheme validation#27

Draft
Copilot wants to merge 3 commits intomainfrom
copilot/fix-private-key-exposure
Draft

security: private key signer callback, token masking, source map removal, metadata limits, exception logging, URL scheme validation#27
Copilot wants to merge 3 commits intomainfrom
copilot/fix-private-key-exposure

Conversation

Copy link

Copilot AI commented Mar 15, 2026

Six medium-severity security findings across both SDKs covering secret handling, build artifacts, and input validation.

Changes

1. Custom signer callback to reduce private key memory exposure (both SDKs)

SignOptions now accepts a signer callback + address as an alternative to privateKey, so the private key can stay entirely outside the SDK process.

TypeScript:

// New: key never enters this process
await capture.register(file, {
  sign: {
    signer: (msg) => externalWallet.signMessage(msg),
    address: '0xABC...',
  }
})

// Legacy still works
await capture.register(file, { sign: { privateKey: '0x...' } })

Python:

from numbersprotocol_capture.types import SignOptions

# Custom signer
capture.register(file, options=RegisterOptions(
    sign=SignOptions(signer=my_signer_fn, address="0xABC...")
))

2. Mask API token in Python __repr__

Capture.__repr__() now returns Capture(token='***...abcd', base_url='...'), preventing the token from appearing in Sentry tracebacks, vars(), or debugger output.

3. Remove source maps from npm package

tsup.config.ts: sourcemap: truesourcemap: false. Eliminates .map files from the published npm package.

4. Restrict customMetadata type + 10 KB size limit (both SDKs)

  • TypeScript: Record<string, unknown>Record<string, string | number | boolean>
  • Python: dict[str, Any]dict[str, str | int | float | bool]
  • Both SDKs raise ValidationError if the serialized payload exceeds 10 KB (measured in UTF-8 bytes).

5. Log swallowed exceptions at DEBUG level (Python)

Four except Exception: pass blocks in client.py and crypto.py replaced with logger.debug(...) so malformed responses and crypto failures surface under debug logging.

6. fileUrl scheme validation in searchAsset (both SDKs)

Both SDKs now reject non-http/https schemes (e.g. file://, ftp://) with a ValidationError before the request is sent.

Original prompt

This section details on the original issue you should resolve

<issue_title>[Security][Medium] Private key memory exposure, source maps in npm, exception swallowing, and metadata injection</issue_title>
<issue_description>## 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</issue_description>

Comments on the Issue (you are @copilot in this section)


📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.

Copilot AI and others added 2 commits March 15, 2026 14:17
… validation, exception swallowing, and URL scheme validation

Co-authored-by: numbers-official <[email protected]>
Copilot AI changed the title [WIP] [Security] Fix private key memory exposure in SDKs security: private key signer callback, token masking, source map removal, metadata limits, exception logging, URL scheme validation Mar 15, 2026
Copilot AI requested a review from numbers-official March 15, 2026 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security][Medium] Private key memory exposure, source maps in npm, exception swallowing, and metadata injection

2 participants