Должен ли я свернуть свой собственный escape-код для отображения пользовательского ввода в HTML / Javascript? - PullRequest
0 голосов
/ 16 апреля 2020

Об этом, должно быть, спрашивали раньше, но я не смог его найти.

Я хочу, чтобы мои пользователи могли вводить текст в форму HTML, а затем отображать этот текст на веб-странице. в точности так, как было написано, избегая:

  1. XSS-атак
  2. Отображается закодированная пунктуация (например, %2C вместо запятой, + вместо пробела)
  3. Неожиданные результаты из-за использования <или> и того, что браузер рассматривает его как часть HTML

Форма enctype является значением по умолчанию application/x-www-form-urlencoded. Я не уверен, что мне действительно нужно это enctype, но по разным причинам я придерживаюсь его сейчас.

Я видел, что могу частично исправить (2) с помощью decodeURI или decodeURIComponent, хотя он не преобразует + обратно в space.

В остальном, разве нет встроенной функции, которую я могу использовать? Единственные библиотеки, которые я нашел, были серверные для. NET или Java, я не нашел ничего для того, чтобы делать это на стороне клиента в Javascript, но я нашел много строгих предупреждений, что если вы свернете свою собственную код, вы, вероятно, сделаете тонкие ошибки.

На данный момент я использую функцию myDecode ниже, которая, кажется, работает, но я не могу поверить, что это лучший способ.

function myDecode(string) {
    // First convert + to space, since decodeURIComponent may introduce new + characters that were previously encoded
    // Then use decodeURIComponent to convert all other punctuation
    // Then escape HTML special characters
    return htmlEscape( decodeURIComponent( string.replace(/\+/g, " ") ) );                                                                        
}

function htmlEscape(string) {
    return string.replace( /&/g, "&amp;")  // remember to do & first, otherwise you'll mess up the subsequent escaping!
                 .replace( /</g, "&lt;" )
                 .replace( />/g, "&gt;" )
                 .replace( /\"/g, "&quot;" )
                 .replace( /\'/g, "&#39" );
}

Мой тест состоит в том, что пользователь может ввести приведенный ниже текст и отобразить его как написанный, без каких-либо изменений и без запуска сценария:

<script>alert( "Gotcha! + & + " );</script>

Но я не знаю, является ли это Достаточно сильный тест.

Это небольшой хобби-проект без конфиденциальных данных и очень небольшого числа пользователей, поэтому он не обязательно должен быть полностью защищенным. Но было бы неплохо знать, как все делать правильно.

...