Issue Summary
There is a potential data exposure vulnerability in
packages/app-store/_utils/getConnectedApps.ts.
The current implementation uses object destructuring with a deny-list approach:
({ credentials: _, credential, key: _2, ...app })
While specific sensitive fields are removed, the remaining properties are
blindly spread using ...app into the API response.
This approach is unsafe because:
- It implicitly exposes all non-excluded fields
- Any new fields added in the future (e.g., internal configs, metadata)
will be automatically leaked
- It violates the principle of explicit data control in API design
Additionally, there is an internal developer note highlighting this issue:
// TODO: Refactor this to pick up only needed fields and prevent more leaking
Steps to Reproduce
-
Open:
packages/app-store/_utils/getConnectedApps.ts
-
Navigate to lines 149–151
-
Observe the mapping logic:
- Sensitive fields are excluded using destructuring
- Remaining object is spread via ...app into the response
-
Add any new internal property in:
- appStoreMetadata, or
- database schema
-
Call getConnectedApps API
-> The newly added internal field will be exposed to the frontend unintentionally
Actual Result
- The API uses a deny-list pattern
- All unspecified properties are automatically included in the response
- This can lead to unintentional leakage of internal or sensitive metadata
Expected Result
The API should follow a strict allow-list approach, where only explicitly
defined safe fields are returned.
Example:
return {
slug: app.slug,
name: app.name,
logo: app.logo,
categories: app.categories,
variant: app.variant,
};
This ensures:
- No accidental exposure of new/internal fields
- Safer and predictable API behavior
- Better long-term maintainability
Technical Details
- File: packages/app-store/_utils/getConnectedApps.ts
- Lines: 149–151
- Component: Backend utilities / tRPC layer
- Environment: Backend logic issue (browser independent)
Evidence
Relevant code snippet:
// TODO: Refactor this to pick up only needed fields and prevent more leaking
let apps = await Promise.all(
enabledApps.map(async ({ credentials: _, credential, key: _2 /* don't leak to frontend */, ...app }) => {
This confirms:
- Known internal concern (via TODO)
- Current reliance on spread operator after partial filtering
Impact
- Risk of data leakage to frontend clients
- Possible exposure of:
- internal configuration
- metadata
- future sensitive fields
- Violates secure API design principles (least privilege)
Proposed Fix
Refactor the mapping logic to:
- Replace deny-list with explicit allow-list
- Return only required public fields
- Avoid usage of ...app in API responses
Contribution
I will be submitting a Pull Request to implement a secure allow-list based fix.
Issue Summary
There is a potential data exposure vulnerability in
packages/app-store/_utils/getConnectedApps.ts.
The current implementation uses object destructuring with a deny-list approach:
({ credentials: _, credential, key: _2, ...app })
While specific sensitive fields are removed, the remaining properties are
blindly spread using ...app into the API response.
This approach is unsafe because:
will be automatically leaked
Additionally, there is an internal developer note highlighting this issue:
// TODO: Refactor this to pick up only needed fields and prevent more leaking
Steps to Reproduce
Open:
packages/app-store/_utils/getConnectedApps.ts
Navigate to lines 149–151
Observe the mapping logic:
Add any new internal property in:
Call getConnectedApps API
-> The newly added internal field will be exposed to the frontend unintentionally
Actual Result
Expected Result
The API should follow a strict allow-list approach, where only explicitly
defined safe fields are returned.
Example:
return {
slug: app.slug,
name: app.name,
logo: app.logo,
categories: app.categories,
variant: app.variant,
};
This ensures:
Technical Details
Evidence
Relevant code snippet:
// TODO: Refactor this to pick up only needed fields and prevent more leaking
let apps = await Promise.all(
enabledApps.map(async ({ credentials: _, credential, key: _2 /* don't leak to frontend */, ...app }) => {
This confirms:
Impact
Proposed Fix
Refactor the mapping logic to:
Contribution
I will be submitting a Pull Request to implement a secure allow-list based fix.