[STG-1692] feat: resolve context labels in browse --context-id#1928
[STG-1692] feat: resolve context labels in browse --context-id#1928
Conversation
Look up --context-id values as label files in ~/.config/browserbase/contexts/ before treating them as raw UUIDs. This interoperates with bb sync's label system so 'browse open <url> --context-id work --persist' works natively. Respects BROWSERBASE_CONFIG_DIR env var for custom config paths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: ad7f76b The changes in this PR will be included in the next version bump. This PR includes changesets to release 0 packagesWhen changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move resolveContextLabel from inline in index.ts to resolve-context.ts so it can be tested independently - Add 6 tests covering: UUID passthrough, ctx_ passthrough, label resolution, whitespace trimming, missing labels, empty files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 2 files
Confidence score: 2/5
- High-risk security concern:
packages/cli/src/index.tsuses--context-iddirectly as a filesystem path segment, which can allow path traversal and unintended file reads during label resolution. - The issue is concrete and high confidence (8/10 severity, 9/10 confidence), so this is not just a theoretical edge case and should be addressed before merge.
- This PR likely needs input sanitization/path normalization for
--context-idto reduce user-impacting and security regression risk. - Pay close attention to
packages/cli/src/index.ts- unsanitized CLI input is flowing into filesystem path construction.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/cli/src/index.ts">
<violation number="1" location="packages/cli/src/index.ts:191">
P1: `--context-id` is used as a filesystem path segment without sanitization, enabling path traversal/arbitrary file reads during label resolution.</violation>
</file>
Architecture diagram
sequenceDiagram
participant User
participant CLI as browse-cli
participant Env as Environment Variables
participant FS as Local Filesystem
participant API as Browserbase API
User->>CLI: browse open <url> --context-id <value>
rect rgb(240, 240, 240)
Note over CLI: NEW: resolveContextLabel(value)
alt value matches UUID regex OR starts with 'ctx_'
CLI->>CLI: Use raw value as ID
else value is a named label (e.g., 'work', 'latest')
CLI->>Env: Check BROWSERBASE_CONFIG_DIR
Env-->>CLI: Path (or default to ~/.config/browserbase)
CLI->>FS: Read file at <configDir>/contexts/<value>
alt File exists and is not empty
FS-->>CLI: Context UUID string
CLI->>CLI: Trim whitespace
Note right of CLI: Log: Resolved context "label" → UUID
else File missing or Read error
FS-->>CLI: Error
CLI->>CLI: CHANGED: Fallback to raw label string
end
end
end
CLI->>CLI: Construct session config with resolved ID
CLI->>API: Request session (POST /sessions)
alt Valid Context ID
API-->>CLI: 200 OK (Session Started)
else Invalid Context ID (Fallback failed)
API-->>CLI: 400/404 Error
end
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
packages/cli/src/index.ts
Outdated
| const configDir = | ||
| process.env.BROWSERBASE_CONFIG_DIR || | ||
| path.join(os.homedir(), ".config", "browserbase"); | ||
| const labelPath = path.join(configDir, "contexts", value); |
There was a problem hiding this comment.
P1: --context-id is used as a filesystem path segment without sanitization, enabling path traversal/arbitrary file reads during label resolution.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/cli/src/index.ts, line 191:
<comment>`--context-id` is used as a filesystem path segment without sanitization, enabling path traversal/arbitrary file reads during label resolution.</comment>
<file context>
@@ -168,6 +168,40 @@ function getLocalInfoPath(session: string): string {
+ const configDir =
+ process.env.BROWSERBASE_CONFIG_DIR ||
+ path.join(os.homedir(), ".config", "browserbase");
+ const labelPath = path.join(configDir, "contexts", value);
+ try {
+ const id = (await fs.readFile(labelPath, "utf-8")).trim();
</file context>
| const labelPath = path.join(configDir, "contexts", value); | |
| const normalizedLabel = path.basename(value); | |
| if (normalizedLabel !== value || value.includes("..")) { | |
| return value; | |
| } | |
| const labelPath = path.join(configDir, "contexts", normalizedLabel); |
There was a problem hiding this comment.
2 issues found across 3 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/cli/src/resolve-context.ts">
<violation number="1" location="packages/cli/src/resolve-context.ts:22">
P1: Unvalidated `--context-id` label input allows path traversal outside the `contexts` directory.</violation>
</file>
<file name="packages/cli/tests/resolve-context.test.ts">
<violation number="1" location="packages/cli/tests/resolve-context.test.ts:30">
P2: Restoring the env var by assigning `undefined` leaves `BROWSERBASE_CONFIG_DIR` set to the literal string "undefined" when it was originally unset. Delete the env var instead when `originalEnv` is undefined to avoid leaking state into other tests.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| const configDir = | ||
| process.env.BROWSERBASE_CONFIG_DIR || | ||
| path.join(os.homedir(), ".config", "browserbase"); | ||
| const labelPath = path.join(configDir, "contexts", value); |
There was a problem hiding this comment.
P1: Unvalidated --context-id label input allows path traversal outside the contexts directory.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/cli/src/resolve-context.ts, line 22:
<comment>Unvalidated `--context-id` label input allows path traversal outside the `contexts` directory.</comment>
<file context>
@@ -0,0 +1,33 @@
+ const configDir =
+ process.env.BROWSERBASE_CONFIG_DIR ||
+ path.join(os.homedir(), ".config", "browserbase");
+ const labelPath = path.join(configDir, "contexts", value);
+ try {
+ const id = (await fs.readFile(labelPath, "utf-8")).trim();
</file context>
| }); | ||
|
|
||
| afterAll(() => { | ||
| process.env.BROWSERBASE_CONFIG_DIR = originalEnv; |
There was a problem hiding this comment.
P2: Restoring the env var by assigning undefined leaves BROWSERBASE_CONFIG_DIR set to the literal string "undefined" when it was originally unset. Delete the env var instead when originalEnv is undefined to avoid leaking state into other tests.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/cli/tests/resolve-context.test.ts, line 30:
<comment>Restoring the env var by assigning `undefined` leaves `BROWSERBASE_CONFIG_DIR` set to the literal string "undefined" when it was originally unset. Delete the env var instead when `originalEnv` is undefined to avoid leaking state into other tests.</comment>
<file context>
@@ -0,0 +1,63 @@
+});
+
+afterAll(() => {
+ process.env.BROWSERBASE_CONFIG_DIR = originalEnv;
+ fs.rmSync(tmpDir, { recursive: true, force: true });
+});
</file context>
Summary
--context-idflag~/.config/browserbase/contexts/<label>bb sync --labelwhich saves context IDs under named labelsBROWSERBASE_CONFIG_DIRenv var (same convention as Stagehand session logging)ctx_prefixed IDs pass through unchangedWhy
bb syncsaves context IDs as named label files (e.g.~/.config/browserbase/contexts/work). Previously, label resolution only worked viabb browse(which intercepts args before forwarding). This change makesbrowseunderstand labels natively, sobrowse open <url> --context-id work --persistworks without thebbwrapper.Linked
Test plan
browse open <url> --context-id latest --persistresolves from ~/.config/browserbase/contexts/latestbrowse open <url> --context-id <raw-uuid> --persistpasses through unchanged🤖 Generated with Claude Code
Summary by cubic
Adds label resolution to
--context-idin@browserbasehq/browse-cli, so labels saved bybb sync --label(e.g., latest, work) resolve natively without thebbwrapper. Addresses Linear STG-1692.New Features
~/.config/browserbase/contexts/<label>and respectsBROWSERBASE_CONFIG_DIR.ctx_-prefixed IDs pass through unchanged.Refactors
resolveContextLabeltoresolve-context.tsand added tests covering UUID/ctx_passthroughs, label resolution, whitespace trimming, and missing/empty files.Written for commit ad7f76b. Summary will update on new commits. Review in cubic