Skip to content

Application uses Basic Authentication

CWE-522CWE-319OWASP A07:2021Updated September 4, 20264 min read

With Basic Authentication the browser sends the username and password with every request, encoded but not encrypted. The password is therefore easy to read back, is repeated endlessly over the wire, cannot be revoked without changing it, and leaves no room for a second factor or a proper logout.

Basic Authentication is one of the oldest parts of HTTP and still in use: it can be set up with a single line of configuration and works everywhere. That simplicity is exactly what makes it unsuitable for a modern application, because it contains no provision at all for what we now expect from authentication. That deserves an explanation.

What is Basic Authentication?

With HTTP Basic Authentication the client sends the username and password in a header, joined by a colon and then encoded in base64. The server decodes that, checks the combination and decides. The browser then remembers the credentials for the rest of the session and sends them again automatically with every subsequent request.

The most common misunderstanding concerns that encoding. Base64 is not encryption but a way to put data into a text format; reversing it is a fraction-of-a-second operation requiring no key at all. Basic am9objpQNHNzdzByZCE= is nothing other than john:P4ssw0rd! in a different notation.

A letter written in block capitals is no more secret than the same letter in cursive. The form differs, the legibility does not.

Why is Basic Authentication unsuitable?

Vulnerable:

GET /admin/reports HTTP/1.1
Host: portal.example
Authorization: Basic am9objpQNHNzdzByZCE=

This header travels with every request: with every page, every image, every API call. That is a fundamental difference from a session cookie, which is a temporary reference to a session on the server. Here the password itself travels, hundreds of times per visit.

That magnifies every form of exposure. If one request goes over an unencrypted connection, the password is out in the open. If the header lands in a proxy log file or an error report, the password is in there. And if an intermediate system stores it for troubleshooting, it sits there too.

Beyond that, everything you need to manage authentication is missing. No second factor is possible. There is no session that can expire. There is no way to withdraw access without changing the password. There is no proper logout, because the browser keeps sending the credentials. And because every request is a full login attempt, limiting the number of attempts is awkward.

Safe:

// A real login flow with a session
app.post('/login', async (req, res) => {
  const user = await checkCredentials(req.body);
  if (!user) return res.status(401).send('Invalid credentials');

  if (user.mfaEnabled) {
    req.session.secondFactorFor = user.id;
    return res.redirect('/login/verify');
  }
  req.session.regenerate(() => {
    req.session.userId = user.id;
    res.cookie('__Host-sid', req.sessionID, {
      httpOnly: true, secure: true, sameSite: 'strict', path: '/',
      maxAge: 30 * 60 * 1000,
    });
    res.redirect('/');
  });
});

The password now crosses the wire exactly once, at login. After that a session reference travels which expires, which you can revoke, which permits a second factor, and which is destroyed on logout. For machine connections, use a token or an API key you can rotate without changing anyone’s password.

If you encounter Basic Authentication on an admin interface, check whether the password has ever been changed. The combination of this method with default or shared credentials is a classic finding, and its consequences are usually more serious than the use of the method itself.

What is the impact of Basic Authentication?

The severity runs from medium to high, with the presence of TLS the most decisive factor. Without encryption the risk is immediate: anyone on the network path reads the password, and because it travels with every request, one intercepted request is enough.

With TLS the biggest risk is gone, but the management issues remain. Without a second factor, access rests entirely on the password, and that password may have leaked elsewhere. Without a revocation option, an employee keeps access until someone changes the password. Without a session there is no timeout, so an unattended browser retains access. And without a logout the user cannot end that situation themselves.

There is a further aspect that is often underestimated: because the password travels with every request, it ends up in many more places than you expect. Proxy logs, monitoring systems, error reports and network captures all then contain the header, and thus the password in a form anyone can read back.

How do you detect Basic Authentication?

Its presence is immediately visible: a response with 401 and a WWW-Authenticate: Basic header, or a browser dialog asking for a username and password instead of a login page within the application itself.

Then the circumstances are examined. Is the connection forced over TLS, or is the service reachable over HTTP as well? Have the credentials been changed from the default? Are they shared between several people, which makes attribution impossible? Is the number of attempts limited? A tester also checks whether Basic Authentication exists alongside a modern login flow: an application with a proper login page plus an API or admin path using Basic is a common pattern, where that second path bypasses the second factor. AssistSec assesses whether the use is defensible for the application in question, because an internal connection over TLS is a different matter from an admin interface for people.

How do you prevent Basic Authentication?

  • Replace Basic Authentication for users with a login flow using session management and cookies.
  • Enforce TLS while the method is still in use, and block every unencrypted route.
  • Use a token or API key you can rotate for machine connections.
  • Change default credentials and never use shared accounts for people.
  • Make sure a second factor is possible; that nearly always requires a different method.
  • Filter the Authorization header out of log files, monitoring and error reports.
  • Limit the number of login attempts, even with a method that authenticates per request.
  • Check that no second channel using Basic exists alongside your modern login flow.
  • Shield admin interfaces at network level rather than with a password alone.

Sources

Frequently asked questions

Is Basic Authentication over HTTPS acceptable?

The biggest risk, being read on the network, is then removed, and for a shielded internal service it can be acceptable. The other objections remain: the password travels with every request, there is no second factor, no logout, and no way to withdraw access without changing the password.

What is the difference with Digest Authentication?

Digest sends not the password but a derived value, which is better, but it uses outdated cryptography and has its own limitations. It is no longer a recommended choice; opt for a session with cookies or for tokens.

How do you log out with Basic Authentication?

That is precisely the problem: there is no clean way. The browser remembers the credentials for the duration of the session and sends them automatically. The usual workaround is forcing a request that fails, which is messy and behaves differently per browser.

May I use it for server-to-server traffic?

For an internal connection over TLS it is common and often acceptable, because the objections around logging out and a second factor do not apply there. Do use a long, randomly generated secret that you can rotate, and not a person's password.

Related articles

Press / to search · Esc