Safeguard
Application Security•

ASVS 5.0 V4.1.1: Send an Accurate Content-Type With a Charset

ASVS V4.1.1 (Level 1): every response with a body needs a Content-Type that matches the content, with a charset for text, XML and similar types. Config and tests.

Safeguard Security Team
3 min read

ASVS 5.0 requirement V4.1.1 says every HTTP response that has a message body must contain a Content-Type header that matches the actual content, including the charset parameter for text types, XML and similar, using IANA media types. It is a Level 1 requirement.

Why it matters

The browser and API clients decide how to parse a response from its content type. A wrong or missing type invites mistakes with security consequences. HTML served as text/plain may be sniffed and run as a page, a JSON error served as text/html becomes a place where reflected input executes, and a missing charset can let an attacker use alternative encodings such as UTF-7 to smuggle markup past filters in older clients.

Accurate types also make X-Content-Type-Options: nosniff safe to enable, see V3.4.4.

How to implement it

Set the type explicitly and consistently.

res.type("application/json; charset=utf-8").send(JSON.stringify(data));
res.type("text/html; charset=utf-8").send(html);

Flask:

return Response(body, mimetype="application/json")   # Flask adds the charset for text types

nginx, for static files and defaults:

charset utf-8;
charset_types text/html text/plain text/css application/javascript application/json application/xml;

Also cover error responses, redirects with bodies, 404 pages and file downloads. For downloads of user content, use application/octet-stream with Content-Disposition: attachment unless the type is known.

How to test it

for p in / /api/v1/health /static/app.js /nope /api/v1/error; do
  printf '%s: ' "$p"; curl -sI https://app.example.com$p | grep -i '^content-type'
done

Every path should return a type that matches its body, and text based ones should include charset=utf-8. Compare against the real body, for example a JSON endpoint must not say text/html. Run the same list against error paths and HEAD requests.

An API scan can walk your whole spec and flag responses with a missing or mismatched type; Safeguard's API security scan demo shows that kind of check.

Click through it at your own pace, or open it full screen.

Common mistakes

Framework default of text/html for errors. Set JSON types on API error handlers.

No charset on text types.

Serving user uploads with the sniffed type. Use an allowlist of safe types.

Proxy rewriting the header. Test the public URL.

Quick check

Does JSON need a charset?

JSON is defined as UTF-8, so many stacks omit it. Adding charset=utf-8 does no harm and satisfies strict checkers.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.