私はSpring
アプリケーションをバックエンドに、GWT
アプリケーションをフロントエンドに持っています。 ユーザーが '' index.jsp ''にログインすると、ユーザー情報がjavascript変数として出力されます。AutobanとXSSの問題
私はAutoBeanFactory
を使用して、ユーザー情報をjsonとしてエンコードおよびデコードしています。
ユーザーは登録でき、ユーザー情報はデータベースに格納されているため、JSPページのユーザー情報をエスケープして、OWASP XSS Preventing cheat sheetに従ってください。
私はエンコードを行うために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の変数は、この(FIRSTNAMEがüを持って注意してください)のようになります。Autobeanと復号化が正常に動作します
var data = {'user':'{"email":"john.doe@gmail.com","lastname":"Doe","firstname":"Über"}'};
しかし文字üが正しく表示されますが、HTMLは(1エスケープされていませんÜber
)。
私はencodeForJavaScript()
機能を使用する場合は、次のように出力されている:
var data = {'user':'{"email":"john.doe@gmail.com","lastname":"Doe","firstname":"\\xDCber"}'};
私は奇妙な問題に遭遇したJSON文字列をデコードしようとします。開発モード/ホストモードのデコードで正常に動作し、Umlautが正しく表示されます。 は、しかし、すぐに私はプロダクションモードでコードを実行するように私はキャッチされない例外を取得:
java.lang.IllegalArgumentException: Error parsing JSON: SyntaxError: Unexpected token x
{"email":"john.doe@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)
私は、次の解決策を考えることができます。データが格納されている場合
- は、(入力の検証にのみ任せdb)、出力エンコーディングを削除します。しかし、それは推奨されるアプローチではありません。
- 通常のASCII文字(ü=> ue)でUmlauteを置き換えて、出力エンコーディングを使用し続けます。
- XSS文字をエスケープしてUMLauteだけを残すライブラリを使用します。
私は
更新いくつかのフィードバックのための感謝:私は今、JSNIからJsoSplittable
を渡し、その後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()
に入るとfindOriginalDeclaringClass
のNPEを取得し、CompilingClassLoader.java
の機能を使用します。declaringClasses
がnullであると思われます。
Thomasさんからの応答に感謝します。 ペイロードに '' encodeForJavaScript() ''を使ってみましたが、うまくいくようです。 Autobeanがすでに各分野(セキュリティ上の賢明さ)で私にそれをしているときに、ペイロードをエンコードすることは実際には意味がありますか? BTW:http://www.wijsmullerbros.nl/content/gwt-hostpage-init-data-encoding –
私が実際に理解していないのは、あなた(そしてリンクされた記事)が代わりに文字列としてオートバイのペイロードを使用する理由ですオブジェクトリテラルのJSNIメソッド( 'Dictionary'ではなく)から' com.google.web.bindery.autobean.gwt.client.impl.JsoSplittable'としてオブジェクトを返し、 '{user :} 'wrapper:' var user = <%= autobeanPayload%> 'と' native JsoSplittable getUser()/ * - {return $ wnd.user; } - * /; '。あなたのオリジナルの質問については、私は 'encodeForJavaScript'を使用しませんが、あなたのページのエンコーディングについて注意する必要があります(UTF-8でなければなりません)。 –
提案をありがとう。私はそれを考えなかった。 Splittableを直接返すようにしました。プロダクションモードで正常に動作します。しかし、ホストモードでは、 '' Splittable.getPayload() ''を呼び出すとNPEを取得します(例外の詳細については私の質問を参照してください)。 –