Skip to content

[Security][Medium] SSRF risk, file size DoS, PermissionError shadowing, and CI/CD supply chain gaps #15

@numbers-official

Description

@numbers-official

Security Findings — Medium Severity

1. Custom baseUrl Allows SSRF When Used Server-Side

Files:

  • ts/src/client.ts line 152
  • python/numbersprotocol_capture/client.py line 158

Description:
Both SDKs accept a custom baseUrl/base_url parameter without any validation. There is no check that the URL uses HTTPS, belongs to a trusted domain, or is even a valid URL. The SDK will then send authenticated requests (including the API token) to whatever URL is provided.

Impact:
In server-side applications where baseUrl might be influenced by configuration or environment variables, this enables SSRF attacks. An attacker can set baseUrl to an internal network address (e.g., http://169.254.169.254/latest/meta-data/) to exfiltrate cloud credentials, or to an attacker-controlled server to capture the API token.

Suggested fix:
Add validation to ensure baseUrl uses HTTPS protocol. Optionally support a configurable allowlist of trusted domains. At minimum, reject http://, private IP ranges, and localhost.


2. No File Size Limits on Asset Registration (DoS via Memory Exhaustion)

Files:

  • ts/src/client.ts lines 86, 94, 103 (in normalizeFile)
  • python/numbersprotocol_capture/client.py lines 83, 92, 101 (in _normalize_file)

Description:
Both SDKs read entire files into memory without any size limit. The only validation is that the file is non-empty, but there is no upper bound. In TypeScript, the data is copied a second time for ArrayBuffer conversion, so peak memory is ~2x file size.

Impact:
A large file can cause out-of-memory crashes (denial of service). Particularly dangerous in server-side applications processing user-provided files.

Suggested fix:
Add a configurable maxFileSize parameter (default e.g. 100 MB). For file paths, use fs.stat() / path.stat() to check size before reading. For blobs, check .size property.


3. Python PermissionError Shadows Built-in

File: python/numbersprotocol_capture/errors.py line 35

Description:
The SDK defines a custom PermissionError class that shadows Python's built-in PermissionError (a subclass of OSError). Any code using from numbersprotocol_capture import * will shadow the built-in.

Impact:
except PermissionError blocks in user code will catch SDK API 403 errors but not OS-level file permission errors (or vice versa), causing confusing debugging scenarios.

Suggested fix:
Rename to ForbiddenError or AccessDeniedError to avoid name collision. This is a breaking change requiring a minor/major version bump with a deprecation alias.


4. API Token Sent to Multiple Third-Party Cloud Endpoints

Files:

  • ts/src/client.ts lines 374-379, 430-436
  • python/numbersprotocol_capture/client.py lines 449-451, 514-517

Description:
The API token is sent via Authorization header to four distinct third-party endpoints across different providers: the primary API, AWS Lambda, Google Cloud Functions, and Pipedream. Issue #10 covers only the Pipedream endpoint; the AWS Lambda and GCF endpoints also receive the full token.

The AWS Lambda URL uses an auto-generated API Gateway identifier (e23hi68y55), suggesting it may lack production-grade security controls.

Impact:
Broadest possible token exposure surface. If any third-party endpoint is compromised or logs request headers, the token is leaked.

Suggested fix:
Consider using separate, scoped tokens for different endpoints, or route all requests through the primary API. At minimum, document which endpoints receive the token.


5. CI/CD Release Pipeline Missing Integrity Verification

File: .github/workflows/release.yml lines 51-122

Description:

  • No CI test gate before publish: Publish jobs depend only on validate (version check), not on CI tests passing. A tag push can publish even if tests fail.
  • Unpinned GitHub Action: softprops/action-gh-release@v1 uses a mutable tag rather than a pinned SHA.
  • No artifact checksums: No verification of built artifacts before publishing.

Impact:
Compromised CI environment or dependency could inject malicious code into published packages without detection.

Suggested fix:

  1. Add CI test jobs as dependencies of publish jobs.
  2. Pin softprops/action-gh-release to a specific commit SHA.
  3. Add artifact checksum computation and include hashes in release notes.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions