ASP.NET MVC Razor render without encoding
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Razor encodes output by default, and that default is one of the most important protections against cross site scripting. Sometimes you must render rich text, so unencoded output is required for trusted content. The safe approach is to make raw rendering explicit, isolated, and backed by sanitization.
Why Razor Encodes By Default
When you write @Model.Body, Razor converts dangerous characters into safe text representation. This prevents user supplied scripts from being interpreted by the browser. If you bypass encoding too early, an attacker can execute JavaScript in another user session.
That is why @Html.Raw(...) should never be a casual formatting tool. It is a security decision point.
Correct Pattern: Sanitize Then Render
If content comes from users, sanitize it on the server using an allow list. Keep only the tags and attributes you explicitly accept.
A small service layer keeps this policy in one place.
In your controller, map raw input to a sanitized view model field.
In Razor, use default encoding for normal fields and raw output only for the sanitized field.
Trusted HTML Versus User HTML
Not all raw HTML has equal risk.
- Trusted template fragments created by developers can be rendered directly.
- User supplied content should be sanitized every time it is accepted or rendered.
- Third party content should be treated as untrusted unless you have strict validation rules.
Keep these paths separate in code. A field named SanitizedHtml is safer than a generic field named Content because it signals expectation and review intent.
Prefer IHtmlContent For Internal Helpers
If you build reusable view helpers, returning IHtmlContent can reduce accidental double encoding and make intent explicit.
This helper still encodes dynamic text before wrapping it in markup.
Security Checks You Should Add
Raw rendering should have automated tests.
- Verify script tags are removed by sanitizer.
- Verify dangerous attributes such as event handlers are stripped.
- Verify allowed formatting tags remain.
- Verify URLs are filtered according to policy.
Also add code review guidance that any new Html.Raw usage must point to trusted or sanitized input.
Common Pitfalls
- Calling
Html.Rawdirectly on request payload fields. - Sanitizing in the view instead of in a service or controller layer.
- Allowing too many tags and attributes in the allow list.
- Mixing trusted templates and untrusted user strings in one property.
- Assuming client side editor filtering is a replacement for server side sanitization.
Summary
- Razor default encoding is a core security feature.
- Use raw rendering only for trusted or sanitized HTML.
- Centralize sanitization policy in a dedicated service.
- Make view model naming explicit so review intent is clear.
- Add tests and review rules for every raw rendering path.

