Интерфейс ModelDriven представляет угрозу безопасности в Struts2? - PullRequest
2 голосов
/ 26 июля 2010

фон: я кодировал класс ActionSupport struts2 с ModelDriven.Это веб-приложение hibernate / spring, использующее OSIV и присоединенные сущности в представлении (JSP).

Сегодня я получил это письмо от архитектора, «наказывающего» меня за то, что я поместил объект, имеющий ссылку на присоединенную сущность.в стойке значений struts2 через интерфейс ModelDriven<E>.Он прав или как?Очевидно, это серьезная вещь, которую я делаю, но я не следую тому, что он говорит, и мне действительно не хочется принимать его предложение и после этого навещать его за столом.О, парень.Время сменить профессию.

--- от архитектора ---

Билли, как мы уже обсуждали, вы все равно повторяете ошибки в своем коде снова и снова.Это уже четвертый раз, когда вы совершаете эту ошибку, и я беспокоюсь о качестве вашей работы.Одно дело сделать это один или даже два раза, но после четвертого раза я задаюсь вопросом, не можете ли вы понять то, что я говорю.Следующее объяснит это для вас.Если вы не получите его после прочтения этого электронного письма, тогда приходите ко мне на стол и мы просмотрим его.Это должно немедленно прекратиться, и я хочу, чтобы весь ваш код был реорганизован до конца дня, чтобы исправить эту ошибку.Если какой-либо код, подобный этому, попадет в производство, у нас будет серьезная проблема с безопасностью.Также обратите внимание, что я копирую Дэйва, чтобы можно было сделать правильный выговор.Я также собираюсь порекомендовать Дэйву перейти с уровня III на уровень II для разработчиков.Прочитайте следующее и, пожалуйста, изучите его и выполните рефакторинг всего своего кода, как я указал.

Об объектах привязки:

Когда класс действия Struts2 помечен с помощью интерфейса ModelDriven, модель будетбыть привязанным к элементам формы на странице HTML.Например, если форма HTML имеет поле с именем userName, а класс действия определен следующим образом:

открытый класс UserAction расширяет ActionSupport реализует ModelDriven

, а UserModel представляет собой POJO следующим образом:

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 и использовании альтернативы это ужасный подход, вы должны определить мелкозернистые модели, которые помещаются в стек значений, а затем скопировать из модели в целевой объект перед отправкой ответа и разрешением транзакции.совершать.

Ответы [ 2 ]

1 голос
/ 08 ноября 2010

Ваш архитектор прав: размещение объектов с доступом к конфиденциальной информации в ValueStack создает потенциальную угрозу безопасности.Вредоносный пользователь действительно может сбросить пароль с помощью вышеуказанной атаки.

НО:

Поскольку он является архитектором, он должен был придумать способы для правильной проверки / ограничения входных параметров.Используя ParamsInterceptor в Struts2, довольно просто разрешить передачу только определенных параметров в действие.Таким образом, не ваша работа - отстой, а архитектура вашей системы.Разработчики должны иметь возможность сосредоточиться на реализации бизнес-логики.Инфраструктура должна быть предоставлена ​​архитектором.

Cheers,

w

0 голосов
/ 12 декабря 2013

Перехватчик ModelDriven является слепым

Да. Интерфейс модели может быть источником проблем безопасности, если вы не обработаете входящие параметры, вы столкнетесь с дырами в безопасности.

Вы должны использовать параметр-перехватчик.

В Struts.xml измените ваш перехватчик params на:

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

Затем в своем действии внедрите ParameterNameAware и напишите acceptableParameterName.

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;
    }

}  

Это важно, если ваш пользователь pojo обладает множеством других свойств и только некоторые из них должны быть получены от пользователя.

Если вы используете множество действий ModelDriven, вы можете сделать их общими.

Создать базовое действие, которое расширяет ParameterNameAware. Затем попробуйте разработать общий подход, чтобы получить список ваших действий и допустимых параметров:

Мы использовали пружину, чтобы прочитать список действий и их приемлемых параметров. Весной xml мы добавили:

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

actions-valid-parameters.properties как:

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

Подсказка, если у Address Object есть объект Detail, и вы хотите заполнить некоторые свойства в объекте Detail, убедитесь, что вы включили «деталь» в приведенный выше список.

Действие как

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;
    }

}

Теперь запишите ваши действия как

  public class UserAction extends BaseActionSupport implements  
        ModelDriven<User>{


}
...