バックエンドと対話するユーザー向けサービスで構成されたこの単純な JSON システムを見てください。
import java.util.*;
import com.json.parsers.*;
import org.json.simple.*;
class Main{static {
String s = new java.util.Scanner(System.in).useDelimiter("\\A").next();
UserFacingService.handleMessage(s);
}}
class UserFacingService {
static void handleMessage(String s) {
JSONParser parser = JsonParserFactory.getInstance().newJsonParser();
Map js = parser.parseJson(s);
if (commandAllowed(js))
Backend.handleMessage(s);
else
System.out.println("unauthorized!");
}
static boolean commandAllowed(Map js) {
if (js.get("cmd").equals("bad stuff"))
return false;
return true;
}
}
class Backend {
static void handleMessage(String s) {
JSONObject js = (JSONObject) JSONValue.parse(s);
String cmd = (String)js.get("cmd");
if (cmd.equals("bad stuff")) {
doBadStuff();
} else if (cmd.equals("ping")) {
doPong();
}
}
static void doBadStuff() { System.out.println("doing bad stuff"); }
static void doPong() { System.out.println("doing pong"); }
}
ユーザー向けサービス ( quick-jsonを使用) は、ユーザーがバックエンド ( json-simpleを使用) に悪いことをさせないようにします。ユーザーをシミュレートするために、stdin from を使用していMain
ます。実際のシナリオでBackend
は、別のサーバーまたは古いレガシー/バイナリ コード上にあるため、Java オブジェクトを受け入れるように単純に変更することはできません。認証は とは別に行う設計になっていBackend
ます。AdminFacingService
これは、管理者のみがアクセスできる別のクラスを作成するかif (userIsAdmin) return true;
、UserFacingService.commandAllowed
.
ご覧のとおり、意図したとおりに動作します。
$ CP=.:json-simple-1.1.1.jar:quick-json-1.0.2.3.jar
$ javac -cp $CP A.java && echo '{"cmd": "ping"}' | java -cp $CP Main
doing pong
Exception in thread "main" java.lang.NoSuchMethodError: main
送信{"cmd": "bad stuff"}
すると、ユーザー向けサービスはコマンドを拒否する必要があります。
$ CP=.:json-simple-1.1.1.jar:quick-json-1.0.2.3.jar
$ javac -cp $CP A.java && echo '{"cmd": "bad stuff"}' | java -cp $CP Main
unauthorized!
Exception in thread "main" java.lang.NoSuchMethodError: main
それもうまくいきます。しかし、ユーザーが を送信する{"cmd": "bad\u0020stuff"}
と、悪いことが起こります。
$ CP=.:json-simple-1.1.1.jar:quick-json-1.0.2.3.jar
$ javac -cp $CP A.java && echo '{"cmd": "bad\u0020stuff"}' | java -cp $CP Main
doing bad stuff
Exception in thread "main" java.lang.NoSuchMethodError: main
しかし、どのように?ユーザー向けサービスがこれをキャッチしないのはなぜですか?