curl Cheatsheet

Cookies and Sessions

Use this curl reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Sending cookies

-b / --cookie takes either an inline name=value string or a path to a cookie file. curl decides by looking for an = sign, so a filename with no = is read as a file.

curl -b 'session=abc123' https://ex.com/dashboard
curl -b 'a=1; b=2' https://ex.com/                # semicolon separated
curl -b cookies.txt https://ex.com/dashboard      # read from a file
curl -b 'extra=1' -b cookies.txt https://ex.com/  # both, merged

Inline cookies are sent to every host in the invocation with no domain check, because you asked for them explicitly. Cookies loaded from a file respect the domain, path, and secure attributes recorded in it.

Saving cookies with -c

-c / --cookie-jar writes the cookies curl holds at the end of the run to a file in Netscape format. This is how you carry a session across two commands.

curl -c jar.txt -d 'user=ada&pass=s3cret' https://ex.com/login
curl -b jar.txt https://ex.com/dashboard
curl -b jar.txt -c jar.txt https://ex.com/next    # read and update

Pass both -b and -c with the same path when you want a persistent session, otherwise -c alone starts from an empty jar every time and overwrites what was there.

FlagEffect
-b <str|file>Load cookies to send
-c <file>Write the jar after the transfer, - for stdout
-j / --junk-session-cookiesDiscard session cookies from the loaded file
-b ""Turn the cookie engine on with no cookies
-b -Read the cookie file from stdin
curl -c - -s -o /dev/null https://example.com     # print the jar
curl -b '' -L https://ex.com/                     # engine on, no input
curl -b jar.txt -j https://ex.com/                # start a fresh session

A login flow in one process

Cookies are only carried between URLs inside a single curl invocation, or through a jar file between invocations. --next lets you do both requests in one process without touching disk.

curl -s -c jar.txt \
     -d 'user=ada' -d 'pass=s3cret' https://ex.com/login \
     --next -b jar.txt https://ex.com/api/me

With -L, cookies set by an intermediate 302 are kept and sent on the following hop, which is what makes a redirect-based login work.

curl -sL -c jar.txt -d 'user=ada&pass=s3cret' https://ex.com/login
curl -s -b jar.txt https://ex.com/api/me

CSRF tokens

Most session logins also require a token read out of the first page or a prior Set-Cookie. Fetch, extract, then post.

# 1. get the form, keep the session cookie
TOKEN=$(curl -s -c jar.txt https://ex.com/login \
        | grep -o 'name="csrf" value="[^"]*"' \
        | cut -d'"' -f4)

# 2. post with the cookie and the token
curl -s -b jar.txt -c jar.txt \
     -d "csrf=$TOKEN" -d 'user=ada' -d 'pass=s3cret' \
     https://ex.com/login

When the token arrives as a cookie rather than in the HTML, read it out of the jar instead.

TOKEN=$(awk '$6=="csrftoken"{print $7}' jar.txt)
curl -b jar.txt -H "X-CSRFToken: $TOKEN" -d 'a=1' https://ex.com/api/x

Gotchas

- -b and -c are easy to swap. -b is the input the request sends, -c is the output curl writes. Reversing them silently drops the session. - A Secure cookie is never sent over http://, so a local test against http://localhost will look like the cookie vanished. - Session cookies (expiry 0) are written to the jar only when the server sent them in that run. -j throws them away on load. - curl has no cookie storage by default. The engine turns on when -b names a file (or -b ""), or when -c is given. An inline -b 'a=1' alone does not enable it, so Set-Cookie is ignored even across -L hops. - The jar is written when the transfer completes. Kill curl mid-run and you get no file.