Skip to content

fix(security): remove token leakage to third-party NFT endpoint and enforce response size limits#13

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/fix-token-leakage-risk
Draft

fix(security): remove token leakage to third-party NFT endpoint and enforce response size limits#13
Copilot wants to merge 2 commits intomainfrom
copilot/fix-token-leakage-risk

Conversation

Copy link

Copilot AI commented Feb 27, 2026

Two medium-severity security issues: the SDK was forwarding the user's API token to a third-party Pipedream endpoint (https://eofveg1f59hrbn.m.pipedream.net), and no response body size limit was enforced anywhere, leaving clients open to memory exhaustion from oversized payloads.

Token leakage fix

Removed Authorization header from search_nft / searchNft calls — this endpoint does not require authentication and should never receive user credentials.

Response size limiting (10 MB cap)

Python — replaced non-streaming _client.request() / _client.post() calls with _client.stream() + a shared _read_response_body() helper that enforces the limit during chunked reads:

def _read_response_body(self, response: httpx.Response) -> bytes:
    content_length = response.headers.get("content-length")
    if content_length and int(content_length) > MAX_RESPONSE_SIZE:
        raise NetworkError("Response body too large")
    chunks, total_size = [], 0
    for chunk in response.iter_bytes():
        total_size += len(chunk)
        if total_size > MAX_RESPONSE_SIZE:
            raise NetworkError("Response body too large")
        chunks.append(chunk)
    return b"".join(chunks)

TypeScript — added readJsonWithSizeLimit() using ReadableStream.getReader() for chunk-by-chunk enforcement, applied to all fetch call sites (request, getHistory, getAssetTree, searchAsset, searchNft):

async function readJsonWithSizeLimit(response: Response): Promise<unknown> {
  const contentLength = response.headers?.get('content-length')
  if (contentLength !== null && parseInt(contentLength, 10) > MAX_RESPONSE_SIZE) {
    throw new NetworkError('Response body too large')
  }
  const reader = response.body.getReader()
  // ... reads chunks, throws NetworkError if totalSize > MAX_RESPONSE_SIZE
}

Both SDKs check Content-Length eagerly (fast-path rejection) before streaming, and MAX_RESPONSE_SIZE is set to 10 MB in both.

Original prompt

This section details on the original issue you should resolve

<issue_title>[Security][Medium] Token leakage risk to third-party NFT search endpoint and missing response size limits</issue_title>
<issue_description>## Summary

Two medium-severity security concerns identified during automated code audit:

1. API Token Sent to Third-Party Pipedream Endpoint

Files: python/numbersprotocol_capture/client.py (L743-753), ts/src/client.ts (L576-583)

The SDK sends the user's Authorization: token {value} header to the NFT search endpoint hosted on Pipedream (https://eofveg1f59hrbn.m.pipedream.net). This is a third-party service that receives the full authentication token. While the connection uses HTTPS, users may not expect their Capture API token to be forwarded to external services.

Impact: If the Pipedream endpoint is compromised or logging tokens, user credentials could be exposed.

Suggested fix:

  • Document clearly which external endpoints receive the token
  • Consider whether the NFT search endpoint actually requires authentication, and if not, omit the token
  • Alternatively, use a separate, scoped token for third-party service calls

2. No HTTP Response Body Size Limit

Files: python/numbersprotocol_capture/client.py (all _request and direct HTTP calls), ts/src/client.ts (all fetch calls)

Neither the Python SDK (using httpx.Client) nor the TypeScript SDK (using fetch) enforces a maximum response body size. A malicious or misconfigured server could return an arbitrarily large response, causing memory exhaustion in the client application.

Impact: Potential denial-of-service if an API endpoint returns an unexpectedly large payload.

Suggested fix:

  • Python: Use httpx's streaming responses with a size check, or set max_content_length
  • TypeScript: Read the response body in chunks and abort if size exceeds a reasonable limit (e.g., 10 MB)

Severity

Medium — no immediate exploitation risk, but reduces defense-in-depth.</issue_description>

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


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

…size limits

- Remove Authorization header from search_nft/searchNft calls to the
  third-party Pipedream endpoint (https://eofveg1f59hrbn.m.pipedream.net)
- Add MAX_RESPONSE_SIZE = 10 MB constant in both Python and TypeScript SDKs
- Python: add _read_response_body() streaming helper; refactor _request,
  search_asset, and search_nft to use httpx streaming with size checks
- TypeScript: add readJsonWithSizeLimit() streaming helper using
  ReadableStream; apply to request, getHistory, getAssetTree,
  searchAsset, and searchNft
- Add tests for token non-leakage and response size enforcement

Co-authored-by: numbers-official <181934381+numbers-official@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix token leakage risk to third-party endpoint fix(security): remove token leakage to third-party NFT endpoint and enforce response size limits Feb 27, 2026
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] Token leakage risk to third-party NFT search endpoint and missing response size limits

2 participants