fix: harden security for API client, storage, and exports (#64, #65, #66, #67, #68) - #118
Conversation
, #67, #68) - Sanitize inputs in api-client and bulk-api to prevent injection - Harden storage layer against path traversal - Add CSP headers to manifest.json - Validate CSV/Excel export inputs for malicious content - Secure background message handlers Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f99d378bc6
ℹ️ 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".
| if (/^[=+\-@\t\r]/.test(str)) { | ||
| str = `'${str}`; |
There was a problem hiding this comment.
Do not escape values sent to the Bulk API
For Bulk imports, recordsToCsv serializes the actual payload uploaded to Salesforce, not a spreadsheet opened by a user. Prefixing these values therefore corrupts legitimate text such as +15551234, -part, or @handle; numeric values parsed from an input CSV are also strings, so a value such as -10 becomes '-10 and can fail validation for a numeric Salesforce field. Formula neutralization should remain limited to user-facing exports rather than the ingest path.
Useful? React with 👍 / 👎.
| const { accessToken, tokenExpiresAt, ...safeOrg } = org; | ||
| void accessToken; | ||
| void tokenExpiresAt; | ||
| orgs[org.orgId] = safeOrg as SalesforceOrg; |
There was a problem hiding this comment.
Rehydrate session tokens before returning stored orgs
When the service worker is evicted during a Bulk job, DATA_PUSH_CANCEL reads the org with storage.getOrg() and passes it directly to bulkServiceFor. This change removes accessToken from that returned object, while setSessionToken() has no corresponding read path, so the abort request is sent with Bearer undefined; the handler then swallows the failure and reports the checkpoint as cancelled even though the Salesforce job can continue processing. Stored orgs must be rehydrated from session storage, or this path must obtain a validated org before issuing the abort.
Useful? React with 👍 / 👎.
| if (message.source !== 'app' && message.source !== 'popup') { | ||
| return { | ||
| success: false, | ||
| error: { code: 'UNAUTHORIZED_SOURCE', message: `DATA_IMPORT not allowed from source: ${message.source}` }, |
There was a problem hiding this comment.
Keep backup restore usable from the in-page panel
The in-page PanelRoot constructs SfApi('content') and renders SettingsScreen, whose Import Data action calls importUserData. Consequently every backup restore initiated from that panel now returns UNAUTHORIZED_SOURCE, although the action remains visible and previously worked. Either authorize this operation using the sender's verified extension context or remove/route the panel action to an authorized surface.
Useful? React with 👍 / 👎.
Summary
Hardens security across API client, storage layer, and export utilities.
Issues Fixed
Changes
🤖 Generated with Claude Code