Passing credentials in a URL is a security risk you should avoid

When you put a username and password directly into a web address — like https://username:password@example.com — the credentials travel in plain sight through multiple systems. Your browser history stores them. Your internet service provider can see them. Any proxy or firewall between you and the server logs them. If someone gains access to your device, your browsing history, or your network traffic, they have your password in readable form.

This method works technically, which is why it exists in older systems and why people still ask about it. But "works" and "safe" are not the same thing. The standard practice in modern APIs is to send credentials in the request body or in a header, encrypted by HTTPS, rather than exposed in the URL itself.

Key Takeaways

  • URLs with embedded credentials appear in browser history, server logs, and network traffic in plain text, making them visible to anyone with access to those records.
  • HTTPS encryption protects the entire request — including headers and body — but does not hide the URL itself from intermediate systems.
  • HTTP Basic Authentication sends credentials in a header instead, which is safer but still requires HTTPS to prevent interception.
  • API tokens and OAuth are the modern standard because they let you revoke access without changing your password and limit what each token can do.
  • If you must use a legacy system that requires URL credentials, use a dedicated account with minimal permissions and rotate the password regularly.

How credentials in URLs actually get exposed

When you type https://user:pass@api.example.com/data into your browser or code, the URL appears in several places before it ever reaches the server. Your browser stores it in the history file on your hard drive. If you share the URL in an email or chat, it sits in those systems' logs. Proxy servers, firewalls, and load balancers between your device and the API server may log the full request, including the URL.

HTTPS encryption protects the content of your request — the body and headers — but it does not hide the URL itself. The URL is part of the initial connection handshake, which happens before encryption is fully established. Anyone monitoring network traffic at the right point can see the full address, credentials and all.

The risk is highest if you hardcode credentials into source code, configuration files, or scripts. If that code is ever committed to a repository, shared with a team member, or stored in a backup, the password is now in multiple places you cannot control.

HTTP Basic Authentication as a middle ground

HTTP Basic Authentication moves the credentials out of the URL and into the request header instead. The credentials are still sent as username and password, but they travel in the Authorization header rather than in the address bar. This keeps them out of browser history and URL logs.

The format looks like this: the server receives a header that says Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=, where the part after "Basic" is the username and password encoded in Base64 (a readable but not encrypted format). The encoding is not encryption — anyone who sees the header can decode it in seconds — but it does keep credentials out of URLs and makes them slightly less obvious to casual inspection.

Basic Authentication is safe only over HTTPS, because HTTPS encrypts the entire request including the header. If you use it over plain HTTP, the credentials are visible to anyone on the network. Most modern APIs require HTTPS for this reason, so if the server accepts Basic Authentication at all, it should force HTTPS.

Why API tokens and OAuth are the modern standard

Instead of sending your actual password to every API call, modern systems use API tokens or OAuth. You log in once with your real password, the server issues you a token (a long random string), and you send that token with each request instead of your password.

This approach has several advantages. If a token is compromised, you can revoke it without changing your password. You can issue different tokens for different purposes — one for reading data, another for writing, another for a specific process — and limit what each one can do. If a developer leaves your team, you delete their token without affecting anyone else's access. If a token is accidentally committed to a repository, you can rotate it without forcing everyone to update their passwords.

OAuth is a standard protocol that many large services use (Google, GitHub, Twitter). It involves redirecting the user to log in on the service's own website, then receiving a token to use in your process. This way your process never sees the user's actual password at all.

How to send credentials safely in an API request

The safest method depends on what the API supports. Check the API documentation first — it will tell you the expected format.

For HTTP Basic Authentication, encode your username and password in Base64 and send them in the Authorization header. In most programming languages, the HTTP library handles this for you. In Python with the requests library, you write: requests.get(url, auth=('username', 'password')). The library encodes the credentials and adds the header automatically. In JavaScript with fetch, you add the header manually: headers: { 'Authorization': 'Basic ' + btoa('username:password') }.

For API tokens, the server usually specifies where to send it. Common patterns are Authorization: Bearer token_value or X-API-Key: token_value. The documentation will say which. You send it the same way as Basic Authentication — in a request header, never in the URL.

For OAuth, you follow the service's login flow, which usually involves redirecting the user to a login page and handling the response. The details vary by service, but the principle is the same: you never handle the user's password directly.

If you must use credentials in a URL

Some legacy systems or internal tools may require credentials in the URL because they were built before modern standards existed. If you have no choice, follow these rules to reduce the damage.

First, create a dedicated account with the minimum permissions it needs. If the API only needs to read data, the account should have read-only access. If it only needs to access one resource, restrict it to that resource. This way, if the credentials are compromised, the attacker cannot access everything.

Second, rotate the password regularly — at least every 90 days, more often if possible. If you discover the credentials were exposed, change the password when ready.

Third, never commit the URL to source code or configuration files. Store it in an environment variable or a secrets management system that your code reads at runtime. This keeps the credentials out of version control and backups.

Fourth, use HTTPS without exception. If the server offers both HTTP and HTTPS, always use HTTPS. If it only offers HTTP, that is a sign the system is not designed for sensitive data.

What to do if credentials are already exposed

If you realize you have shared a URL with embedded credentials — in a commit message, an email, a support ticket, or anywhere else — treat it as a password breach. Change the password when ready. If it was a dedicated account, delete the account. If it was your main account, change your password and review what access the account had.

Check your API logs or server logs to see if anyone used those credentials after they were exposed. Most API platforms let you view request history by IP address or timestamp. If you see suspicious activity, investigate further or contact your security team.

If the credentials were in a Git repository, they are now in the repository history even if you delete the file. You cannot straightforward remove them from a commit. You have to rewrite the repository history using tools like git filter-branch or BFG Repo-Cleaner, which is disruptive for teams. This is why preventing the exposure in the first place — by using environment variables and secrets management — is so much easier than cleaning it up afterward.

Frequently Asked Questions

Does HTTPS hide the username and password in the URL?

HTTPS encrypts the request body and headers, but the URL itself is part of the connection handshake that happens before full encryption. Intermediate systems like proxies and firewalls can see the URL. HTTPS prevents casual eavesdropping on the network, but it does not hide the URL from your browser history, server logs, or the systems between you and the server.

Can I use a URL with credentials if I delete the browser history?

Deleting your browser history removes it from your device, but the URL has already been logged elsewhere — in your ISP's records, in proxy logs, in server access logs, and in any backups of those systems. Deleting local history does not erase those copies. The safer approach is to never put credentials in the URL in the first place.

What is the difference between Basic Authentication and Bearer tokens?

Basic Authentication sends your username and password (encoded but not encrypted) with every request. Bearer tokens send a long random string that the server issued to you. Tokens are safer because you can revoke them without changing your password, and you can issue different tokens with different permissions. Most modern APIs use tokens instead of Basic Authentication.

If I use an API token instead of a password, is it safe to put it in the URL?

No. Tokens should be sent in request headers, not in URLs, for the same reasons passwords should not be in URLs. Tokens in URLs appear in browser history, logs, and network traffic. Send tokens in the Authorization header or whatever header the API documentation specifies.

How do I know if an API supports OAuth?

Check the API documentation. It will have a section on authentication that lists the supported methods — usually Basic Authentication, API keys, Bearer tokens, or OAuth. If OAuth is available, the documentation will explain the login flow and how to handle the response. If the documentation does not mention OAuth, the API probably does not support it.