形式动作中反映的XSS - 形成动作最佳实践

时间:2013-11-11 12:39:27

标签: php html forms xss

我刚收到一份报告,指出由于我负责的php / IIS网络应用程序中的Reflected XSS导致PCI合规性扫描失败。

可利用的样本:

GET /login/recover/en?alert('TK00000105') HTTP/1.1

证据:

<form id='recover_form_1' method='post'  action='https://www.somebody.com/login/recover/en?alert('TK00000105')' enctype='multipart/form-data'> 

输出由表单类生成,如果没有提供完整操作(JavaScript增强功能和HTML5验证),它最近获得了提供完整操作的功能。此操作是包含查询字符串的完整URL(或多或少)。通常,查询字符串实际上是加载实际页面的指示因素(它并不是全部友好!),所以我不能盲目地从URL中删除查询。

我应该如何(你如何),为表单行为清理url,应该过滤的实际危险载体是什么?

剥离html标签是否足够,或者是修补此标签的唯一真正方法是使表单的每次使用都能提供特定的操作?

------------------编辑表单创建的详细信息------------------------ -

构造和打开表单标记生成如下:

public function __construct( $id = false, $method = 'post', $action = '', $class= '')
    {        
        $this->_method = strtolower($method);
        $this->_action = $action;
        $this->_class =  $class;

        if ($id == false) 
        {
            FormEX::$_numForms++;
            $this->_id = 'form_'.FormEX::$_numForms."";
        } 
        else 
        {
            $this->_id = $id;
        }

        FormEX::Persist($this);
        $this->Controls = new \Collection(__NAMESPACE__.'\HTMLControl');
    }

...

     public function StartForm()
        {
            $action = $this->_action != '' ? $this->_action : $this->GenerateAction();
            $class = $this->_class != '' ? " class ='{$this->_class}'" : '';
            $enc = $this->_formEnctype != '' ? $this->_formEnctype : 'multipart/form-data';
            return "<form id='{$this->getID()}' method='{$this->_method}' $class action='$action' enctype='$enc'>";
        }

您可以在控制器(或视图后面的其他位置)创建表单,并在视图中使用以下内容:

<?if($this->form != null): ?>
    <?= $this->form->StartForm(); ?>
    <fieldset id="<?= $this->form->getID(); ?>">
        <div class='input'>
            <?= $this->form->_rc('Confirm'); ?>
            <?= $this->form->_rc('Cancel'); ?>
        </div>
    </fieldset>
    <?= $this->form->EndForm(); ?>
<?endif ?>

---------------------编辑 - 感谢Marek ---------------------- ---------

因此,一项改进是确保对url进行编码,同时在输出点对所有开发人员可写属性进行防御性编码。

_s()是我们库中htmlentities($value, ENT_QUOTES, 'utf-8')的编码快捷方式。

public function StartForm()
{
    $action = $this->_action != '' ? $this->_action : $this->GenerateAction();
    $class = $this->_class != '' ? " class ='{$this->_class}'" : '';
    $enc = $this->_formEnctype != '' ? $this->_formEnctype : 'multipart/form-data';
    $formTag = "<form id='" . _s($this->getID()) . "' method='" . _s($this->_method) . "' $class action='" . _s($action) . "' enctype='" . _s($enc) . "'>";
    return $formTag;
} 

关于我的问题,还有什么我应该注意的吗?

感谢。

1 个答案:

答案 0 :(得分:2)

该库是可利用的,它无法正确转义单引号,它用于引用属性。 htmlspecialchars不会使用默认参数转义单引号(我希望库使用它)。表单标记应该是以下之一:

<form id='recover_form_1' method='post'  action='https://www.somebody.com/login/recover/en?alert(&#039;TK00000105&#039;)' enctype='multipart/form-data'>

<form id="recover_form_1" method="post"  action="https://www.somebody.com/login/recover/en?alert('TK00000105')" enctype="multipart/form-data">

第一个将ENT_QUOTES标志添加到htmlspecialchars,第二个使用双引号,并按原样保留单个。

您现在应该修复库并通知开发人员。