curl Cookies: How to Send, Store, and Reuse Sessions Safely
Web Data Collection Specialist
TL;DR:
- A curl cookie can be sent directly with
-b, but a cookie jar is safer for a multi-request session. The jar lets curl apply expiry, domain, path, and transport rules instead of rebuilding aCookieheader by hand. -cwrites cookies received fromSet-Cookie;-breads cookies for the next request. Use both options when a script must update and reuse the same jar.- Cookie files are credentials. Store them outside source control, limit file permissions, redact values from logs, and remove them when the authorized workflow ends.
- curl does not execute client-side JavaScript or complete interactive MFA and passkey ceremonies. Those flows need an approved browser session and a human-controlled authentication boundary.
- Scrapeless Scraping Browser can continue a browser-only workflow after curl reaches its limit. It provides a fresh cloud browser session; your application still owns authorization and credential handling.
- Free to start. New Scrapeless accounts include free Scraping Browser runtime — sign up at app.scrapeless.com.
Introduction: Cookies Turn Separate HTTP Requests Into a Session
HTTP requests are independent until the server and client agree on state. A response can set a cookie, and a later request can return that cookie to the matching host and path. That small exchange is how many applications preserve preferences, anonymous carts, consent state, and authorized sessions.
curl includes a cookie engine for exactly this job. The official curl HTTP scripting guide documents both literal cookie strings and persistent jars, while the HTTP state-management specification defines the server and user-agent behavior behind them.
This guide uses a public test endpoint and curl 8.7.1 to send, capture, store, inspect, and reuse non-sensitive demonstration cookies. It then draws a hard line between an HTTP session and browser-only authentication.
What Is a curl Cookie?
A curl cookie is a name-value pair that curl places in the HTTP Cookie request header after applying its cookie-engine rules.
There are two ways to supply one:
| Method | Best fit | Main tradeoff |
|---|---|---|
Literal string with --cookie / -b |
One controlled request with known non-sensitive values | You own every value and matching decision |
Cookie file with --cookie / -b |
A session carried between commands | The file becomes credential material |
Cookie jar written with --cookie-jar / -c |
A server-driven multi-step flow | The jar must be protected and cleaned up |
The response direction is different. A server sends Set-Cookie; curl evaluates the attributes and records eligible cookies in memory or in a jar. The Set-Cookie header reference describes attributes such as Domain, Path, Expires, Max-Age, Secure, HttpOnly, and SameSite.
Send Cookies With -b
-b is the short form of --cookie. When its argument contains an equals sign, curl treats the value as cookie data rather than a filename.
bash
curl --silent \
--cookie "theme=dark; view=compact" \
https://httpbingo.org/cookies
The public endpoint echoes the cookies it received:
json
{
"cookies": {
"theme": "dark",
"view": "compact"
}
}
Literal values are convenient for harmless preferences. Do not put a real session identifier on a shared command line: shell history, process inspection, terminal recordings, and CI logs can all expose it.
Read Set-Cookie Without Mixing It Into the Body
Set-Cookie is a response header, so inspect it separately from the response body. --dump-header - writes headers to standard output, and --output /dev/null discards the body.
bash
curl --silent \
--dump-header - \
--output /dev/null \
"https://httpbingo.org/cookies/set?theme=dark"
The live response returned an HTTP redirect and this header:
text
set-cookie: theme=dark; Path=/; HttpOnly; Secure
HttpOnly prevents browser JavaScript from reading the value; it does not stop an HTTP client from storing and sending the cookie. Secure limits transmission to secure transport. Neither attribute turns the cookie into a permission grant—the server still decides what the session may access.
Write and Reuse a Cookie Jar
A cookie jar preserves the server's attributes in the Netscape cookie-file format. Use -c on the response that sets state, then -b on the request that needs it.
bash
COOKIE_JAR="$(mktemp)"
chmod 600 "$COOKIE_JAR"
curl --silent --location \
--cookie-jar "$COOKIE_JAR" \
"https://httpbingo.org/cookies/set?demo_session=authorized" \
--output /dev/null
curl --silent \
--cookie "$COOKIE_JAR" \
https://httpbingo.org/cookies
The second command returned:
json
{
"cookies": {
"demo_session": "authorized"
}
}
When the server may update the session, read and write the same file:
bash
curl --silent --location \
--cookie "$COOKIE_JAR" \
--cookie-jar "$COOKIE_JAR" \
https://httpbingo.org/cookies
The jar is written when the transfer completes. Keep it on a private filesystem and remove it after the authorized job.
Start Scraping with Scrapeless
Power up your web scraping and automation workflow with Scrapeless!
Sign up today and get $5 in free credit — no credit card required.Claim your free credit now in the Scrapeless Dashboard.
Multiple Cookies and Domain/Path Rules
The cookie engine sends only cookies whose scope matches the request. A jar line records the domain, whether subdomains are included, the path, the Secure flag, expiry, name, and value.
The captured public test cookie looked like this:
text
#HttpOnly_httpbingo.org FALSE / TRUE 0 demo_session authorized
The #HttpOnly_ prefix is curl's file-format marker for an HttpOnly cookie. FALSE means the domain does not include subdomains, / is the matching path, TRUE marks Secure transport, and 0 represents a session cookie with no persistent expiry timestamp.
Do not broaden a domain or path to make a request work. Scope is a security boundary. A cookie for one application host should not be copied to an unrelated host, and a path-restricted cookie should remain path-restricted.
Secure, HttpOnly, and SameSite
Cookie attributes answer different questions, so treat them independently.
| Attribute | What it controls | curl implication |
|---|---|---|
Secure |
Whether the cookie travels over secure transport | curl will not send it over plain HTTP |
HttpOnly |
Whether browser JavaScript may read it | curl preserves the marker in its jar |
SameSite |
Whether a browser sends it in cross-site contexts | a command-line HTTP client does not reproduce a browser's full site-context model |
Domain |
Which host scope can receive it | curl matches the request host |
Path |
Which URL paths can receive it | curl matches the request path |
For authorized sessions, follow the OWASP session-management controls: protect identifiers at rest and in transit, rotate them through the application, and make termination effective server-side.
Debug the Cookie Header Without Leaking It
--verbose shows outgoing request headers, including Cookie. That makes it useful and dangerous.
Use verbose output only in a private local terminal with demonstration values. In shared logs, confirm names and scope from the jar while redacting values:
bash
awk 'BEGIN { FS="\t" } !/^#/ && NF >= 7 { print $1, $3, $6, "[REDACTED]" }' "$COOKIE_JAR"
If the server returns 401, first confirm that curl selected the expected cookie for the host and path. If the server returns 403, the session may be authenticated but not authorized for that resource. Neither status justifies changing account scope or copying another user's session.
When curl Is Not Enough
curl is an HTTP client, not a browser runtime. It does not execute client-side JavaScript, render a login widget, satisfy a passkey ceremony, or let a person approve an MFA prompt.
Browser-only flows also depend on state beyond cookies: origin storage, service workers, JavaScript-generated requests, device-bound credentials, and interactive redirects. Reconstructing only the Cookie header can therefore produce an incomplete or invalid session.
Use curl for documented HTTP flows and controlled APIs. Use an approved browser session when the application requires browser behavior.
Continue the Workflow With Scrapeless
Scrapeless Scraping Browser provides a cloud browser for JavaScript-rendered and interactive workflows. It does not convert an unauthorized curl cookie into access.
The safe handoff is a fresh session: create the cloud browser, let an authorized operator complete any required login or MFA boundary, then keep the approved work inside that session. The exact SDK connection requires your Scrapeless API key.
Note: The following block requires
SCRAPELESS_API_KEYand an authorized target. The local verification environment confirmed the installed SDK interface but did not run an authenticated cloud session.
javascript
import { Playwright } from "@scrapeless-ai/sdk";
const browser = await Playwright.connect({
apiKey: process.env.SCRAPELESS_API_KEY,
sessionTTL: 300,
proxyCountry: "US",
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto("https://app.example.com/login", {
waitUntil: "domcontentloaded",
});
// An authorized operator completes any login, MFA, or passkey step here.
// Continue only within the account and scope approved for the workflow.
await browser.close();
The Scrapeless Scraping Browser page explains the managed browser boundary. Check Scrapeless pricing, keep the SDK aligned with the Scrapeless documentation, and use the Puppeteer download workflow when the browser must produce a file rather than an HTTP response body.
Conclusion: Keep Session State Deliberate
curl cookies are predictable when you separate the flow into receive, store, match, send, and destroy. Use -c to capture server state, -b to reuse it, and a private jar when more than one command participates.
When the workflow crosses into JavaScript, interactive authentication, or browser-bound credentials, stop treating the session as a header exercise. Create an approved browser session and keep its scope explicit.
Ready to Build a Safer Browser Workflow?
Join our community to compare session-handling patterns with developers building authorized automation: Discord · Telegram.
Sign up at app.scrapeless.com for free Scraping Browser runtime and move browser-only steps into a managed session.
FAQ
Q: What does curl -b do?
curl -b enables the cookie engine and supplies either a literal cookie string or a cookie file for the request.
Q: What does curl -c do?
curl -c writes eligible cookies to a cookie jar when the transfer completes. Pair it with -b when the same file must be read and updated.
Q: Is a curl cookie jar safe to commit?
No. A cookie jar can contain active session credentials and should stay outside source control with restrictive filesystem permissions.
Q: Why is curl not sending a cookie from the jar?
The cookie may be expired or may not match the request's domain, path, or secure-transport requirements. Inspect those attributes without printing the value.
Q: Can curl complete MFA or a passkey login?
No. Interactive MFA and passkey ceremonies require a browser and, often, an authorized person to approve the step.
Q: Can Scrapeless import every curl cookie jar?
No. Browser sessions can depend on more than cookies, so the safe general pattern is to start a fresh authorized browser session and complete required authentication inside it.
Q: How much concurrency should a session workflow use?
Keep no more than three workers per host until the application's owner approves a different limit, and isolate each worker's session state.
At Scrapeless, we only access publicly available data while strictly complying with applicable laws, regulations, and website privacy policies. The content in this blog is for demonstration purposes only and does not involve any illegal or infringing activities. We make no guarantees and disclaim all liability for the use of information from this blog or third-party links. Before engaging in any scraping activities, consult your legal advisor and review the target website's terms of service or obtain the necessary permissions.




