You’d think request.headers
would contain an array of HTTP headers. However, in Rails this variable includes the entire rack environment.
Instead you’ll need to use a regex to filter out HTTP headers from the rest of the environment:
http_headers = request.env.select { |k, _v| k =~ /\A[A-Za-z0-9\-_]+\z/ }
Here’s the list of headers that will be included in the array:
SCRIPT_NAME
QUERY_STRING
SERVER_PROTOCOL
SERVER_SOFTWARE
GATEWAY_INTERFACE
REQUEST_METHOD
REQUEST_PATH
REQUEST_URI
HTTP_VERSION
HTTP_HOST
HTTP_CONNECTION
HTTP_DNT
HTTP_UPGRADE_INSECURE_REQUESTS
HTTP_USER_AGENT
HTTP_SEC_FETCH_USER
HTTP_ACCEPT
HTTP_SEC_FETCH_SITE
HTTP_SEC_FETCH_MODE
HTTP_ACCEPT_ENCODING
HTTP_ACCEPT_LANGUAGE
SERVER_NAME
SERVER_PORT
PATH_INFO
REMOTE_ADDR
ROUTES_70282879079520_SCRIPT_NAME
ORIGINAL_FULLPATH
ORIGINAL_SCRIPT_NAME
Actually, use request.filtered_env instead
The problem with request.env
is that it includes a field called RAW_POST_BODY
. The problem with this is particularly with login actions peformed by users.
The request.env['RAW_POST_BODY']
will include unobfuscated passwords, credit card data, API keys, anything. Whereas request.filtered_env
will filter out this sensitive data.
So rewriting what I recommended above, but with sensitive parameters blocked:
http_headers = request.filtered_env.select { |k, _v| k =~ /\A[A-Za-z0-9\-_]+\z/ }