QA TestingcURLSecurityQA TestingBug ReportsDeveloper Tools

How to Remove Secrets From a cURL Command Before You Share It

“Can you send me the cURL?” is one of the most common questions in any bug triage. It is also one of the easiest ways to leak a production token. Copy as cURL captures the exact request your browser sent, including the credentials that let anyone replay it as you.

This guide shows what a copied cURL command really contains, why redacting it by hand keeps failing, and how to sanitize it in a few seconds with the free cURL Secret Scrubber, which runs locally in your browser.

October 16, 20269 min readBy MockFlow Team

What Copy as cURL Actually Leaks

Chrome, Edge, and Firefox all offer Copy as cURL in the Network tab. It is the fastest way to turn a failing request into something a teammate can run. The browser does not filter anything out, so a single copied command typically includes:

  • The Authorization header — a live Bearer token, often a JWT that is valid for an hour or more.
  • Every cookie for the domain — session IDs, CSRF tokens, refresh tokens, and analytics IDs, all in one Cookie header.
  • API keys in headers or the URL — x-api-key, ?api_key=, ?access_token=.
  • The request body — login forms with passwords, payment payloads, or JSON with client_secret and refresh_token fields.
  • Basic auth — --user name:password or credentials embedded in the URL as https://user:pass@host.

A bearer token is exactly what the name says: whoever bears it is treated as you. Pasting it into a ticket hands that access to everyone who can read the ticket, for as long as the token is valid.

Where cURL Commands End Up

cURL commands rarely stay in one place. A command copied for a quick question often travels through:

  • Jira, Linear, or Azure DevOps bug reports that the whole company can search.
  • Slack and Teams threads, including shared channels with vendors and contractors.
  • GitHub issues and pull request comments, sometimes on public repositories.
  • Vendor support tickets, where the data is stored on a third-party system.
  • AI chat assistants, where the prompt may be logged or retained.
  • Stack Overflow questions and internal wikis that get indexed and cached.

Each of these keeps history. Deleting the message later does not undo notifications, email digests, search indexes, or exports. That is why the safe default is to scrub before you paste, not after.

Why Manual Redaction Keeps Failing

Most people redact by hand: find the Authorization header, replace the token with xxx, and send. It works until it does not. Secrets hide in more places than one header:

  • A 4 KB cookie header where the session cookie is the ninth value.
  • An API key in the query string, far to the right of a long URL.
  • A password field nested three levels deep inside a minified --data-raw JSON body.
  • A token in a custom header like x-auth-token that you did not know the app sends.
  • Shell syntax such as $(...)that a careless edit can turn into a command that runs on someone else's machine.

Hand-editing also breaks quoting. Remove the wrong apostrophe and the command no longer runs, so the teammate asks for “the original” and the unsanitized version gets sent anyway.

How to Sanitize a cURL Command in 4 Steps

  1. Copy the request as cURL. In Chrome DevTools, open the Network tab, right-click the request, and choose Copy > Copy as cURL (bash) or Copy as cURL (cmd).
  2. Paste it into the cURL Secret Scrubber. Open the MockFlow cURL Secret Scrubber and paste the command into the Original cURL box. Nothing is uploaded.
  3. Scrub secrets. Click Scrub secrets. Authorization headers, cookies, API keys, sensitive query parameters, and sensitive JSON fields are replaced with placeholders such as [REDACTED_AUTH].
  4. Review the removal list and copy. Read the sanitized command and the What was removed table, check for custom secret fields, then copy the sanitized cURL into your bug report or chat.

The scrubber parses the command the way a shell would, so quoting and line continuations survive. Only the secret values change, and the output is still a valid cURL command.

Before and After: A Real Example

Here is a typical command copied from DevTools. It carries an API key in the URL, a bearer token, a session cookie, and a password in the JSON body:

curl 'https://api.example.com/v1/orders?limit=20&api_key=sk_live_51HxExampleKey' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N' \
  -H 'Cookie: session=8f3a9c2e7b; theme=light' \
  --data-raw '{"email":"qa@example.com","password":"hunter2","order":{"id":42,"note":"retry"}}'

After one click in the scrubber:

curl 'https://api.example.com/v1/orders?limit=20&api_key=[REDACTED_TOKEN]' \
  -H 'Accept: application/json' \
  -H 'Authorization: [REDACTED_AUTH]' \
  -H 'Cookie: session=[REDACTED_COOKIE]; theme=[REDACTED_COOKIE]' \
  --data-raw '{"email":"qa@example.com","password":"[REDACTED_TOKEN]","order":{"id":42,"note":"retry"}}'

The endpoint, method, headers, and the order payload are all still there, which is what the person debugging needs. Cookie names stay visible so they can see which cookies the request depended on. Next to the output, the tool lists every replacement with its location and reason, for example Query api_key — Sensitive query parameter or JSON body password — Sensitive JSON field.

What the cURL Secret Scrubber Redacts

  • Credential headers — Authorization, Proxy-Authorization, X-API-Key, X-Auth-Token, CSRF and XSRF tokens, and AWS security tokens.
  • Cookies — every value in Cookie, Set-Cookie, and -b, with names left visible.
  • User credentials — -u, --user, --proxy-user, and user:pass@ in URLs.
  • Query parameters and form fields — names like token, access_token, api_key, password, signature, and session.
  • JSON body fields — sensitive keys at any depth, including client_secret, refresh_token, private_key, and connection_string.
  • Token-shaped values anywhere — JWTs, Bearer and Basic credentials, Stripe keys (sk_live_), GitHub tokens (ghp_, github_pat_), Slack tokens (xoxb-), AWS access key IDs, Google API keys, and GitLab tokens, even when the field name looks harmless.

It also refuses to guess when guessing is unsafe. Bodies it cannot parse are removed instead of partially scrubbed, @file references and --config files are not read, and shell substitutions are replaced with [NOT_EXECUTED] so the shared command cannot run anything unexpected.

Why It Runs in Your Browser

A secret scrubber that uploads your command to a server has the same problem it is supposed to solve: your token now lives on someone else's machine. The MockFlow scrubber is built the other way around:

  • The command is parsed in your browser tab. No API request carries it anywhere.
  • It is not written to local storage, cookies, or analytics events.
  • The command is never executed, and the URL inside it is never contacted.
  • Commands up to 256 KiB are supported, enough for large JSON bodies.

That makes it usable in teams with strict data handling rules, where pasting a production request into a random online formatter would not be allowed.

Workflow for QA Engineers: Safer Bug Reports

A good API bug report includes the exact request, the response, and the expected result. The cURL command is the most reproducible part, so make it a standard step:

  1. Reproduce the bug with DevTools open on the Network tab.
  2. Copy the failing request as cURL and scrub it.
  3. Paste the sanitized cURL into the ticket, along with the status code and response body. Use the JSON Formatter to make the response readable.
  4. Note which test account was used, so the developer can supply their own token.

This also keeps test environments clean. Staging tokens often have broader access than anyone expects, and shared QA accounts are a common source of leaked sessions. For more on structuring API checks, see the API testing checklist for frontend teams.

Workflow for Developers: Support Tickets, PRs, and AI

Developers share requests with more audiences than QA does, and many of them sit outside the company:

  • Vendor support — Stripe, Auth0, or a cloud provider asks for the failing request. Send the scrubbed version and the request ID instead of your live key.
  • Pull requests and issues — reproduction steps in a PR description should never contain a real session.
  • AI coding assistants — scrub before you paste a request into a chat prompt, especially when it was copied from production.
  • Mock APIs and fixtures — when you turn a real request into a test fixture or a mock API, start from the scrubbed command so credentials never land in the repo.

If the bearer token is a JWT and you only need to show its claims, inspect it in the JWT Decoder and share the decoded payload without the signature. For webhook payloads, capture them with a request catcher and replay the HTTP request instead of passing raw commands around.

Review Checklist Before You Share

Automatic detection removes the common cases. It works from known names and token shapes, so a custom field can still slip through, and a harmless field named key may be redacted. Take ten seconds to check:

  • Does any custom header carry an internal signature or tenant secret?
  • Does the URL path contain an ID or token, such as a password reset link?
  • Is there personal data (emails, phone numbers, addresses) you should also mask?
  • Did the tool show a warning about a body it could not inspect?
  • If you already shared an unsanitized command, did you revoke that token?

FAQ

Is it safe to share a cURL command from Chrome DevTools?

Not as copied. Copy as cURL includes the live Authorization header, every cookie for the domain, and the full request body. Anyone who receives it can usually replay the request as you until the token or session expires. Scrub the command before you share it.

How do I remove an API key or bearer token from a cURL command?

Paste the command into the MockFlow cURL Secret Scrubber and click Scrub secrets. It replaces Authorization and API key headers, cookie values, --user credentials, URL userinfo, sensitive query parameters, and sensitive JSON fields with placeholders, while keeping the rest of the command intact.

Does the cURL Secret Scrubber upload or run my command?

No. Scrubbing runs entirely in your browser. The command is not sent to a server, stored, logged, or executed, and shell substitutions such as $(...) are replaced instead of evaluated.

Will the sanitized cURL command still work?

The structure stays the same: URL, method, headers, and body are all there. Replace each placeholder with your own test credential and the request runs again, which is what a teammate needs to reproduce a bug.

Can an automatic scrubber miss a secret?

Yes. Detection is based on known header names, field names, and token shapes, so a custom field like x-internal-sig-v2 can pass through. Always read the removal list and the output before sharing.

Should I rotate a token that was already shared?

Yes. If an unsanitized cURL command was posted in a ticket, chat, or public issue, treat the token or session as exposed. Revoke it or log out of that session, then share a scrubbed version instead.

Scrub your next cURL command before you paste it

Free, local, and built for bug reports. Paste a Copy as cURL command, remove the tokens, cookies, and API keys, and share a request your team can still run.