CHtml::clientChange(). Межсайтовый скриптинг?

Предварительное обсуждение найденных ошибок перед отправкой их авторам фреймворка, а также внесение новых предложений.
Ответить
Аватара пользователя
zolton007
Сообщения: 180
Зарегистрирован: 2013.08.16, 08:43
Откуда: Воронеж

CHtml::clientChange(). Межсайтовый скриптинг?

Сообщение zolton007 »

Обнаружилась следующая фигня.
Имеются страницы редактирования. Например, вот (не обязательно сразу всматриваться в этот листинг, сначала прочитайте до конца):

Код: Выделить всё

<?php
/* @var $this OperationController|TaskController|RoleController */
/* @var $model AuthItemForm */
/* @var $item CAuthItem */
/* @var $form СActiveForm */

$this->breadcrumbs = array(
    $this->capitalize($this->getTypeText(true)) => array('index'),
    $item->description => array('view', 'name' => CHtml::encode($item->name)),
    Yii::t('AuthModule.main', 'Edit'),
);
?>

<h1>
    <?php echo CHtml::encode($item->description); ?>
    <small><?php echo $this->getTypeText(); ?></small>
</h1>

<?php
    $form = $this->beginWidget('CActiveForm', array(
        'htmlOptions' => array(
            'role' => 'form',
            'class' => 'form-horizontal'
        )
    ));
?>

<?php
    echo $form->hiddenField($model, 'type');
?>

<div class="form-group">
    <?php echo $form->labelEx($model, 'name', array('class' => 'col-sm-2 control-label'));?>
    <div class="col-sm-10">
        <?php
            echo $form->textField($model, 'name', array(
                'disabled'=>true,
                'title'=>Yii::t('AuthModule.main', 'System name cannot be changed after creation.'),
                'class' => 'form-control'
            ));
        ?>
    </div>
</div>

<div class="form-group">
    <?php echo $form->labelEx($model, 'description', array('class' => 'col-sm-2 control-label'));?>
    <div class="col-sm-10">
        <?php echo $form->textField($model, 'description', array('class' => 'form-control'));?>
    </div>
</div>

<div class="form-group">
    <?php echo $form->labelEx($model, 'bizrule', array('class' => 'col-sm-2 control-label'));?>
    <div class="col-sm-10">
        <?php echo $form->textField($model, 'bizrule', array('class' => 'form-control'));?>
    </div>
</div>

<div class="form-actions">
    <?php echo CHtml::submitButton(Yii::t('AuthModule.main', 'Save'), array('class'=>'btn btn-success'));?>
    <?php echo CHtml::linkButton(Yii::t('AuthModule.main', 'Cancel'), array('view', 'name' => $item->name), array('class'=>'btn btn-default'));?>
</div>

<?php $this->endWidget(); ?>
Это форма редактирования роли из переделанного модуля yii-auth. Суть в следующем: если создать роль с именем '+alert("Привет")+' при последующем её редактировании будет вылазить алерт привет :) и во вьюхе это не поправить, поскольку вылазит оно при помощи CHtml.php
в коде представленном далее приведены задействованные в этом процессе куски кода:

Код: Выделить всё

protected static function clientChange($event,&$htmlOptions)
…
  if(isset($htmlOptions['id']))
    $id=$htmlOptions['id'];
  else
    //см. $id, $htmlOptions['name']
    $id=$htmlOptions['id']=isset($htmlOptions['name'])?$htmlOptions['name']:self::ID_PREFIX.self::$count++;
…
  if($live)
    //см. $id
    $cs->registerScript('Yii.CHtml.#' . $id,"jQuery('body').on('$event','#$id',function(){{$handler}});");
  else
    //см. $id
    $cs->registerScript('Yii.CHtml.#' . $id,"jQuery('#$id').on('$event', function(){{$handler}});");
…
Понятно, что решить эту проблему можно по-разному. В том числе поправив строку 2405 файла CHtml следующим образом:

Код: Выделить всё

//см. CHtml::encode($htmlOptions['name'])
$id=$htmlOptions['id']=isset($htmlOptions['name'])?CHtml::encode($htmlOptions['name']):self::ID_PREFIX.self::$count++;
 
чтобы избежать сюрпризов :idea:
Ответить