0

最近、一般的なJSR245ポートレットクラスで次のような関数を見つけました。

    public class MyGenericPortlet extends GenericPortlet {
      @Override
      public void processAction(ActionRequest rq, ActionResponse rs) throws PortletException{
        String actParam = rq.getParameter("myAction");

        if( (actParam != null) && (!("").equals(actParam))) {
          try{
            Method m = this.getClass().getMethod(actParam, new Class[]{ActionRequest.class, ActionResponse.class});
                m.invoke(this, new Object[]{rq, rs});
            }
            catch(Exception e){
                setRequestAttribute(rq.getPortletSession(),"error", "Error in method:"+action);
                e.printStackTrace();
            }
        }
        else setRequestAttribute(rq.getPortletSession(),"error", "Error in method:"+action);
      }
    }

そのようなコードはどれくらい安全ですか?私が見る限り、次の問題が発生する可能性があります。

  1. クライアントから送信されたパラメータは、チェックを外して関数を呼び出すために使用されます。これにより、対応するポートレットにデータを送信できるすべてのユーザーが、一致する関数を呼び出すことができます。一方、呼び出される関数には特定のインターフェイスが必要です。通常、そのような機能は非常にまれです。
  2. プログラマーは、対応するインターフェースを備えた関数を誤って追加する可能性があります。パブリック関数のみが検出されているように見えるため、関数がプライベートまたは保護されている限り、これは問題ありません。
  3. エラーメッセージは、ソフトウェアに関する情報をクライアントに明らかにする可能性があります。ソフトウェア自体はオープンソースであるため、これは問題にはなりません。

明らかに、悪用される可能性のあるプログラミングエラーの余地があります。発生する可能性のある他の望ましくない副作用はありますか?私(または開発者)は、この機能から生じるリスクをどのように判断する必要がありますか?

安全だとお考えの方は、その理由をお聞かせください。

4

1 に答える 1

1

特定のシグニチャを持つパブリックメソッドのみをリモートで呼び出すことができるという事実は良いことです。ただし、たとえば、アクションメソッドに特別なアノテーションを要求することで、より安全にすることができます。これは、開発者がメソッドを呼び出し可能なアクションにすることを特に意図していたことを示します。

現在の実装が危険である可能性がある現実的なシナリオは、開発者がリクエスト内の情報が安全であることを検証するアクションを追加し、実際の処理のためにリクエストとレスポンスを別のメソッドに渡す場合です。攻撃者がデリゲートメソッドの名前を知ることができれば、パラメータの安全性の検証をバイパスして、直接呼び出すことができます。

于 2012-06-19T14:56:35.353 に答える