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.
References
• 015. Insecure Authentication Method - Basic