Preview path
Note who can upload and who later views the preview, including admins.
Treat HTML produced from an uploaded DOCX as untrusted content. A DOCX-to-HTML converter does not establish that links and markup are safe to inject into your application page. Sanitize the HTML with a narrow allowlist, restrict link protocols, and consider an isolated preview frame for documents from other users.
This guide covers check 04: Input validation and error handling in the Zenveus Production Readiness Standard.
For builders
Converting a DOCX file to HTML does not make that HTML safe for a browser. A document can contain links or markup your preview should never execute. Sanitize the converted HTML, authorize file access, and test malicious fixtures in an isolated preview.
A scoped repair request
Use this prompt in Lovable, Cursor, Replit, or Claude Code with the relevant server files available.
Audit my DOCX conversion and preview path for unsafe HTML rendering. Authorize file access before conversion, limit uploads and conversion resources, sanitize output with an explicit HTML and URL allowlist, and test disallowed protocols and markup in isolated fixtures. Work on a branch with synthetic data and mocked external services. Show the smallest diff, identify required adapters and deployment settings, and add allowed and denied tests that prove side effects cannot happen before checks pass. Do not disable security checks to make a test pass.The same failure may appear as
Find the failure layer
Each check removes a class of causes. Keep the first failing result, its timestamp, and the production log beside it.
Note who can upload and who later views the preview, including admins.
File extension and MIME checks do not sanitize document contents.
Confirm the preview removes or neutralizes it. Test large documents for conversion time and memory limits.
Ranked diagnosis
The app returns Mammoth HTML and inserts it without a visible sanitizer.
A DOCX extension does not validate links or HTML generated from document content.
An authorized admin can still encounter untrusted content uploaded by a different user.
A pathological document may consume excessive CPU or memory without isolation.
Step-by-step repair
Edit the DOCX conversion endpoint and DocumentViewer.tsx at the point that uses dangerouslySetInnerHTML. Apply authorization and upload limits before conversion.
Production safety ruleNever disable access controls, expose service keys, or add wildcard CORS as a routine shortcut.
Resolve the document using both ID and the caller permission. Limit compressed upload size, expanded archive size, conversion time, and memory in an isolated worker; small ZIP files can expand substantially.
Use a maintained HTML sanitizer with explicit tags and attributes needed for your preview. Start with text, headings, lists, and tables. Exclude links and embedded media until you implement and test their URL policy.
Pass sanitized HTML into dangerouslySetInnerHTML. Do not modify it afterward or run another transformation that can reintroduce unsafe markup. Keep sanitizer dependencies updated.
For external uploads, consider a separately isolated preview with restrictive CSP and a sandbox that does not combine script execution with same-origin privileges. Keep authenticated app actions outside the preview.
Implementation example
import DOMPurify from 'dompurify';
export function DocumentPreview({ convertedHtml }) {
const clean = DOMPurify.sanitize(convertedHtml, {
ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'h1', 'h2', 'h3',
'ul', 'ol', 'li', 'table', 'thead', 'tbody', 'tr', 'th', 'td'],
ALLOWED_ATTR: []
});
return <div dangerouslySetInnerHTML={{ __html: clean }} />;
}This example runs in a browser Client Component and intentionally strips links, images, styles, and attributes. Install and maintain DOMPurify; server-side sanitization needs a supported DOM implementation. Authorize the document on the server as well.
Prove the repair
Run these checks with synthetic data in your test environment, then repeat the relevant acceptance checks after deployment.
When the built-in AI fix makes it worse
Pause generated changes, restore a known working branch, and capture one failing request with its logs. Change one layer and rerun the allowed and denied checks before proceeding.
Engineering handoff
We trace one production request through the complete path, isolate the failing boundary, and leave behind evidence your team can repeat.
Upload ownership and access checks before conversion and preview delivery.
File size, conversion resources, worker isolation, and failure handling.
Allowed HTML, attributes, URL protocols, library version, and later mutations.
Disallowed markup and protocols tested against the actual browser rendering sink.
Typical repair pattern
Authorized users see permitted formatting; a disallowed test link is neutralized and oversized documents fail safely.
Before the next release
Clear answers
No. Extension checks select a file format; they do not validate the HTML produced from its contents.
It is appropriate only when the inserted HTML has been made safe for that context and trusted according to a clear policy.
Escaping is safe but removes formatted preview. A strict sanitizer can retain permitted formatting while removing unsafe links and markup.
Run the verification checks on this page against your test environment, then repeat the relevant checks after deployment. Example code needs your app's authentication, data model, and configuration; reading the guide alone does not verify your deployment.
Official documentation and library references
Free next step
The free tool helps you inspect this symptom. Its result does not establish whether the whole app is production ready.
The Verdict
We can see the symptom from here. What we cannot tell you from outside is whether it is contained or structural. A scanner collects evidence. A named senior engineer makes the decision. For $299, a named senior engineer reads your code and signs a written Verdict against the nine checks in the Zenveus Production Readiness Standard. The 48-hour clock begins when the required access and context are available. If the report does not give your developer a list they can act on, you do not pay.
The 48-hour clock starts when the required access and context are available.
Free decision aid
Get a senior view of the constraint, the evidence you have, and the next decision that removes the most risk.
No email required for this decision aid. Dismiss once and this popup stays closed for the session.