CKeditor 在提交某些 html 标签时返回 403

Posted

技术标签:

【中文标题】CKeditor 在提交某些 html 标签时返回 403【英文标题】:CKeditor returning 403 when submitting certain html tags 【发布时间】:2013-05-17 09:10:52 【问题描述】:

我创建了一个页面,其中有两个输入文本区域,我将 CKeditor(版本 4)添加到它们。

第一个编辑器工作正常,我在 config.js 中设置了 config.allowedContent = true; 以停止剥离 <script> 之类的标签,并且一切正常。 我在它下面有另一个编辑器,相同的设置,相同的设置,我只是更改了 textarea 字段的 ID。当我提交普通文本时它可以工作,但是一旦我添加一个<script> 标签,例如,并按下编辑器所在表单的提交按钮,它似乎重新加载页面,不提交任何数据firebug 告诉我服务器返回 403。

我尝试隔离编辑器,添加个人配置。没有。第一个 textarea 就像一个魅力,如果文本中有 unsafe 标签,第二个返回 403。

我的设置如下,我使用这个ckeditor helper 在我需要的地方插入编辑器。如您所料,页面是使用 CodeIgniter 创建的。 我在 ckeditor 文件夹中有一个 config.js 文件。 我使用的是常规形式,没什么好看的。看起来像这样

<form action="http://domain.com/admin/articles/edit/47" method="post">
    <div id="cke_ckeditor_en_container">
        <textarea cols="75" rows="7" id="ckeditor_en" name="text_en" class="input-text is-col-text"><?php echo set_value('text_en', isset($text_en) ? htmlspecialchars_decode($text_en) : ''); ?></textarea>
        <?php echo display_ckeditor($ckeditor_en); ?>
    </div>
    <input type="submit" value="submit" />
</form>

表单有另一个编辑器的html的另一部分是相同的,改变了id和其他属性,还有一个复选框,没有任何关系。

在我的控制器中得到了这个

public function edit()
    $this->load->helper('ckeditor');
    $id = (int)$this->uri->segment(4);

    if (empty($id))
        $this->session->set_flashdata('error', 'Empty ID!');
        redirect('admin/articles');
    

    $data = $this->articles_model->fetch_article($id);

    $data['page_title'] = "Edit `" . $data['title'] . "`";
    $data['form_url'] = "admin/articles/edit/" . $id;

    $data['ckeditor'] = array(
        'id'    =>  'ckeditor',
        'path'  =>  'js/ckeditor');
    $data['ckeditor_en'] = array(
        'id'    =>  'ckeditor_en',
        'path'  =>  'js/ckeditor');

    $data['edit'] = true;   

    if($this->input->post('submit'))
        $this->save_article("update",$id);
    


    $this->load->view("admin/articles",$data);


private function save_article($type='insert', $id=0)
    $this->load->library('form_validation');

    $this->form_validation->set_rules('title','Title','trim|xss_clean|max_length[150]|min_length[1]');          
    $this->form_validation->set_rules('text','Text','trim');

    $this->form_validation->set_rules('title_en','Title EN','trim|xss_clean|max_length[150]|min_length[1]');            
    $this->form_validation->set_rules('text_en','Text EN','trim');

    $this->form_validation->set_rules('top_menu','Show in top menu','trim|xss_clean|max_length[1]');            


    if ($this->form_validation->run() === FALSE)
    
        return FALSE;
    

    // make sure we only pass in the fields we want

    $data = array();
    $data['title']       = $this->input->post('title');
    $data['text']        = htmlspecialchars($this->input->post('text'));

    $data['title_en']       = $this->input->post('title_en');
    $data['text_en']        = htmlspecialchars($this->input->post('text_en'));

    $data['url']               = $this->toAscii($this->input->post('title'));
    $data['url_en']            = $this->toAscii($this->input->post('title_en'));

    $data['top_menu']        = $this->input->post('top_menu');

    if($type == "insert")
        $data['time']           = date("YmdHis");
    


    if ($type == 'insert')
        if($this->articles_model->insert($data))
            $this->session->set_flashdata('success', 'Article added successfully!');
        else
            $this->session->set_flashdata('error', 'An error occured!');
        
    else if ($type == 'update')
        if($this->articles_model->update($id, $data))
            $this->session->set_flashdata('success', 'Article `' . $data['title'] . '` edited successfully!');
        else
            $this->session->set_flashdata('error', 'An error ecc!');
        
    
    redirect("admin/articles");


确切地说,与我的代码的安全性或不安全性无关

编辑 为ckeditor添加config.js

CKEDITOR.editorConfig = function( config ) 

    config.filebrowserBrowseUrl = '/js/kcfinder/browse.php?type=files';
    config.filebrowserImageBrowseUrl = '/js/kcfinder/browse.php?type=images';
    config.filebrowserFlashBrowseUrl = '/js/kcfinder/browse.php?type=flash';
    config.filebrowserUploadUrl = '/js/kcfinder/upload.php?type=files';
    config.filebrowserImageUploadUrl = '/js/kcfinder/upload.php?type=images';
    config.filebrowserFlashUploadUrl = '/js/kcfinder/upload.php?type=flash';

    config.removeButtons = 'Underline,Subscript,Superscript';
    config.allowedContent = true;
    // Se the most common block elements.
    config.format_tags = 'p;h1;h2;h3;pre';

    // Make dialogs simpler.
    config.removeDialogTabs = 'image:advanced;link:advanced';
;

我一头雾水,一头雾水,我对该怎么做没有个想法。好像单输入被诅咒了。

感谢您的帮助。

【问题讨论】:

你能发布所有相关的控制器和查看代码吗?你在两个文本区域都使用ckeditor_en 吗? ID 是独一无二的,我认为它甚至不适用于重复的 ID。稍后我会发布代码。 所以要明确一点:第一个编辑器可以正确处理不允许的文本(例如&lt;script&gt;),而第二个不能? 403 是 forbidden 错误。你能检查一下网络请求(开发者工具/firebug),看看是哪个抛出了错误吗? 您的服务器是如何配置的? IIRC、Apache mod_security 以及可能许多其他类似的此类工具,如果它看到它真的不喜欢的东西,将抛出 403,可能例如 POST 内容中的 &lt;script&gt; 标签。一个快速的一线测试是完全禁用 ckEditor,看看你是否通过纯文本区域提交相同的结果;如果是这样,您知道 ckEditor 没有错,是时候开始查看您的服务器配置了。 Mod_security!我或多或少只是读过它,结果发现造成麻烦的事情。我仍然对为什么第一次输入没有触发它感到困惑。我让我的主人检查是否有问题,他们确认了。非常感谢 sortmdrain 和 Aaron 的时间和耐心!如果您将评论作为答案发表,我可以接受。 【参考方案1】:

这将是您的 mod_security 规则的结果。根据它们的严格程度,它们有助于更好地保护脚本免受漏洞的攻击,通常是那些通过 POST 被利用的漏洞。

【讨论】:

【参考方案2】:

据我了解,您正在尝试向您的第二个文本区域添加一些内容。并且 CKEditor 删除了一些“不安全”的标签。我不会很安全,但这可以帮助你:

config.extraAllowedContent = '**';

您将把它添加到您的 config.js 中。此代码可让您添加任何您想要的内容。 CKEditor 不会删除“不安全”标签。

Documenation for this method

【讨论】:

以上是关于CKeditor 在提交某些 html 标签时返回 403的主要内容,如果未能解决你的问题,请参考以下文章

使用CKEditor,提交内容到数据库,再取回时,显示出来的是html代码,请问怎么只显示文字效果?

ckeditor后显示的html标签

jeecg <t:ckeditor ajax form表单提交 获取不到值问题解决

如何在 CKEditor 中定义允许的标签?

ckeditor html标签的class 等attribute属性都被屏蔽啦,替换成空的解决方案

CKEDITOR 在首次提交时不通过 ajax 提交数据