2015-04-23 8 views
1

Интересно, сможет ли кто-нибудь подтвердить, безопасно это или нет, поскольку я не могу найти ссылку в Интернете, а также еще один вопрос о SO, который специально занимается этим «решением» для XSS.Сохраненная поддержка XSS с богатыми текстовыми комментариями с использованием DocumentFragment и innerHTML

Мне нужно вставлять комментарии богатого текста на мою страницу. Очевидно, что риски XSS высоки, поэтому мой план состоял в том, чтобы innerHTML был временным DIV в DocumentFragment, а затем реорганизовал дерево, используя предопределенный белый список имен тегов и имена атрибутов, которые я считал «безопасными», удалив любые небезопасные. Затем я могу перенести этот безопасный HTML-код в мой настоящий документ.

Это безопасный способ сделать это? Можно ли каким-либо образом запустить XSS-атаку, выполнив это с помощью DocumentFragment? Я надеюсь, что он будет изолирован от реального документа и, следовательно, защищен от запуска пользовательских событий, который может начать любые атаки.

ответ

2

Я бы не рекомендовал писать собственную библиотеку анти-XSS, так как злонамеренные пользователи должны знать, какой эксплойт вы не учли. Я бы рекомендовал использовать стороннюю библиотеку, например Google Caja HTML Sanitiser.

Посмотрев на свое пере, ее код по-прежнему уязвим, если < и > тегов экранируются:

var unsafe = '\u003Cimg src=1 onerror=alert(\u0027XSS_attack_in_progress\u0027)\u003E', 
 
    //var unsafe = '<h3>Hello</h3><h4>World</h4>', 
 
    whitelistTags = ['h1', 'h2', 'h3', 'b', 'i', 'em', 'strong', 'u'], 
 
    testNode = document.getElementById('testNode'); 
 

 
makeSafeAndAddToDoc(unsafe, testNode); 
 

 
function makeSafeAndAddToDoc(unsafe, targetParent) { 
 
    var safeDocFrag = document.createDocumentFragment(), 
 
    containerDiv = safeDocFrag.appendChild(document.createElement("DIV")), 
 
    nextChild; 
 
    containerDiv.innerHTML = unsafe; 
 
    while ((nextChild = containerDiv.firstChild)) { 
 
    if (isSafe(nextChild)) { 
 
     safeDocFrag.appendChild(containerDiv.firstChild); 
 
     console.debug(safeDocFrag.children); 
 
    } else { 
 
     containerDiv.removeChild(nextChild); 
 
    } 
 
    } 
 
    safeDocFrag.removeChild(containerDiv); 
 
    targetParent.appendChild(safeDocFrag); 
 
} 
 

 
function isSafe(testNode) { 
 
    var tag = testNode.tagName && testNode.tagName.toLowerCase(), 
 
    isTextNode = testNode.nodeType === 3; 
 
    if (!isTextNode && whitelistTags.indexOf(tag) === -1) { 
 
    console.warn('Removing unsafe element: ', testNode.tagName); 
 
    return false; 
 
    } 
 
    for (var i = 0; i < testNode.childNodes.length; i++) { 
 
    if (!isSafe(testNode.childNodes[i])) { 
 
     testNode.removeChild(testNode.childNodes[i]); 
 
     i--; 
 
    } 
 
    } 
 
    return true; 
 
}
#testNode { 
 
    min-width: 10px; 
 
    min-height: 10px; 
 
    border: 1px solid red; 
 
}
<div id="testNode"></div>

+0

Я не пишу библиотеку анти-XSS. Я спрашиваю, будет ли браузер защищать меня от XSS, если я использую DocumentFragment в качестве временного заполнителя, когда я запускаю белый список безопасных тегов и атрибутов. Я не собираюсь писать парсер HTML для санитации самого HTML! – Martin

+0

Если это окажется неработоспособным, то ссылка на HTML Sanitiser, безусловно, приветствуется ... спасибо. – Martin

+0

В вашем сообщении упоминается итерация через предварительно определенный белый список имен тегов и атрибутов. Это звучит как написание собственного кода для устранения уязвимостей XSS. – Jaco