{"record":{"id":"ba3ee5e61356c123","repo":"Dolibarr/dolibarr","slug":"error-using-the-image-wrapper-to-output-a-file-with-a-mime","errorCode":null,"errorMessage":"Error: Using the image wrapper to output a file with a mime type HTML is not possible.","messagePattern":"Error: Using the image wrapper to output a file with a mime type HTML is not possible\\.","errorType":"http","errorClass":null,"httpStatus":403,"severity":"warning","filePath":"htdocs/viewimage.php","lineNumber":259,"sourceCode":"\t\tif ($extname) {\n\t\t\t$original_file = getImageFileNameForSize($original_file, $extname);\n\t\t}\n\t} else {\n\t\thttponly_accessforbidden(\"ErrorFileNotFoundWithSharedLink\", 403, 1);\n\t}\n}\n\n// Define mime type\n$type = 'application/octet-stream';\nif (GETPOST('type', 'alpha')) {\n\t$type = GETPOST('type', 'alpha');\n} else {\n\t$type = dol_mimetype($original_file);\n}\n\n// Security: This wrapper is for images. We do not allow type/html\nif (preg_match('/html/i', $type)) {\n\thttponly_accessforbidden('Error: Using the image wrapper to output a file with a mime type HTML is not possible.');\n}\n// Security: This wrapper is for images. We do not allow files ending with .noexe\nif (preg_match('/\\.noexe$/i', $original_file)) {\n\thttponly_accessforbidden('Error: Using the image wrapper to output a file ending with .noexe is not allowed.');\n}\n\n// Security: Delete string ../ or ..\\ into $original_file\n$original_file = preg_replace('/\\.\\.+/', '..', $original_file);\t// Replace '... or more' with '..'\n$original_file = str_replace('../', '/', $original_file);\n$original_file = str_replace('..\\\\', '/', $original_file);\n\n// Find the subdirectory name as the reference\n$refname = basename(dirname($original_file).\"/\");\nif ($refname == 'thumbs') {\n\t// If we get the thumbs directory, we must go one step higher. For example original_file='10/thumbs/myfile_small.jpg' -> refname='10'\n\t$refname = basename(dirname(dirname($original_file)).\"/\");\n}\n","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/Dolibarr/dolibarr/blob/598aa4bdada683d17ca04b1842548821ff0eb6c6/htdocs/viewimage.php#L241-L277","documentation":"viewimage.php is an image-only wrapper: if dol_mimetype() of the resolved file matches /html/i it blocks output with 'Error: Using the image wrapper to output a file with a mime type HTML is not possible.' This prevents serving active content (HTML, which can contain JS) through the image endpoint and sidestep content-type protections.","triggerScenarios":"Request to viewimage.php with file param pointing to an .html/.htm file or any file whose detected mime type contains 'html' (e.g. file=page.html, or a file saved without extension but with HTML content type detection).","commonSituations":"Developers trying to reuse the image wrapper to display uploaded HTML previews; CMS/medias uploads mixing html files with images and templating loops that render all uploads through viewimage; files renamed with image extensions but detected by content.","solutions":["Serve HTML files through document.php (with proper download headers) instead of viewimage.php","Remove/rename the HTML file or store previews as real images (PNG/JPEG)","If you only meant to display an image, fix the file parameter to point at the actual image","For custom previews, generate a static PNG snapshot of the HTML instead of serving raw HTML"],"exampleFix":"// before\n<img src=\"viewimage.php?modulepart=medias&file=upload/page.html\">\n// after\n<a href=\"document.php?modulepart=medias&original_file=upload/page.html\">Open page</a>","handlingStrategy":"validation","validationCode":"if (preg_match('/html/i', dol_mimetype($file)) || preg_match('/\\.(html?|xhtml)$/i', $file)) { throw new InvalidArgumentException('Use document.php for HTML files'); }","typeGuard":"function isImageFile(string $f): bool { $t = dol_mimetype($f); return strpos($t, 'image/') === 0 && !preg_match('/html/i', $t); }","tryCatchPattern":null,"preventionTips":["Route HTML/active content through document.php, images through viewimage.php","Validate uploaded file types at upload time; separate image galleries from documents","Rely on content-based mime detection, not just file extensions","Never repurpose the image wrapper as a generic file server"],"tags":["security","viewimage","mime-type","content-type","dolibarr"],"backgroundTag":"unsupported-operation","analyzedSha":"598aa4bdada683d17ca04b1842548821ff0eb6c6","analyzedAt":"2026-09-14T11:12:15.309Z","contentChangedAt":"2026-09-14T11:12:15.309Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}