Skip to content

security: URL injection via unvalidated workspaceId and channelId #2

@SippieCup

Description

@SippieCup

Severity

Critical

Description

workspaceId and channelId (from plugin config or environment variables) are interpolated directly into the ClickUp API URL without any validation or encoding.

Vulnerable codesrc/send-message.ts:19:

const url = `${CLICKUP_API_BASE}/workspaces/${workspaceId}/chat/channels/${channelId}/messages`;

Risk

An attacker who can control environment variables or plugin config (e.g., compromised CI secrets, supply-chain attack on .releaserc) can:

  • Perform path traversal: workspaceId = "ws1/../../admin"
  • Inject query strings: channelId = "ch1?admin=true"
  • Redirect the API request to an unintended endpoint

Exploit Example

{
  "workspaceId": "123/../../../v2/admin",
  "channelId": "456"
}

Resulting URL: https://api.clickup.com/api/v3/workspaces/123/../../../v2/admin/chat/channels/456/messages

Recommended Fix

Encode path segments with encodeURIComponent and/or validate against an alphanumeric-plus-hyphens pattern:

// Validate
const ID_RE = /^[\w-]+$/;
if (!ID_RE.test(workspaceId) || !ID_RE.test(channelId)) {
  throw new Error("Invalid workspaceId or channelId format");
}
// Encode
const url = `${CLICKUP_API_BASE}/workspaces/${encodeURIComponent(workspaceId)}/chat/channels/${encodeURIComponent(channelId)}/messages`;

Validation should also be added to verifyConditions.


AI Fix Prompt

In the file src/send-message.ts (line 19) and src/verify-conditions.ts, fix a URL injection vulnerability where workspaceId and channelId are directly interpolated into an API URL without validation.

Changes needed:
1. In src/send-message.ts, wrap both workspaceId and channelId with encodeURIComponent() in the URL template literal on line 19.
2. In src/verify-conditions.ts, add validation that workspaceId and channelId match /^[\w-]+$/ (alphanumeric and hyphens only). If they don't match, push a new error using getError() — add EINVALIDWORKSPACEID and EINVALIDCHANNELID error codes to src/errors.ts with appropriate messages.
3. Update tests in test/verify-conditions.test.ts to cover the new validation cases.
4. Keep changes minimal — only touch what is necessary for the security fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingsecuritySecurity vulnerability or concern

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions