Forbidden Error When Submitting Simple PHP Form
Asked Answered
K

7

6

I have a non complicated issue......that seems to be more complicated than it should be.

I have a simple form that is used to add content to a website. Some of the fields need to have html inputted into them. However, when you input certain html elements into the different parts of the form, it decides that it hates you and throws a forbidden 403 error. Here is the form below:

<?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>

I have other forms that follow this same pattern without any trouble. To further make this even more confusing, it will only throw this error when any 2 html elements are supplied in the text area (it handles one html element just fine). The text areas are ads, keywords, salaries, and jobs. The other text areas will take it just fine, but these 4 won't. If I can make this one more bit confusing, if I simple enter in text in those fields and save it, it runs without a problem.

To handle the post data, I only use mysql_real_escape_string() to handle the data, I don't do a strip_tags() as I need the html in there.

Is this a weird apache error that can be fixed with .htaccess? Is there a module in PHP that is conflicting with this?

-------EDIT HERE IS THE ANSWER--------

Ben brought up a fantastic answer that is probably the problem and I cannot fix it because of a lack of privileges. So I created an onsubmit event from an idea that Gerben gave me and wrote the following 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;    
    }

Then on the receiving end, I did a str_replace to replace #@! back to a < and that at least made the thing work.

I'm on a horse....hyaa!

Thanks for all your help. :)

Kikelia answered 11/1, 2012 at 18:18 Comment(10)
Can you also post the code that is in charge of processing the submission? This may be a redirect or error-handler problem generated by the validating php.Persse
Does the url look different when submitting the form, as supposed to the url of the form page itself?Misbegotten
@BenD There really isn't any code in charge of processing the submission. It's a simple foreach statement to run through the $_POST vars and throw a mysql_real_escape_string on them. There isn't any javascript validation. You just hit submit, it loads the same page, it just falls into a switch statement that should land it in the area to update the info. It works for everything else (same foreach statement) on other parts of the site, just not here when multiple html elements are involved.Kikelia
@Misbegotten the only difference in the url is that it is page.php?id=[id]&action=edit where when the form loads it is page.php?id=[id]&action=viewKikelia
the 403 is thrown by apache, so it should not be caused by your php. My guess is that POST is disallowed by your host somehow. This is very rare though.Misbegotten
@Misbegotten the only thing that makes me not think of that is because I can still submit the same form just fine, as long as I don't include html elements in those text fields I mentioned. It submits just fine and updates it in the database. Speaking of the database, all the fields are the same so there is no difference between the 4 that don't work and the others that do work.Kikelia
@Gerben, 403 is normally thrown by apache, but PHP can cause it by (a) intentionally, by sending 403 error headers; or (b) Trigger an apache 403 error by redirecting the page to a forbidden resource. However, given the Firefly's response, it appears to be neither a _POST restriction or a php trigger given what he's describing. I have a thought...Persse
Sorry, I didn't read your question very thoroughly. Try using <?=htmlentities($data['xxxx'])?>Misbegotten
@Misbegotten Thanks for the idea. You have made me a very happy person. If I take you all out for pizza I would....but a thank you will have to do.Kikelia
possible duplicate of 403 Forbidden on form submissionExuberant
P
9

Given that you're able to post, and that your post-handling is apparently extremely simple and so unlikely to be throwing 403 errors or redirecting to forbidden directories, I'm going to hazard a guess that you're running an apache-level firewall. Have a look at your apache config files, and check to see if you're running mod_security or any other firewall module loaded. There are a number of ways mod_security can be configured, including scanning POST data for html content and reacting accordingly. If it is configured to prevent html injection, this may be your issue (see configuration details here: http://www.modsecurity.org/projects/modsecurity/apache/feature_content_injection.html).

To test this, try adding an htaccess file into your web root (assuming you're allowed to override apache settings with htaccess) and setting:

SecFilterEngine Off

Restart apache and then see if it's still happening.

If this is a shared host, or you otherwise don't have the ability to modify apache settings, you can try a workaround using javascript that base64 encodes all the data before submitting (onsubmit), and then base64_decode($_POST[key]) in the php script that processes it.

Persse answered 11/1, 2012 at 20:25 Comment(3)
I'm thinking I can't override that feature. I did phpinfo(); and I didn't see anything about firewall, or mod_security. I tried inputting the code into an htaccess file and it gave me a Internal Server Error 500. It's another clients account and they are using fastwebhost.com which....blocks your IP if you breathe wrong.Kikelia
Thanks for your help. I figured it out with yours and Gerben's help.Kikelia
That's a great idea as well. Mine is more......novice and.....yeah just novice. :)Kikelia
A
6
<IfModule mod_security.c>
  SecFilterEngine Off
  SecFilterScanPOST Off
</IfModule>

Use This Code I Think This Solved Your Problem

Aristocrat answered 11/4, 2018 at 6:53 Comment(1)
this should correct answersSheldonshelduck
S
3
<IfModule mod_security.c>
SecRuleEngine Off
SecRequestBodyAccess Off
</IfModule>

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

after add this on my htaccess file the problem solve.

Stans answered 10/5, 2022 at 11:21 Comment(2)
After adding the below script are there some further action that needs to be done such as restarting the PHP.Bandaid
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Lash
T
2

Just had the same sort of issue on submit showed 403 error but for me it was simple because the form was too big triggering a rule on mod_security.

Also worth increasing php.ini post_max_size and test size using: $_SERVER['CONTENT_LENGTH']

Traynor answered 29/7, 2014 at 10:10 Comment(0)
M
2

In my case, disabling MOD security in cPanel solved the issue for me.

Maracaibo answered 22/6, 2019 at 14:50 Comment(0)
C
1

Might be abit late, but I faced a similar problem today while trying to submit a form through POST. It would not allow me to submit a text with a link and would throw a 403 Forbidden Acess Denied error. Disabling modsecurity (I did this from the control panel) solved it!

Composer answered 24/7, 2017 at 23:31 Comment(0)
G
1

The issue is caused by the Apache Firewall mod, it can also be fixed via .htaccess file if you cannot or dont want to edit the httpd.conf.

Create or edit the existing .htaccess file in the directory where the script is called (usually where the index.php is) and add the following lines:

<IfModule mod_security.c>
#SecRuleEngine Off
SecRequestBodyAccess Off
</IfModule>
Gastrolith answered 7/3, 2019 at 12:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.