Jump. CredoChecks. NoManualContentDisposition
(Jump.CredoChecks v0.5.0)
View Source
Basics
This check is disabled by default.
Learn how to enable it via .credo.exs.
This check has a base priority of normal and works with any version of Elixir.
Explanation
Prefer Phoenix.Controller.send_download/3 instead of manually setting content-disposition.
This prevents injection attacks by sanitizing filename in the response header.
This follows the suggestion from the
Cowboy security checklist:
All request data, including parsed values, MUST be considered both untrusted and unsafe, and must be validated, sanitized or escaped before use.
# ❌ Bad (manual, error-prone use of content-disposition header):
conn
|> put_resp_content_type(content_type)
|> put_resp_header("content-disposition", "attachment; filename="#{filename}.csv")
|> send_resp(200, content)
# ✅ Good (Phoenix handles filename sanitization)
send_download(conn, {:binary, content},
filename: filename,
content_type: content_type,
charset: "utf-8",
disposition: :inline
)
# 🆗 OK (need to stream response, can't use send_download)
encoded_filename = URI.encode(filename, &URI.char_unreserved?/1)
content_disposition = ~s[attachment; filename="#{encoded_filename}"; filename*=utf-8''#{encoded_filename}]
conn
|> put_resp_content_type("text/csv")
# stream chunks, so send_download/3 cannot be used here
# credo:disable-for-next-line Ev2.Credo.NoManualContentDisposition
|> put_resp_header("content-disposition", content_disposition)
|> send_chunked(200)Check-Specific Parameters
There are no specific parameters for this check.
General Parameters
Like with all checks, general params can be applied.
Parameters can be configured via the .credo.exs config file.