Skip to content

fix(web): validate attachment filename types - #380

Open
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/issue-344-attachment-type-safety
Open

fix(web): validate attachment filename types#380
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/issue-344-attachment-type-safety

Conversation

@seekskyworld

Copy link
Copy Markdown
Contributor

Problem

Adds the MIME/filename consistency slice of #344. Attachment admission could accept a filename whose extension contradicted its declared content type.

Value

Future upload paths get a clearer fail-closed boundary against misleading or malformed attachment metadata.

Approach

Require supported MIME types to use an allowed filename extension while retaining count, traversal, per-file, and aggregate byte limits.

Validation

  • npx tsc --noEmit
  • git diff --check

Impact

  • User-visible behavior: invalid type/extension pairs are rejected.
  • Model-visible context/tools: none.
  • Runtime/lifecycle: none.
  • Persisted config/data: none.
  • Compatibility/risk: additive validation for future attachment admission.

Signed-off-by: seekskyworld <djh1813553759@gmail.com>

@tt-a1i tt-a1i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

切片对,但会和 #365 硬冲突

MIME↔扩展名白名单、拒绝 ..,方向对。问题:

  1. 整文件重造了 attachments.ts,和 #365 合不了。请 rebase 到 #365 上,只留类型校验。
  2. 没有测试。toLocaleLowerCase() 做扩展名折叠,会吃 locale。
  3. #388 的 staging 现在还没调用这个校验。准入应先于暂存。

@tt-a1i tt-a1i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Exact-head review of 5bf88a1. The MIME/extension admission boundary is useful, but malformed MIME metadata currently throws instead of returning the validator's bounded rejection result. The existing integration concerns with #365/#388 also remain; this review adds one independently reproduced correctness finding. No deployed HTTP or installed runtime impact is claimed.

for (const attachment of attachments) {
if (!/^(?!\.\.?(?:$|\.))[\w .()\[\]-]{1,120}$/u.test(attachment.name) || attachment.name.includes("..")) return { ok: false as const, error: "invalid attachment name" };
if (!MIME_EXTENSIONS[attachment.mime]) return { ok: false as const, error: "unsupported attachment type" };
if (!MIME_EXTENSIONS[attachment.mime].some((extension) => attachment.name.toLocaleLowerCase().endsWith(extension))) return { ok: false as const, error: "attachment extension does not match type" };

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2] Reject inherited object keys before invoking the extension list

MIME_EXTENSIONS is an ordinary object, so a MIME value of constructor or __proto__ passes the truthiness check on the preceding line. This line then throws TypeError: MIME_EXTENSIONS[attachment.mime].some is not a function, rather than returning { ok: false, error: "unsupported attachment type" }. I reproduced both with the exact-head module and validateWebAttachments([{ name: "x.txt", mime, size: 1 }]); the normal text/plain case succeeds.

Use an own-property whitelist lookup (or a Map/null-prototype record) and add regression cases for inherited keys so arbitrary unsupported MIME strings are rejected without throwing. This is the pure admission contract, not evidence of an active upload endpoint.

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.

2 participants