Insufficient data authenticity validation - Checksum verification
Need
To validate the integrity of resources loaded from external sources.
Context
- Usage of Elixir (1.12.0 and above) for building scalable and fault-tolerant applications
- Usage of HTTPoison for making HTTP requests
Description
Non compliant code
defmodule MyAppWeb.ExternalResourceController do
use MyAppWeb, :controller
def get_resource(conn, _) do
{:ok, response} = HTTPoison.get("https://external-server/resource")
send_resp(conn, 200, response.body)
end
end
This insecure code example fetches a resource from an external server and sends it to the client without verifying its integrity. An attacker could potentially tamper with the resource on the external server or during transmission, and the client would receive a compromised resource.
Steps
- Use a cryptographic hash function to generate a checksum for the original resource.
- Include the checksum alongside the resource when transmitting it.
- On the receiving end, generate a new checksum for the received resource and compare it with the original. If they match, the resource's integrity is confirmed.
Compliant code
defmodule MyAppWeb.ExternalResourceController do
use MyAppWeb, :controller
def get_resource(conn, _) do
{:ok, response} = HTTPoison.get("https://external-server/resource")
{:ok, checksum} = HTTPoison.get("https://external-server/resource_checksum")
if :crypto.hash(:sha256, response.body) == checksum.body do
send_resp(conn, 200, response.body)
else
send_resp(conn, 403, "Resource integrity compromised")
end
end
end
In the secure code example, the server fetches both the resource and its checksum from the external server. It then generates a new checksum for the received resource and compares it with the original. If the checksums match, the server sends the resource to the client. If not, it rejects the resource.