Skip to main content

In today's lesson we are going to start with the most basic, basic HTTP authentication, continue with cookies and tokens, and end with one-time signatures and passwords. Read on to learn all about this.

HTTP basic authentication

The HTTP authentication basic is a method for the customer to provide a username and password when making a request.

This is the simplest possible way to enforce access control, as it does not require cookies, sessions, or anything else. To use this, the client must send the Authorization along with every request you make. The name of Username and the password they are not encrypted, but they are constructed like this:

The username and password are concatenated into a single string: username: password this string is Base64 encoded

The key word BASIC is placed before this hardcoded value

Example for a user named juan with a secret password:

curl --header "Authorization: Basic am9objpzZWNyZXQ =" my-website.com

Implementing it is pretty easy in Node.js too - the following code snippet shows how you can make a Express middleware to do it.

import basicAuth from 'basic-auth'; function unauthorized (res) {res.set ('WWW-Authenticate', 'Basic realm = Authorization Required'); return res.send (401); }; export default function auth (req, res, next) {const {name, pass} = basicAuth (req) || {}; if (! name ||! pass) {return unauthorized (res); }; if (name === 'john' && pass === 'secret') {return next (); } return unauthorized (res); };

Of course, you can do it at a higher level, like in nginx.

Sounds simple, right? So what are the downsides of using HTTP Basic Authentication?

The cons:

  • The username and password are sent with every request, potentially exposing them, even if they are sent over a secure connection connected to SSL / TLS, if a website uses weak encryption or an attacker can break it,
  • Usernames and passwords will be exposed immediately there is no way to log out the user using basic authentication, the expiration of credentials is not trivial - you have to ask the user to change the password to do so.

cookies

When a server receives an HTTP request in the response, it can send a header Set-Cookie. The browser places it in a cookie container, and the cookie will be sent along with each request made to the same origin in the HTTP Cookie header.

To use cookies for authentication purposes, there are a few key principles that must be followed.

Always use HttpOnly cookies

To mitigate the possibility of XSS attacks, always use the flag HttpOnly when setting cookies. This way they will not appear in document.cookies.

Always use signed cookies

With signed cookies, a server can tell if the client modified a cookie.

Later, all requests use the cookies set for the given domain:

Use of Chrome cookies

The cons:

  • Need to go the extra mile to mitigate CSRF attacks
  • Incompatibility with REST as it introduces a state into a stateless protocol

Records

Today, JWT (JSON Web Token) is everywhere; the potential security issues are worth a look though.

JWT consists of three parts:

  • Header: containing the token type and hashing algorithm
  • Useful load: containing the claims.
  • Firm: which can be calculated as follows if you choose HMAC SHA256: HMACSHA256 (base64UrlEncode (header) + "." + base64UrlEncode (payload), secret)

Add JWT to applications Koa it's just a couple of lines of code:

var koa = require ('koa'); var jwt = require ('koa-jwt'); var app = koa (); app.use (jwt ({secret: 'very-secret'})); // Protected middleware app.use (function * () {// the content of the token will be available in this.state.user this.body = {secret: '42'};});

Example of use:

curl --header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRJONYQDXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiOWRJONYQRG9lIiwiYWRJONW4OrZOrZBrsiteBuyWRJONW4GRG9lIiwiYWRJONY7MyGsiteBuyByWRtaW4GRG9lIiwiYWRJONW4OrZOrZSiteBuyWRTaW4gRG9lIiwiYWRJONW4OrZOrZSiWo9WRTaW4Gsite

Like the previous ones, the tokens can also be observed in Chrome:

If you are writing API for native mobile apps or SPA, JWT may be a good choice for you. One thing to note: to use JWT in the browser, you have to store it in LocalStorage or SessionStorage, which can lead to XSS attacks.

The cons:

  • Need to go the extra mile to mitigate XSS attacks

Firms

Whether using cookies or tokens, if the transport layer is exposed for any reason, your credentials are easy to access, and with a token or cookie the attacker can act like the real user.

One possible way to solve this, at least when it comes to the API and not the browser, is to sign every request. How can we do it?

When a consumer of an API makes a request, they must sign it, which means they must create a hash of the entire request using a private key. For that hash calculation you can use:

  • HTTP method
  • Request path
  • HTTP headers
  • HTTP payload checksum
  • and a private key to create the hash

For this to work, both the API consumer and the provider must have the same private key. Once you have the signature, you need to add it to the request, either in query strings or HTTP headers. In addition, a date must also be added, so that you can define an expiration date.

Why go through all these steps? Because even if the transport layer is compromised, an attacker can only read your traffic, he will not be able to act as a user, since the attacker will not be able to sign requests, since the private key is not in his possession. Most AWS services are using this type of authentication.

node-http-signature deals with HTTP request signing and is worth checking out.

The cons:

  • Cannot be used in browser / client, only between APIs

One-time passwords

One-time password algorithms generate a one-time password with a shared secret and the current time or counter:

  • One-time password algorithm time based, is based on the current time.
  • One-time password algorithm based on HMAC, is based on a counter.

These methods are used in applications that take advantage of two-factor authentication: a user enters the username and password, and both the server and the client generate a one-time password.

In Node.js, implement this using notp it is relatively easy.

Cons:

  • With shared secret user tokens (if stolen) they can be emulated
  • because clients can be stolen, all real-time applications have methods to avoid this, such as an email reset that adds additional attack vectors to the application
Which web authentication method to choose when?

If you only have to support one web application, cookies or tokens are fine. For cookies, think of XSRF, so JWT takes care of XSS.

If you have to support a web app and mobile client, use an API that supports token-based authentication.

If you are creating APIs that communicate with each other, better use request signing.

R Marketing Digital