提交简单PHP表单时出现禁止错误

时间:2012-01-11 18:18:52

标签: php forms .htaccess post http-status-code-403

我有一个非复杂的问题......似乎比应该更复杂。

我有一个简单的表单,用于向网站添加内容。一些字段需要输入html。但是,当您将某些html元素输入到表单的不同部分时,它会决定它讨厌您并抛出禁止的403错误。以下是表格:

<?php
    $data = f("SELECT * FROM table WHERE id = '{$_GET['id']}'");
?>
<form action="<?=$_SERVER['PHP_SELF']?>?id=<?=$_GET['id']?>&action=edit" method="post">
    <table cellspacing="0" cellpadding="2" border="0">
        <tr>
            <td><b>Title:</b></td>
            <td><input type="text" name="title" style="width: 300px;" value="<?=$data['title']?>" /></td>
        </tr>
        <tr>
            <td><b>URL:</b></td>
            <td><input type="text" name="url" style="width: 300px;" value="<?=$data['url']?>" /></td>
        </tr>
        <tr>
            <td><b>Sub-Category:</b></td>
            <td>
                <select name="subCategoryId">
                    <option value=""></option>
                    <option value="1">A</option>
                    <option value="2">B</option>

                </select>
            </td>
        </tr>
        <tr>
            <td><b>Short Description:</b></td>
            <td><textarea name="shortDescription" rows="6" cols="60"><?=$data['shortDescription']?></textarea></td>
        </tr>
        <tr>
            <td><b>Template:</b></td>
            <td><textarea name="template" rows="6" cols="60"><?=$data['template']?></textarea></td>
        </tr>
        <tr>
            <td><b>Ads:</b></td>
            <td><textarea name="ads" rows="6" cols="60"><?=$data['ads']?></textarea></td>
        </tr>
        <tr>
            <td><b>Keywords:</b></td>
            <td><textarea name="keywords" rows="6" cols="60"><?=$data['keywords']?></textarea></td>
        </tr>
        <tr>
            <td><b>Questions:</b></td>
            <td><textarea name="questions" rows="6" cols="60"><?=$data['questions']?></textarea></td>
        </tr>
        <tr>
            <td><b>Salary:</b></td>
            <td><textarea name="salary" rows="6" cols="60"><?=$data['salary']?></textarea></td>
        </tr>
        <tr>
            <td><b>Jobs:</b></td>
            <td><textarea name="jobs" rows="6" cols="60"><?=$data['jobs']?></textarea></td>
        </tr>
        <tr>
            <td><b>Meta Description:</b></td>
            <td><input type="text" name="metaDescription" style="width: 300px;" value="<?=$data['metaDescription']?>" /></td>
        </tr>
        <tr>
            <td><b>Meta Keywords:</b></td>
            <td><input type="text" name="metaKeywords" style="width: 300px;" value="<?=$data['metaKeywords']?>" /></td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td><input type="submit" name="submit" value="Edit Job" /></td>
        </tr>
    </table>
</form>

我有其他形式遵循相同的模式没有任何麻烦。为了进一步使这更令人困惑,它只会在文本区域中提供任何2个html元素时抛出此错误(它处理一个html元素就好了)。文本区域是广告,关键字,工资和工作。其他文本区域会很好,但这4个不会。如果我可以让这个更容易混淆,如果我简单地输入这些字段中的文本并保存它,它运行没有问题。

要处理post数据,我只使用mysql_real_escape_string()来处理数据,我没有做strip_tags(),因为我需要html。

这是一个奇怪的apache错误,可以用.htaccess修复吗? PHP中是否存在与此冲突的模块?

-------编辑在这里是答案--------

Ben提出了一个很棒的答案,这可能是问题所在,由于缺乏特权,我无法修复它。所以我根据Gerben给我的想法创建了一个onsubmit事件,并编写了以下javascript。

function awesome() {
        elements = document.forms[0].elements;
        for(var i = 0; i < elements.length; i++) {
            switch(elements[i].name) {
                case "ads":
                case "shortDescription":
                case "template":
                case "questions":
                case "salary":
                case "jobs":
                    str = elements[i].value;
                    elements[i].value = str.replace(/</g,"#@!");
                    break;
            }
        }
        return true;    
    }

然后在接收端,我做了一个str_replace来取代#@!回到&lt;至少使事情发挥作用。

我骑马...... hyaa!

感谢您的帮助。 :)

6 个答案:

答案 0 :(得分:7)

鉴于您能够发布,并且您的后处理显然非常简单,因此不太可能丢失403错误或重定向到禁止的目录,我会冒险猜测您和#39;重新运行apache级别的防火墙。查看您的apache配置文件,并检查您是否正在运行mod_security或任何其他加载的防火墙模块。可以通过多种方式配置mod_security,包括扫描html内容的POST数据并做出相应的反应。如果它被配置为阻止html注入,这可能是您的问题(请参阅此处的配置详细信息:http://www.modsecurity.org/projects/modsecurity/apache/feature_content_injection.html)。

要对此进行测试,请尝试将htaccess文件添加到您的Web根目录中(假设您允许使用htaccess覆盖apache设置)并设置:

SecFilterEngine Off

重新启动apache,然后查看它是否仍在发生。

如果这是共享主机,或者您无法修改apache设置,则可以在提交之前使用base64 encodes所有数据的javascript尝试解决方法(onsubmit),然后在处理它的php脚本中的base64_decode($ _ POST [key])。

答案 1 :(得分:2)

刚才有同样的问题提交显示403错误,但对我来说这很简单,因为表单太大触发了对mod_security的规则。

还值得增加php.ini post_max_size并测试大小:$_SERVER['CONTENT_LENGTH']

答案 2 :(得分:2)

<IfModule mod_security.c>
  SecFilterEngine Off
  SecFilterScanPOST Off
</IfModule>

使用此代码我认为这解决了您的问题

答案 3 :(得分:0)

可能会迟到,但我在尝试通过POST提交表单时遇到了类似的问题。它不允许我提交带有链接的文本,并会抛出403 Forbidden Acess Denied错误。 禁用modsecurity(我是通过控制面板完成的)解决了它!

答案 4 :(得分:0)

该问题是由Apache Firewall mod引起的,如果您不能或不想编辑httpd.conf,也可以通过.htaccess文件修复此问题。

在调用脚本的目录(通常是index.php所在的目录)中创建或编辑现有的.htaccess文件,并添加以下几行:

<IfModule mod_security.c>
#SecRuleEngine Off
SecRequestBodyAccess Off
</IfModule>

答案 5 :(得分:0)

就我而言,在cPanel中禁用MOD安全性为我解决了这个问题。