Skip to content

Refuse a sandboxed component whose title is only whitespace - #393

Open
kevin9327 wants to merge 1 commit into
CopilotKit:mainfrom
kevin9327:fix/sandboxed-blank-title
Open

Refuse a sandboxed component whose title is only whitespace#393
kevin9327 wants to merge 1 commit into
CopilotKit:mainfrom
kevin9327:fix/sandboxed-blank-title

Conversation

@kevin9327

Copy link
Copy Markdown
Contributor

What this changes

POST /api/sandboxed took a title of spaces and stored it. The guard checked the field was present,
not that it said anything:

if (!body?.slug || !body.title) {  }

  slug: body.slug,
  title: body.title,

The slug is safe: SandboxedStore.save runs it against ^[a-z0-9][a-z0-9_]{0,38}[a-z0-9]$ and
refuses one made of spaces. The title has no check anywhere and is inserted verbatim, so the
component lands in the playground grid with nothing to read, and a Bot granted it is told the
component is called " ".

This is the third endpoint of that exact shape. #376 fixed POST /api/servers/custom and #377 fixed
POST /api/skills yesterday, both by trimming and refusing whitespace; this one was not in either
diff. The change here is the same two lines.

Where it runs

  • New state that outlives a request? None. The same row is written, with a trimmed title.
  • What happens on the second replica? Nothing differs. The check is per request and reads
    only the body.
  • Anything serialised? No change. save still upserts on sandboxedComponents.name.
  • Anything fanned out to a browser? No.
  • New listener, port, or schedule? None.

Boundary and audit

  • Every acting call still goes through the gateway: untouched, this is a save behind
    requireAdmin.
  • New refusals and new failures each write a row: the refusal is a 400 on a malformed body, the
    same class the two sibling endpoints answer without an audit row.
  • Nothing new is trusted from the client that the server can resolve itself: strictly less is
    trusted than before.

Changelog

  • A line in CHANGELOG.md under Unreleased.

Proof

server/tests/sandboxed-routes.test.ts, new. The two sibling fixes shipped without tests, so this
adds the ones that pin the behaviour for this route:

  • refuses a title that is only whitespace — 400, and the store is never called.
  • refuses a missing title, as it always did — the guard that already worked still works.
  • stores a padded title without its padding" Weather card " is saved as "Weather card".
  • leaves an ordinary title alone — no change to the ordinary path.

Before this change, two of the four fail:

(fail) stores a padded title without its padding
- "title": "Weather card",
+ "title": "  Weather card  ",
2 pass, 2 fail

After: 4 pass. bunx tsc --noEmit in server/ is clean, and bunx biome check on both files is
clean.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

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.

1 participant