If you only need to display the HTML string without the possibility of triggering XSS:
<?php
$yourSuspectString = "<span style=\"color:red;\" onmouseover=\"alert('Hacked!');\">This is coloured red!</span>";
?>
<!DOCTYPE html>
<script>
/**
* The height of the document element grows to fill the space it's allocated.
* To find the actual height of the content, we need the height of the body plus any margins set.
* @param iFrameDocument The Document element from the iFrame.
*/
function getRealDocumentHeight(iFrameDocument) {
const body = iFrameDocument.body;
// Make sure margins of items inside the body make the body larger, not the HTML element
body.style.display = "flow-root";
const bodyStyle = window.getComputedStyle(body);
const topMargin = parseFloat(bodyStyle.marginTop);
const bottomMargin = parseFloat(bodyStyle.marginBottom);
// Add one to account for possible sub-pixel rounding down
return body.scrollHeight + topMargin + bottomMargin + 1;
}
</script>
<iframe srcdoc="<?php echo htmlspecialchars($yourSuspectString) ?>" sandbox="allow-same-origin" style="width:100%;border:none;" onload="this.height=getRealDocumentHeight(this.contentDocument);"></iframe>
The sandbox attribute will prevent JavaScript from running inside the iFrame. All browsers that don't support sandbox don't support srddoc either. (allow-same-origin
is needed otherwise contentDocument is null).
Though of course this won't prevent, say, someone embedding an inappropriate video or GIF.