Skip to main content




En la lección de hoy vamos a comenzar con la más básica, la autenticación HTTP básica, continuaremos con las cookies y los tokens , y terminaremos con firmas y contraseñas de un solo uso. Sigue leyendo para que aprendas todo acerca de esto.

HTTP basic authentication

The HTTP authentication básica es un método para que el client proporcione un nombre de Username y una contraseña al realizar una solicitud.

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 === 'juan' && pass === 'secreta') {
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, si un sitio Web utiliza un cifrado débil o un atacante puede romperlo,
  • 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

Cuando un server recibe una solicitud HTTP en la respuesta, puede enviar un encabezado Set-Cookie. The browser lo coloca en un contenedor de cookies, y la cookie se enviará junto con cada solicitud realizada al mismo origen en el encabezado Cookie HTTP.

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.

Más adelante, todas las solicitudes utilizan las cookies establecidas para el domain dado:

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: que contiene el tipo de token y el algorithm de hash
  • Useful load: containing the claims.
  • Firm: que puede calcularse de la siguiente manera si elige 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:

Si está escribiendo API para aplicaciones móviles nativas o SPA, JWT puede ser una buena opción para ti. Una cosa a tener en cuenta: para usar JWT en el navegador, debe almacenarlo en LocalStorage or SessionStorage, which can lead to XSS attacks.

The cons:

  • Need to go the extra mile to mitigate XSS attacks

Firms

Ya be utilizando cookies o tokens, si la capa de transporte por cualquier motivo queda expuesta, sus credenciales son fáciles de acceder, y con un token o cookie el atacante puede actuar como el usuario real.

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
  • Headers HTTP
  • 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.

¿Por qué pasar por todos estos pasos? Porque incluso si la capa de transporte se ve comprometida, un atacante solo puede leer su traffic, no podrá actuar como usuario, ya que el atacante no podrá firmar solicitudes, ya que la clave privada no está en su poder. La mayoría de los servicios de AWS están utilizando este tipo de autenticación.

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.