2

JSF 2.2 を使用しています。JSF を純粋なテンプレート言語として使用しようとしています。ただし、問題が 1 つあります。私の環境で JSF ページを作成しているユーザーは、次のようなことができます。

#{session.getAttribute('user').getApiKey()}

ここでは、セッションに保存されているユーザー オブジェクトがあり、getApiKey() メソッドはそのクラスのゲッターです。

JSFページでセッションオブジェクトを完全に無効にするために使用できる「web.xml」構成またはその他のトリックはありますか?

4

3 に答える 3

2

JSFページでセッションオブジェクトを完全に無効にするために使用できる「web.xml」構成またはその他のトリックはありますか?

いいえ。

許可されたタグ、属性、および EL 式のホワイトリストに対して手動でテンプレートを解析します (注: ブラックリストを使用しないでください。ハッカーは、あなたが想像もしていなかった方法を見つけるでしょう)。たとえば、次の式は と同じ効果があります#{session.getAttribute('user').getApiKey()}

  • #{request.session.getAttribute('user').apiKey}
  • #{sessionScope.user.apiKey}
  • #{user.apiKey}
  • #{facesContext.externalContext.sessionMap.user.apiKey}
  • #{facesContext.externalContext.session.getAttribute('user').apiKey}

結局のところ、JSF/Facelets は、サーバーで実行されるある種のテンプレートをクライアントに提供するという仕事には不適切なツールである可能性があります。BB / Wiki / Markdownのようなマークアップやホワイトリストに登録された HTMLを探してください<h:outputText escape="false">

于 2013-04-10T21:03:12.670 に答える
0

この問題を解決するために私がしたことは次のとおりです。このクラスは基本的に、ページ上のすべてのコア オブジェクトへのアクセスを取り消します。さらに、コンテキスト パスへのアクセスを可能にするユーティリティ変数を追加しました。私はこれを試してみましたが、うまくいくようです!.

package com.example.templates.jsf;

import javax.el.ELContext;
import javax.el.ELException;
import javax.el.PropertyNotFoundException;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

import com.sun.faces.component.CompositeComponentStackManager;
import com.sun.faces.el.ImplicitObjectELResolver;
import com.sun.faces.util.MessageUtils;

/**
 *  This class revokes access to server page context objects 
 */
public class CustomImplicitObjectELResolver extends ImplicitObjectELResolver {

public static final int CONTEXT_PATH = 19;

public CustomImplicitObjectELResolver(){
    super();

    // Revoke access to variables that can potentially
    // give access to internal class objects.
    IMPLICIT_OBJECTS.remove("facesContext");
    IMPLICIT_OBJECTS.remove("session");
    IMPLICIT_OBJECTS.remove("sessionScope");
    IMPLICIT_OBJECTS.remove("application");
    IMPLICIT_OBJECTS.remove("applicationScope");
    IMPLICIT_OBJECTS.remove("request");
    IMPLICIT_OBJECTS.remove("requestScope");
    IMPLICIT_OBJECTS.remove("view");
    IMPLICIT_OBJECTS.remove("viewScope");
    IMPLICIT_OBJECTS.remove("initParam");
    IMPLICIT_OBJECTS.remove("component");       
    IMPLICIT_OBJECTS.remove("cookie");
    IMPLICIT_OBJECTS.remove("header");
    IMPLICIT_OBJECTS.remove("headerValues");
    IMPLICIT_OBJECTS.remove("flowScope");

    // My own utility method
    IMPLICIT_OBJECTS.put("contextPath", CONTEXT_PATH);
}

@Override
public Object getValue(ELContext context,Object base, Object property)
        throws ELException {
    // variable resolution is a special case of property resolution
    // where the base is null.
    if (base != null) {
        return null;
    }
    if (property == null) {
        String message = MessageUtils.getExceptionMessageString
            (MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "property");
        throw new PropertyNotFoundException(message);
    }

    Integer index = IMPLICIT_OBJECTS.get(property.toString());

    if (index == null) {
        return null;
    } else {
        FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
        ExternalContext extCtx = facesContext.getExternalContext();
            switch (index) {

            case COMPOSITE_COMPONENT:
                // The following five lines violate the specification.
                // The specification states that the 'cc' implicit object
                // always evaluates to the current composite component,
                // however, this isn't desirable behavior when passing
                // attributes between nested composite components, so we
                // need to alter the behavior so that the components behave
                // as the user would expect.
                /* BEGIN DEVIATION */
                CompositeComponentStackManager manager =
                      CompositeComponentStackManager.getManager(facesContext);
                Object o = manager.peek();
                /* END DEVIATION */
                if (o == null) {
                    o = UIComponent.getCurrentCompositeComponent(facesContext);
                }
                context.setPropertyResolved(o != null);
                return o;
            case PARAM:
                context.setPropertyResolved(true);
                return extCtx.getRequestParameterMap();
            case PARAM_VALUES:
                context.setPropertyResolved(true);
                return extCtx.getRequestParameterValuesMap();
            case CONTEXT_PATH:
                context.setPropertyResolved(true);
                return extCtx.getRequestContextPath();
            case RESOURCE:
                context.setPropertyResolved(true);
                return facesContext.getApplication().getResourceHandler();
            default:
                return null;
        }
    }
}

}

次に、faces-config.xml に次のエントリを追加します。

<application>
    <el-resolver>
        com.example.templates.jsf.CustomImplicitObjectELResolver
    </el-resolver>
</application>
于 2013-04-11T16:32:47.637 に答える