2010-07-26 4 views
2

배경 : ModelDriven을 사용하여 Struts2 ActionSupport 클래스를 코딩했습니다. 보기 (JSP)에서 OSIV 및 첨부 된 엔티티를 사용하여 최대 절전/스프링 웹 응용 프로그램입니다. ModelDriven 인터페이스가 struts2에서 보안 위협을 제기합니까?

은 내가 ModelDriven<E> 인터페이스를 통해 struts2의 valuestack에 부착 된 개체에 대한 참조를 가지고 객체 을 가하고 저를 '처벌'건축가에서 오늘이 이메일을 받았습니다. 그는 맞습니까? 또는 무엇입니까? 분명히 이것은 내가하는 중대한 일이지만 그가 말한 것을 따르지 않고 있으며, 나는 그 후에 그의 제안을 받아 들여 그의 책상에서 그를 방문하는 것 같지 않습니다. 오 소년. 경력을 바꿀 시간. 우리는 전술 한 바와 같이

는 --- 건축가에서 ---

빌리, 당신은 여전히 ​​계속해서 또 다시 코드 에 같은 실수를하고 있습니다. 이것은 당신이이 오류를 만든 네 번째 시간이며 나는 당신의 작업의 질에 대해 에 대해 우려하고 있습니다. 이것을 한 번 또는 두 번하는 것이 한 가지이지만, 네 번째 시간 후에 후에 나는 내가 말하는 것을 이해할 수 없는지 궁금합니다. 다음은 당신을 위해 그것을 밖으로 철자합니다. 이 이메일을 읽은 후에 가져 오지 못하면 내 책상에 와서 우리가 살펴 보겠습니다. 이 작업은 즉시 중단되어야하며이 실수를 바로 잡기 전에 코드가 리팩토링되기를 바랍니다. 과 같은 코드가 있으면 생산에 지장이 생기며 심각한 보안 문제가 발생할 수 있습니다. 또한 적절한 견책을 줄 수 있도록 Dave를 복사하고 있습니다. 저는 Dave에게 당신이 Level III에서 Level II로 옮겨 갈 것을 추천 할 것입니다. 다음 내용을 읽고 배우고 지시 한대로 모든 코드를 리팩토링하십시오. 바인딩 된 객체

:

Struts2 액션 클래스는 ModelDriven 인터페이스로 표시되어

는 모델 는 HTML 페이지의 양식 요소에 바인딩됩니다.

공용 클래스 UserAction는 ActionSupport를가

ModelDriven

구현 확장 그리고 다음과 같이 UserModel는 POJO입니다 : 예를 들어, HTML 양식 이는 userName라는 필드가 있고 것처럼 액션 클래스는 정의

public class UserModel { 
    private String userName; 

    public String getUserName() { 
     return userName; 
    } 

    public void setUserName(String userName) { 
     this.userName = userName; 
    } 
} 

양식이 제출되면 Action에 UserModel의 인스턴스가 포함되어있는 한 struts2 은 userName 필드를 UserModel.userName에 바인딩하여 값을 자동으로 채 웁니다.

그러나이 단순성은 악의적 인 사용자에게 높은 비용을 초래합니다. 객체가 ModelDriven으로 으로 선언되면 최종 사용자 인 브라우징 사용자는 모델 설정자를 통해 모델 그래프에 액세스 할 수 있습니다. 예를 들어,이 경우를 보자

공용 클래스 UserAction는 ActionSupport를가

및 ModelDriven

구현 연장 ...

public class UserModel { 
    private String userName; 
    private UserEntity userEntity; 

    public String getUserName() { 
     return userName; 
    } 

    public void setUserName(String userName) { 
     this.userName = userName; 
    } 

    pubic UserEntity getUserEntity() { 
     return userEntity; 
    } 
} 

와 ...

@Entity 
public class UserEntity { 
    private String password; 

    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 
} 

OSIV 패턴 가정이 사용되고 엔티티 UserEntity가 첨부됩니다.

그의 손에 앞 지식이나 시간의 비트와 함께 교활 사용자 수 엔티티를 가정

/myform?userName=billy&userEntity.password=newpassword 

세션, 빌리의 암호를 변경하는 위의 결과의 마지막에 저장됩니다.

요점은 객체 그래프를 사용할 수 있다는 것입니다.

ModelDriven을 사용하고, 대안을 사용하면, 당신은 valuestack에 배치 세밀한 모델을 정의하고 응답을 전송하고 거래를 허용하기 전에 에 모델에서 대상 개체를 복사해야 끔찍한 방법입니다 커밋하기.

답변

1

건축가가 옳습니다. ValueStack의 민감한 정보에 액세스 할 수있는 물체를 설치하면 잠재적 인 보안 위험이 발생할 수 있습니다. 위의 공격으로 악의적 인 사용자가 실제로 비밀번호를 재설정 할 수 있습니다.

하지만 :

그는 입력 매개 변수의 적절한 검증/제한에 대한 방법을 설계해야 건축가이기 때문에. Struts2에서 ParamsInterceptor를 사용하면 특정 매개 변수를 액션에 전달하는 것이 매우 쉽습니다. 따라서 그것은 당신의 작업이 짜증나는 것이 아니라 시스템의 아키텍처입니다. 개발자는 비즈니스 논리 구현에 집중할 수 있어야합니다. 인프라는 건축가가 제공해야합니다.

건배,

0

ModelDriven 인터셉터 w

당신이 직면하게 될 것이다 입력 매개 변수를 처리하지 않을 경우 블라인드

예 모델 인터페이스, 보안 문제의 원천이 될 수있다 보안 구멍.

매개 변수 인터셉터를 사용해야합니다. 그런 다음 행동에 ParameterNameAware를 구현하고 acceptableParameterName 쓰기

<interceptor-ref name="params"> 
    <param name="excludeParams">\w+((\.\w+)|(\[\d+\])|(\(\d+\))|(\['\w+'\])|(\('\w+'\)))*</param> 
</interceptor-ref> 

다음 struts.xml에서

는로 PARAMS 인터셉터를 변경합니다. 당신의 사용자 POJO는 그들 중 일부는 사용자로부터 얻을 수 있어야 다른 속성을 많이하고 이있는 경우

public class sample implements ParameterNameAware(){ 
     public boolean acceptableParameterName(String parameterName) { 
     if (("username".equals(parameterName) || 
      "firstname".equals(parameterName) || 
      "lastname".equals(parameterName)) 
      return true; 
     else 
      return false; 
    } 

} 

위는 중요하다.

많은 ModelDriven 작업을 사용하는 경우 일반적으로 만들 수 있습니다.

ParameterNameAware을 확장하는 기본 동작을 만듭니다. 그런 다음 당신의 행동 목록과 유효한 매개 변수 목록을 갖는 일반적인 접근법을 개발하십시오 :

우리는 행동 목록과 허용 가능한 매개 변수를 읽기 위해 봄을 사용했습니다.스프링 XML에서 우리는 추가 :

<util:properties id="actionsValidParameters" 
    location="classpath:/configs/actions-valid-parameters.properties" /> 

actions-valid-parameters.properties 그대로 : 주소 개체가 Detail 객체가 있고 세부 개체의 일부 속성을 채우려는 경우

save-user=username,description,firstname,lastname 
save-address=zipcode,city,detail,detail.addLine1,detail.addLine2,detail.no 

힌트, 당신이 있는지 확인 위의 목록에 '세부 사항'을 포함하십시오. 이제

public class UserAction extends BaseActionSupport implements 
     ModelDriven<User>{ 


} 
로 작업을 wrtie
public class BaseActionSupport extends ActionSupport implements ParameterNameAware 
{ 

@Resource(name = "actionsValidParameters") 
public Properties actionsValidParameters; 

@Override 
public boolean acceptableParameterName(String parameterName) { 

    String actionName = ActionContext.getContext().getName(); 
    String validParams = (String) actionsValidParameters.get(actionName); 

    //If the action is not defined in the list, it is assumed that the action can accept all parameters. You can return false so if the action is not in the list no parameter is accepeted. It is up to you! 
    if(StringUtils.isBlank(validParams)) 
     return true; 
    // Search all the list of parameters. 
      //You can split the validParams to array and search array. 
    Pattern pattern = Pattern.compile("(?<=^|,)" + parameterName 
      + "(?=,|$)"); 
    Matcher matcher = pattern.matcher(validParams); 
    boolean accepeted = matcher.find(); 
    LOG.debug(
      "The {} parameter is {} in action {}, Position (excluding the action name) {} , {} , mathced {} ", 
      parameterName, accepeted, actionName, matcher.start(), matcher.end(), 
      matcher.group()); 
    return accepeted; 
    } 

} 

는 액션이다

관련 문제