Skip to content

feat: Netscape HTTP Cookie File support via --cookie-file - #6

Merged
teng-lin merged 3 commits into
mainfrom
feature/cookie-file
Feb 15, 2026
Merged

teng-lin merged 3 commits into
mainfrom
feature/cookie-file

Conversation

@teng-lin

Copy link
Copy Markdown
Owner

Summary

  • Add --cookie-file flag and AGENT_FETCH_COOKIE_FILE env var to load cookies from Netscape HTTP Cookie File format (standard format used by curl and browser extensions)
  • Cookie file entries are filtered by domain/path/secure/expiry per RFC 6265 before sending
  • Explicit --cookie flags take precedence over cookie file entries on name conflicts
  • Available in both CLI and programmatic API (cookieFile option on HttpFetchOptions)

Changes

  • New: src/fetch/cookie-file.ts — parser, URL-based filter, resolver, merge helper
  • New: src/__tests__/cookie-file.test.ts — 37 tests covering parser, URL filtering, resolver, merge, and error paths
  • Modified: src/cli.ts — --cookie-file shared flag, cookie merge in fetch and crawl commands
  • Modified: src/fetch/http-fetch.ts — cookieFile option on HttpFetchOptions

Security

  • Domain suffix attack prevention (.example.com won't match badexample.com)
  • Path segment boundary enforcement per RFC 6265 §5.1.4 (/api won't match /apiv2)
  • Descriptive error on missing/unreadable cookie files

Test plan

  • 37 unit tests passing (parser, domain/path/secure/expiry filtering, resolver, merge, error handling)
  • 903 total tests passing
  • Lint, format, build all pass
  • Manual test with real cookie file against authenticated site confirmed working

Add cookie file parsing and URL-based filtering so users can pass
browser-exported cookie files (the standard format used by curl and
browser extensions). Cookie file cookies merge with --cookie flags,
with explicit --cookie values taking precedence on conflicts.

- New module: src/fetch/cookie-file.ts (parser, URL filter, resolver)
- CLI: --cookie-file flag + AGENT_FETCH_COOKIE_FILE env var
- API: cookieFile option on HttpFetchOptions for programmatic use
- 31 new tests covering parser, URL filtering, and resolver
- Extract mergeCookies() helper to eliminate triplicated merge pattern
- Fix path matching to enforce segment boundaries per RFC 6265 §5.1.4
  (/api no longer matches /apiv2, only /api and /api/*)
- Add error handling in loadCookiesFromFile with descriptive message
- Rename domainWithoutDot → cookieDomain for conciseness
- Add tests: path boundary attack, file-not-found error, mergeCookies
@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @teng-lin, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the application's ability to manage and utilize HTTP cookies by introducing support for the widely adopted Netscape HTTP Cookie File format. This allows users to seamlessly integrate existing cookie stores from other tools, improving authentication workflows and overall flexibility when interacting with web resources. The implementation includes careful consideration for security and correct cookie behavior, ensuring that cookies are applied only when appropriate for the target URL.

Highlights

  • Netscape HTTP Cookie File Support: Added support for loading cookies from the standard Netscape HTTP Cookie File format, enabling compatibility with tools like curl and browser extensions.
  • Robust Cookie Filtering: Implemented comprehensive filtering of cookies based on the target URL's domain, path, secure flag (HTTPS only), and expiry date, adhering to RFC 6265 principles including domain suffix attack prevention and path segment boundary enforcement.
  • Flexible Configuration: Introduced a new --cookie-file CLI flag and an AGENT_FETCH_COOKIE_FILE environment variable for specifying the cookie file path. This functionality is also available programmatically via the cookieFile option in HttpFetchOptions.
  • Cookie Precedence: Ensured that explicitly provided cookies (e.g., via --cookie flag or cookies option) take precedence over entries loaded from the cookie file in case of name conflicts.
Changelog
  • src/tests/cookie-file.test.ts
    • Added 37 new unit tests covering parsing of Netscape cookie files, URL-based filtering logic (domain, path, secure, expiry), cookie file path resolution, cookie loading, and merging behavior, including error handling for missing files.
  • src/cli.ts
    • Imported new cookie file utility functions (resolveCookieFile, loadCookiesFromFile, mergeCookies).
    • Added a cookieFile property to the SharedFlags and CliOptions interfaces.
    • Implemented parsing for the new --cookie-file CLI argument.
    • Integrated cookie file loading and merging logic into the parseCrawlArgs and main functions to apply cookies from the file before explicit cookies.
  • src/fetch/cookie-file.ts
    • Added a new file defining the NetscapeCookie interface.
    • Implemented parseNetscapeCookieFile to parse content from the Netscape cookie file format, handling comments, blank lines, and malformed entries.
    • Developed filterCookiesForUrl to apply RFC 6265-compliant filtering based on domain (including subdomain and suffix attack prevention), path (with segment boundary enforcement), secure flag, and expiry.
    • Created resolveCookieFile to determine the cookie file path from explicit options or environment variables.
    • Added loadCookiesFromFile to read, parse, and filter cookies from a specified file for a given URL, including error handling for file access issues.
    • Provided mergeCookies to combine cookies from a file with explicitly defined cookies, giving precedence to explicit entries.
  • src/fetch/http-fetch.ts
    • Imported new cookie file utility functions (resolveCookieFile, loadCookiesFromFile, mergeCookies).
    • Added a cookieFile property to the HttpFetchOptions interface to allow programmatic specification of a cookie file.
    • Modified the httpFetch function to resolve and merge cookies from the specified cookie file with any explicit cookies provided in the options, ensuring explicit cookies override file-based ones.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for loading cookies from a Netscape-format cookie file, enhancing authenticated session handling. However, critical security vulnerabilities exist, including Path Traversal and Information Exposure, due to a lack of validation on file paths and sensitive error messages. Additionally, a high-severity code issue was found where an explicit empty cookie file path fails to correctly override environment variables, leading to unintended behavior.

Comment thread src/fetch/cookie-file.ts

let content: string;
try {
content = readFileSync(cookieFilePath, 'utf-8');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The cookieFilePath is used directly in readFileSync without validation or size limits. This allows for arbitrary file read (Path Traversal) and potential Denial of Service (DoS) if a very large file is provided. An attacker could exfiltrate sensitive data by sending file contents as cookies to a malicious URL. Consider validating that the path is within an allowed directory and checking the file size before reading.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a CLI tool — the user provides their own file path on their own machine via --cookie-file or an env var they set themselves. There is no server, no untrusted input, and the user already has full filesystem access. This is the same trust model as curl --cookie / curl --cookie-jar. Path traversal and arbitrary file read are not meaningful threats in this context.

A file size limit would prevent legitimate use cases (large cookie jars) without mitigating any real attack vector, since the "attacker" here would be the user themselves.

Comment thread src/fetch/cookie-file.ts Outdated
* Priority: explicit > AGENT_FETCH_COOKIE_FILE
*/
export function resolveCookieFile(explicit?: string): string | undefined {
return explicit || process.env.AGENT_FETCH_COOKIE_FILE || undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There's a subtle issue here. If a user provides an empty string for the explicit path (e.g., via --cookie-file "" on the command line), it will be treated as a falsy value, causing the function to fall back to the AGENT_FETCH_COOKIE_FILE environment variable. This is likely not the user's intent; an explicit empty path should probably disable the cookie file feature by returning undefined, overriding any environment variable.

  if (explicit !== undefined) {
    return explicit || undefined; // An explicit empty string means no file
  }
  return process.env.AGENT_FETCH_COOKIE_FILE || undefined;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Fixed in 68c1a22 — resolveCookieFile now checks explicit !== undefined first, so an explicit empty string returns undefined instead of falling through to the env var. Added a test for this case as well.

Comment thread src/fetch/cookie-file.ts
try {
content = readFileSync(cookieFilePath, 'utf-8');
} catch (err) {
throw new Error(`Failed to read cookie file: ${cookieFilePath}: ${(err as Error).message}`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The current error message exposes sensitive information like the full file path and system error details (e.g., ENOENT), which could reveal server file system structure to an attacker. Additionally, the message can be redundant by repeating the file path. It's recommended to use a more generic error message for the user and log detailed information internally to prevent information exposure and improve clarity.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a CLI tool — the user typed the file path themselves (or set the env var). Showing the path and the OS error (ENOENT, EACCES) in the message is the expected UX and helps the user debug typos or permission issues. Hiding this information would make the error less actionable. Same approach as curl, wget, etc.

An explicit empty string (--cookie-file "") now correctly returns
undefined instead of falling through to AGENT_FETCH_COOKIE_FILE.
@teng-lin
teng-lin merged commit 686388a into main Feb 15, 2026
5 checks passed
@teng-lin
teng-lin deleted the feature/cookie-file branch February 21, 2026 20:19
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