我有一个非复杂的问题......似乎比应该更复杂。
我有一个简单的表单,用于向网站添加内容。一些字段需要输入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> </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!
感谢您的帮助。 :)
答案 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安全性为我解决了这个问题。