Автобан и XSS выпуск

У меня есть Spring приложение на бэкэнд и GWT приложение на веб-интерфейсе. Когда пользователь вошел в систему, index.jsp выведет информацию о пользователе в виде переменной javascript.

я использую AutoBeanFactory кодировать и декодировать пользовательскую информацию как JSON.
Поскольку пользователь может зарегистрироваться, а пользовательская информация хранится в базе данных, я стараюсь следовать шпаргалке по OWASP XSS Preventing, избегая пользовательской информации на странице JSP.

Я использую библиотеку esapi для кодирования. Код на стороне сервера выглядит следующим образом:

public static String serializeUserToJson(CustomUser user) {
        String json;
        AppUserProxy appUserProxy = appUserFactory.appuser().as();
        appUserProxy.setFirstname(encoder.encodeForHTML(user.getFirstname()));
        appUserProxy.setLastname(encoder.encodeForHTML(user.getLastname()));
        AutoBean<AppUserProxy> bean = appUserFactory.appuser(appUserProxy);
        json = AutoBeanCodex.encode(bean).getPayload();
        return json;
    }

Я пытался использовать encodeForHTML а также encodeForJavaScript(), Это нормально работает для обычных символов, однако, как только я использую символы Umlaute (ü, ä, ö), я сталкиваюсь с проблемами.

Если я использую encodeforHTML() Функция, в которой переменная javascript выглядит следующим образом (обратите внимание, что имя пользователя имеет ü):

var data = {'user':'{"email":"john.doe&#x40;gmail.com","lastname":"Doe","firstname":"&Uuml;ber"}'};

Декодирование с помощью Autobean работает нормально, однако символ ü не отображается должным образом, но HTML-код экранирован (&Uuml;ber).

Когда я использую encodeForJavaScript() Функция вывода выглядит следующим образом:

var data = {'user':'{"email":"john.doe&#x40;gmail.com","lastname":"Doe","firstname":"\\xDCber"}'};

Когда я пытаюсь декодировать строку JSON, я сталкиваюсь со странной проблемой. В режиме разработки / размещенном режиме декодирование работает нормально, и умлаут отображается правильно. Однако, как только я запускаю код в производственном режиме, я получаю необнаруженное исключение:

java.lang.IllegalArgumentException: Error parsing JSON: SyntaxError: Unexpected token x
{"email":"john.doe&#x40;gmail.com","lastname":"Doe","firstname":"\xDCber"}
    at Unknown.java_lang_RuntimeException_RuntimeException__Ljava_lang_String_2V(Unknown Source)
    at Unknown.java_lang_IllegalArgumentException_IllegalArgumentException__Ljava_lang_String_2V(Unknown Source)
    at Unknown.com_google_gwt_core_client_JsonUtils_throwIllegalArgumentException__Ljava_lang_String_2Ljava_lang_String_2V(Unknown Source)
    at Unknown.com_google_gwt_core_client_JsonUtils_safeEval__Ljava_lang_String_2Lcom_google_gwt_core_client_JavaScriptObject_2(Unknown Source)
    at Unknown.com_google_web_bindery_autobean_shared_impl_StringQuoter_split__Ljava_lang_String_2Lcom_google_web_bindery_autobean_shared_Splittable_2(Unknown Source)
    at Unknown.com_google_web_bindery_autobean_shared_AutoBeanCodex_decode__Lcom_google_web_bindery_autobean_shared_AutoBeanFactory_2Ljava_lang_Class_2Ljava_lang_String_2Lcom_google_web_bindery_autobean_shared_AutoBean_2(Unknown Source)
    at Unknown.com_gmi_nordborglab_browser_client_mvp_main_UserInfoPresenter_onBind__V(Unknown Source)

Я могу думать о следующих решениях:

  1. Положитесь только на проверку входных данных (когда данные хранятся в БД) и удалите выходную кодировку. Но это не рекомендуемый подход.
  2. Замените Umlaute обычными символами ASCII (ü => ue) и продолжайте использовать выходную кодировку
  3. используйте некоторую библиотеку, которая экранирует символы XSS, но оставляет Umlaute в покое.

Я благодарен за отзыв

Обновление: на основе предложений Томаса я сейчас прохожу JsoSplittable от JSNI, а затем передать это AutoBeanCodex.decode функция. Он работает нормально в производственном режиме, однако в размещенном режиме я получаю следующий NPE:

java.lang.NullPointerException: null
    at com.google.gwt.dev.shell.CompilingClassLoader$MyInstanceMethodOracle.findOriginalDeclaringClass(CompilingClassLoader.java:428)
    at com.google.gwt.dev.shell.rewrite.WriteJsoImpl.isObjectMethod(WriteJsoImpl.java:307)
    at com.google.gwt.dev.shell.rewrite.WriteJsoImpl.visitMethod(WriteJsoImpl.java:289)
    at com.google.gwt.dev.shell.rewrite.WriteJsoImpl$ForJsoInterface.visitMethod(WriteJsoImpl.java:228)
    at com.google.gwt.dev.asm.ClassAdapter.visitMethod(ClassAdapter.java:115)
    at com.google.gwt.dev.shell.rewrite.RewriteJsniMethods.visitMethod(RewriteJsniMethods.java:350)
    at com.google.gwt.dev.asm.ClassReader.accept(ClassReader.java:774)
    at com.google.gwt.dev.asm.ClassReader.accept(ClassReader.java:420)
    at com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.rewrite(HostedModeClassRewriter.java:251)
    at com.google.gwt.dev.shell.CompilingClassLoader.findClassBytes(CompilingClassLoader.java:1236)
    at com.google.gwt.dev.shell.CompilingClassLoader.findClass(CompilingClassLoader.java:1059)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

Код, который вызывает это исключение, выглядит следующим образом:

private native final JsoSplittable getJsoUserdata() /*-{
    if (typeof $wnd.user   !== 'undefined')
        return $wnd.user;
    return null;
}-*/;

@Override
public JsoSplittable getUserdata() {
    JsoSplittable user = null;
    user = getJsoUserdata();
    if (user != null) {
       String payload = user.getPayload();
       Window.alert(payload);
    }
    return user;
}

Window.alert (полезная нагрузка) отлично работает в производственном режиме. В режиме хостинга, когда я вхожу в user.getPayload() Я получаю NPE в findOriginalDeclaringClass функция CompilingClassLoader.java, Кажется, что declaringClasses нулевой

1 ответ

Решение

Вы не должны явно избегать чего-либо; AutoBeans уже сделали это для вас. Вернее, если вы хотите что-то избежать, избегайте вывода AutoBean's getPayload()а не внутренности.

Ваша проблема в том, что AutoBeans использует нативный JSON.parse() когда это возможно (по соображениям производительности и безопасности), который, согласно спецификации, поддерживает только \uNNNN виды побегов, а не \xHH тот encodeForJavaScript выходы. Другими словами, ESAPI потребуется encodeForJSON,

Другие вопросы по тегам