2

HTML と Javascript にレンダリングされるサニタイズ データを処理するために、Spring JSP プロジェクトに esapi を導入しました。使用する 1 つのフィールドはサードパーティの Web サービスによって設定され、結果を Javascript 変数に出力します。

var errReason= '<esapi:encodeForJavaScript>${myOrder.rateErrorMessage}</esapi:encodeForJavaScript>';

問題は、WebService からの結果の末尾に改行文字が追加される場合があることです。encodeForJavascript は改行を処理する必要があると考えていましたが、代わりに上記のコードは次のようにレンダリングされます。

var errReason 'This was an invalid request: missing required parameter
';

esapi は設計どおりに機能していますか? この問題に対処するための代替手段はありますか?

ありがとう。

4

1 に答える 1

1

与えられた情報では、ここで問題を引き起こしているのは esapi ではありません。次の単体テストに合格します。

@Test
public void testWindowsNewline() { 
     Encoder instance = ESAPI.encoder(); 
     assertEquals("\\x0D\\x0A", instance.encodeForJavaScript("\r\n")); 
}

FWIW、taglibs は esapi エンコーダー クラスの単なるラッパーです。

JavaScript 文字列に埋め込まれた taglibs を使用しているようです。これは、私のチームのコード レビューで見た場合、欠陥としてマークします。その理由は次のとおりです。

ページをレンダリングするときに JSP コンパイラが実行する手順は複数あります。ほんの数例を挙げると、HTML レンダリング、データ バインディング、JSTL バインディングがあります。この順序付けは実装固有であるため、ここにあるようなコードを混在させないようにしてください。

を呼び出す前に、JSP コンパイラが"\r\n"を HTML 空白として解釈していると思われます<esapi:encodeForJavaScript></esapi:encodeForJavaScript>

ここに私が過去にやったことのいくつかがあります。私はコントローラー/サービス層でのエスケープを好む傾向があります。この例では、Spring MVC を想定しており、かなりの自由を取っています。

@Controller
public class FooController {
     //This should actually be done in a service class, but this is for demo
     private Encoder = ESAPI.encoder();

     @Autowired
     private DataService dataService;

     //logic for handling request

     public String returnStringEscapedForJavascriptContext(){
          OrderBean myOrder = dataService.getMyOrder(); 
          String unescaped = myOrder.getRateErrorMessage();
          String escapedAsJavascriptData = encoder.encodeForJavaScript(unescaped);
          return escapedAsJavascriptData ;
     }
}

myOrderviewBean などに 変換する場合も、同じ基本的なロジックが適用されます。

もう 1 つの解決策は、安全な esapi エスケープ メソッドを、すべてのビュー Bean が継承した抽象クラスとしてラップすることです。そのため、JSP でこの作業を本当に行う必要がある場合は、次のようにすることができます。

public abstract class SecureBean {
     private Encoder encoder = ESAPI.encoder();
     public String escapeForJavaScript(String input){
          return encoder.escapeForJavaScript(input);
     }
}

次に継承します。

public class OrderBean extends SecureBean {
     String rateErrorMessage;  //with getters/setters assumed
}

今あなたのjspで:

var errReason= '${myOrder.escapeForJavaScript(myOrder.rateErrorMessage())}';

一部は少し冗長ですが、ここでの目標は、JSP のレンダリング順序を踏まないようにすることです。Encoder の実装を交換できるように、エンコード/デコード用のアダプター インターフェイスを作成することも検討してください。

于 2015-01-28T17:39:34.513 に答える