logo

Database

Insecure Authentication Method - Basic

Need

Securely authenticate user requests

Context

• Usage of Elixir (1.10 and above) for building scalable and fault-tolerant applications

• Usage of Phoenix Framework for building web applications

• Usage of Guardian library for JWT authentication

Description

1. Non compliant code

def login(conn, %{"username" => username, "password" => password}) do
  user = Repo.get_by(User, username: username)
  if user && Bcrypt.checkpw(password, user.password_hash) do
    {:ok, token, _claims} = BasicAuthToken.encode_and_sign(user.username)
    conn
    |> put_resp_header("authorization", "Basic #{token}")
    |> send_resp(:ok, "Logged in")
    send_resp(conn, :unauthorized, "Incorrect username or password")...

In the insecure code example, the server uses Basic Authentication, where the user credentials are Base64-encoded but not encrypted, and transmitted over the network. This can be easily decoded and allows an attacker to intercept the user's credentials.

2. Steps

• Implement Bearer authentication using hashed tokens instead of transmitting sensitive user credentials.

• Use HTTPS for all sensitive communications to prevent the interception of data.

• Consider other authentication mechanisms like OAuth or JWT for even better security.

3. Secure code example

def login(conn, %{"username" => username, "password" => password}) do
  user = Repo.get_by(User, username: username)
  if user && Bcrypt.checkpw(password, user.password_hash) do
    {:ok, jwt, _full_claims} = Guardian.encode_and_sign(user, :token)
    conn
    |> put_resp_header("authorization", "Bearer #{jwt}")
    |> send_resp(:ok, "Logged in")
    send_resp(conn, :unauthorized, "Incorrect username or password")...

In the secure code example, the server uses Bearer Authentication with a hashed token. The server generates a JWT token for the authenticated user and returns it in the Authorization header. This ensures the user's sensitive credentials are not transmitted over the network.