Non-encrypted Confidential Information - Credit Cards - Elixir

Non-encrypted Confidential Information - Credit Cards - Elixir

Need

Ensure that credit card information is encrypted both during transport and at rest.

Context

  • Usage of Elixir (1.12.0 and above) for building scalable and fault-tolerant applications
  • Usage of Plug (1.12.0 and above) for building composable web applications in Elixir
  • Usage of Plug.Crypto library (version 1.2.0 and above) for cryptographic operations

Description

Non compliant code

        defmodule MyAppWeb.PaymentController do
  use MyAppWeb, :controller

  def process_payment(conn, %{'card_number' => card_number, 'expiry_date' => expiry_date, 'cvv' => cvv}) do
    payment_successful = PaymentProcessor.process(card_number, expiry_date, cvv)
    if payment_successful do
      json(conn, %{status: 'success'})
    else
      json(conn, %{status: 'error'})
    end
  end
end
        
        

The code is insecure because it directly uses the credit card data without any form of encryption. This allows anyone who can intercept the data to have access to sensitive credit card information.

Steps

  • Install Plug.Crypto library to handle encryption and decryption of sensitive data.
  • Encrypt credit card data before sending it to the server.
  • Decrypt the data server-side before processing the payment.
  • Always use secure connections (HTTPS) to transport sensitive data.

Compliant code

        defmodule MyAppWeb.PaymentController do
  use MyAppWeb, :controller
  alias Plug.Crypto.KeyGenerator

  def process_payment(conn, %{'card_number' => enc_card_number, 'expiry_date' => enc_expiry_date, 'cvv' => enc_cvv}) do
    key = KeyGenerator.generate(conn.private.salt, conn.private.iteration)
    card_number = KeyGenerator.stream_decrypt(key, enc_card_number)
    expiry_date = KeyGenerator.stream_decrypt(key, enc_expiry_date)
    cvv = KeyGenerator.stream_decrypt(key, enc_cvv)
    payment_successful = PaymentProcessor.process(card_number, expiry_date, cvv)
    if payment_successful do
      json(conn, %{status: 'success'})
    else
      json(conn, %{status: 'error'})
    end
  end
end
        
        

The code is secure because it decrypts the encrypted credit card data on the server side before processing the payment, which means the credit card information is encrypted during transport.

References