이제 모든 주요 브라우저 샌드 박스 iframe을 지원하는, 내가하는 훨씬 간단한 방법이 생각 안전 할 수는. 이런 종류의 보안 문제에 더 익숙한 사람들이이 답변을 검토 할 수 있다면 좋겠습니다.
참고 :이 방법은 IE 9 및 이전 버전에서는 작동하지 않습니다. 샌드 박싱을 지원하는 브라우저 버전 은 이 표 를 참조하십시오 . (참고 : 표에는 Opera Mini에서 작동하지 않는다고 표시되어 있지만 방금 시도했지만 작동했습니다.)
아이디어는 JavaScript가 비활성화 된 숨겨진 iframe을 만들고 신뢰할 수없는 HTML을 붙여넣고 파싱하도록하는 것입니다. 그런 다음 DOM 트리를 살펴보고 안전한 것으로 간주되는 태그와 속성을 복사 할 수 있습니다.
여기에 표시된 화이트리스트는 예시 일뿐입니다. 화이트리스트에 가장 좋은 것은 애플리케이션에 따라 다릅니다. 태그 및 속성의 화이트리스트보다 더 정교한 정책이 필요한 경우,이 예제 코드는 아니지만이 방법으로 수용 할 수 있습니다.
var tagWhitelist_ = {
'A': true,
'B': true,
'BODY': true,
'BR': true,
'DIV': true,
'EM': true,
'HR': true,
'I': true,
'IMG': true,
'P': true,
'SPAN': true,
'STRONG': true
};
var attributeWhitelist_ = {
'href': true,
'src': true
};
function sanitizeHtml(input) {
var iframe = document.createElement('iframe');
if (iframe['sandbox'] === undefined) {
alert('Your browser does not support sandboxed iframes. Please upgrade to a modern browser.');
return '';
}
iframe['sandbox'] = 'allow-same-origin';
iframe.style.display = 'none';
document.body.appendChild(iframe);
iframe.contentDocument.body.innerHTML = input;
function makeSanitizedCopy(node) {
if (node.nodeType == Node.TEXT_NODE) {
var newNode = node.cloneNode(true);
} else if (node.nodeType == Node.ELEMENT_NODE && tagWhitelist_[node.tagName]) {
newNode = iframe.contentDocument.createElement(node.tagName);
for (var i = 0; i < node.attributes.length; i++) {
var attr = node.attributes[i];
if (attributeWhitelist_[attr.name]) {
newNode.setAttribute(attr.name, attr.value);
}
}
for (i = 0; i < node.childNodes.length; i++) {
var subCopy = makeSanitizedCopy(node.childNodes[i]);
newNode.appendChild(subCopy, false);
}
} else {
newNode = document.createDocumentFragment();
}
return newNode;
};
var resultElement = makeSanitizedCopy(iframe.contentDocument.body);
document.body.removeChild(iframe);
return resultElement.innerHTML;
};
여기서 시도해 볼 수 있습니다 .
이 예제에서는 스타일 속성과 태그를 허용하지 않습니다. 허용했다면 CSS를 구문 분석하고 목적에 맞는지 확인하고 싶을 것입니다.
여러 최신 브라우저 (Chrome 40, Firefox 36 베타, IE 11, Android 용 Chrome)와 이전 브라우저 (IE 8)에서이를 테스트하여 스크립트를 실행하기 전에 구제되었는지 확인했습니다. 나는 그것에 문제가있는 브라우저가 있는지, 아니면 내가 간과하고있는 어떤 엣지 케이스가 있는지 알고 싶다.