Skip to content

fix(security): prevent streaming upload filename path disclosure - #2386

Merged
HAYDEN-OAI merged 5 commits into
mainfrom
agent/streaming-filename-path-privacy-txrrei
Aug 19, 2026
Merged

HAYDEN-OAI merged 5 commits into
mainfrom
agent/streaming-filename-path-privacy-txrrei

Conversation

@HAYDEN-OAI

Copy link
Copy Markdown
Contributor
  • I understand that this repository is auto-generated and my pull request may not be merged

Summary

  • Strip POSIX and Windows parent directories from lazy toStreamingFile() uploads by default, matching existing buffered File behavior and preventing private local paths from appearing in multipart filenames.
  • Preserve explicitly opted-in nested Skills paths, Windows path normalization, literal backslash/control-character header escaping, lazy streaming, metadata, sparse upload ordering, and safe filename fallbacks.
  • Update one preexisting expectation that explicitly encoded the old default-path-disclosure behavior.

Validation

  • Regression first: 10 failing public SDK cases and 3 passing compatibility controls before the fix; all 13 focused regressions pass.
  • Public client.files.create, client.images.edit, client.audio.transcriptions.create, client.skills.create, and client.skills.versions.create.
  • Full handwritten suite: 100 files / 2,979 tests passed.
  • Minimum-supported Node 22 focused matrix: 5 files / 113 tests passed.
  • ./scripts/lint
  • pnpm exec tsc --project tsconfig.json --noEmit
  • ./scripts/build
  • TypeScript 4.9 and current TypeScript against published dist/src.
  • node --experimental-strip-types scripts/test-packed-package.ts
  • node --experimental-strip-types scripts/check-node-version-policy.ts

Only two handwritten upload tests and their owning handwritten upload implementation were changed; no generated endpoints or package metadata changed.

@openai-sdks

openai-sdks Bot commented Aug 17, 2026 •

Copy link
Copy Markdown
Contributor

OkTest Summary

✅ 237/237 SDK tests passed in 10.756s for Node SDK PR #2386.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 167ms
tests/chat-completions-create.test.ts ✅ Passed 211ms
tests/chat-completions-stream.test.ts ✅ Passed 127ms
tests/files-content-binary.test.ts ✅ Passed 157ms
tests/files-create-multipart.test.ts ✅ Passed 143ms
tests/files-list-pagination.test.ts ✅ Passed 201ms
tests/initialize-config.test.ts ✅ Passed 171ms
tests/instance-isolation.test.ts ✅ Passed 126ms
tests/models-list.test.ts ✅ Passed 133ms
tests/responses-background-lifecycle.test.ts ✅ Passed 253ms
tests/responses-body-method-errors.test.ts ✅ Passed 324ms
tests/responses-cancel-timeout.test.ts ✅ Passed 260ms
tests/responses-cancel.test.ts ✅ Passed 277ms
tests/responses-compact-retries.test.ts ✅ Passed 223ms
tests/responses-compact.test.ts ✅ Passed 214ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 128ms
tests/responses-create-advanced.test.ts ✅ Passed 261ms
tests/responses-create-disconnect.test.ts ✅ Passed 1.095s
tests/responses-create-errors.test.ts ✅ Passed 194ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 200ms
tests/responses-create-retries.test.ts ✅ Passed 284ms
tests/responses-create-stream-failures.test.ts ✅ Passed 136ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 2.14s
tests/responses-create-stream-wire.test.ts ✅ Passed 2.508s
tests/responses-create-stream.test.ts ✅ Passed 167ms
tests/responses-create-terminal-states.test.ts ✅ Passed 247ms
tests/responses-create-timeout.test.ts ✅ Passed 232ms
tests/responses-create.test.ts ✅ Passed 132ms
tests/responses-delete.test.ts ✅ Passed 219ms
tests/responses-input-items-errors.test.ts ✅ Passed 206ms
tests/responses-input-items-list.test.ts ✅ Passed 196ms
tests/responses-input-items-options.test.ts ✅ Passed 110ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 302ms
tests/responses-input-tokens-count.test.ts ✅ Passed 244ms
tests/responses-malformed-inputs.test.ts ✅ Passed 2.312s
tests/responses-not-found-errors.test.ts ✅ Passed 273ms
tests/responses-parse.test.ts ✅ Passed 247ms
tests/responses-retrieve-retries.test.ts ✅ Passed 259ms
tests/responses-retrieve.test.ts ✅ Passed 288ms
tests/responses-stored-method-errors.test.ts ✅ Passed 622ms
tests/retry-behavior.test.ts ✅ Passed 3.271s
tests/sdk-error-shape.test.ts ✅ Passed 281ms

View OkTest run #32084142613

SDK merge (c4e74477d68b) · head (7f0954510f3c) · base (1f3ce0760abb) · OkTest (7e7850017529)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f8fd78be7b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/internal/uploads.ts Resolved

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This aligns branded streaming uploads with buffered uploads by stripping directory components before multipart-header construction. The default path now covers mixed/nested bodies and preserves lazy streaming, but the Skills path-preserving mode still admits unsafe path shapes and the exported filename documentation no longer matches wire behavior.

Confirmed findings

  1. [Medium] Skills uploads preserve absolute and traversal-bearing paths

    • Location: src/internal/uploads.ts:462-464
    • Both public Skills methods hardcode stripFilenames: false for directory upload. normalizeFilenamePath only converts backslashes, so absolute POSIX paths, drive/UNC/device paths, and .. segments are still transmitted. This retains local-path disclosure and gives a relative directory-upload field unsafe names.
    • Centralize a preserved-relative-path validator for buffered and streaming paths: keep safe nested relative names, but reject leading /, drive/UNC/device forms, and parent segments. Add public Skills regressions for both upload modes.
  2. [Low] Exported toStreamingFile filename documentation is now inaccurate

    • Location: src/internal/uploads.ts:39-54
    • The comments say name is the filename sent in multipart, but default endpoints now send only its basename while Skills preserves a normalized relative path.
    • Document name as the logical/source name from which the wire filename is derived, including default directory stripping and the Skills exception.

All exact-head checks passed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c29bd16875

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/internal/uploads.ts Resolved

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6cd609684e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/internal/uploads.ts Resolved

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent two-pass re-review confirms the prior path-preservation and documentation issues are fixed. Buffered and streaming Skills uploads reject absolute, Windows drive and UNC, and traversal paths while preserving safe relative structure and lazy streaming. Validated inputs are snapshotted, threads are resolved, and substantive CI is green. No actionable findings.

@HAYDEN-OAI
HAYDEN-OAI added this pull request to the merge queue Aug 19, 2026
Merged via the queue into main with commit c88a024 Aug 19, 2026
27 checks passed
@HAYDEN-OAI
HAYDEN-OAI deleted the agent/streaming-filename-path-privacy-txrrei branch August 19, 2026 16:28
@openai-sdks openai-sdks Bot mentioned this pull request Aug 19, 2026

This branch was successfully deployed

1 active deployment
ci — 7f095451 Deployed Aug 18, 2026 by HAYDEN-OAI via ecosystem tests #8340
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants