ข้อผิดพลาดที่ต้องห้ามเมื่อส่งแบบฟอร์ม PHP อย่างง่าย

ฉันมีปัญหาที่ไม่ซับซ้อน......ซึ่งดูเหมือนจะซับซ้อนกว่าที่ควรจะเป็น

ฉันมีแบบฟอร์มง่ายๆที่ใช้เพื่อเพิ่มเนื้อหาลงในเว็บไซต์ บางฟิลด์จำเป็นต้องใส่ 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>

ฉันมีรูปแบบอื่นที่เป็นไปตามรูปแบบเดียวกันนี้โดยไม่มีปัญหาใดๆ เพื่อให้เกิดความสับสนมากยิ่งขึ้น ระบบจะโยนข้อผิดพลาดนี้เมื่อมีการระบุองค์ประกอบ html 2 รายการในพื้นที่ข้อความเท่านั้น (รองรับองค์ประกอบ html หนึ่งรายการได้ดี) พื้นที่ข้อความ ได้แก่ โฆษณา คำสำคัญ เงินเดือน และงาน พื้นที่ข้อความอื่นๆ ก็พอใช้ได้ แต่ 4 อย่างนี้ไม่ได้ผล ถ้าฉันสามารถทำให้สิ่งนี้สับสนมากขึ้นอีกหน่อย ถ้าฉันป้อนข้อความในช่องเหล่านั้นแล้วบันทึก มันก็จะทำงานได้โดยไม่มีปัญหา

ในการจัดการข้อมูลที่โพสต์ ฉันใช้เฉพาะ mysql_real_escape_string() เพื่อจัดการข้อมูล ฉันไม่ได้ทำ strip_tags() เนื่องจากฉันต้องการ html ในนั้น

นี่เป็นข้อผิดพลาด apache แปลก ๆ ที่สามารถแก้ไขได้ด้วย .htaccess หรือไม่ มีโมดูลใน PHP ที่ขัดแย้งกับสิ่งนี้หรือไม่?

------- แก้ไข นี่คือคำตอบ ---------

เบ็นเสนอคำตอบที่ยอดเยี่ยมซึ่งอาจเป็นปัญหา และฉันไม่สามารถแก้ไขได้เนื่องจากขาดสิทธิพิเศษ ดังนั้นฉันจึงสร้างกิจกรรม onsubmit จากแนวคิดที่ Gerben มอบให้ฉันและเขียนจาวาสคริปต์ต่อไปนี้

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 เพื่อแทนที่ #@! กลับไปที่ ‹ และอย่างน้อยนั่นก็ทำให้สิ่งนี้ได้ผล

ฉันขี่ม้าแล้ว....ฮ้า!

ขอบคุณสำหรับความช่วยเหลือทั้งหมดของคุณ :)


person n0nag0n    schedule 11.01.2012    source แหล่งที่มา
comment
คุณสามารถโพสต์รหัสที่รับผิดชอบในการประมวลผลการส่งได้หรือไม่ นี่อาจเป็นปัญหาการเปลี่ยนเส้นทางหรือตัวจัดการข้อผิดพลาดที่สร้างโดยการตรวจสอบความถูกต้องของ php   -  person Ben D    schedule 11.01.2012
comment
URL ดูแตกต่างออกไปเมื่อส่งแบบฟอร์ม ตามที่ควรจะเป็นกับ URL ของหน้าแบบฟอร์มหรือไม่   -  person Gerben    schedule 11.01.2012
comment
@BenD ไม่มีรหัสใด ๆ ที่รับผิดชอบในการประมวลผลการส่ง เป็นคำสั่ง foreach ง่ายๆ ที่จะเรียกใช้ผ่าน $_POST vars และส่ง mysql_real_escape_string ลงไป ไม่มีการตรวจสอบความถูกต้องของจาวาสคริปต์ คุณเพิ่งกดส่ง มันจะโหลดหน้าเดียวกัน มันแค่อยู่ในคำสั่ง switch ที่ควรลงจอดในพื้นที่เพื่ออัปเดตข้อมูล มันใช้งานได้กับทุกสิ่ง (คำสั่ง foreach เดียวกัน) ในส่วนอื่น ๆ ของเว็บไซต์ เพียงแต่ไม่ใช่ที่นี่เมื่อมีองค์ประกอบ html หลายรายการเข้ามาเกี่ยวข้อง   -  person n0nag0n    schedule 11.01.2012
comment
@Gerben ข้อแตกต่างเพียงอย่างเดียวใน url ก็คือ page.php?id=[id]&action=edit โดยที่เมื่อโหลดแบบฟอร์มจะเป็น page.php?id=[id]&action=view   -  person n0nag0n    schedule 11.01.2012
comment
403 ถูกโยนโดย apache ดังนั้นจึงไม่ควรเกิดจาก php ของคุณ ฉันเดาว่า POST ไม่ได้รับอนุญาตจากโฮสต์ของคุณในทางใดทางหนึ่ง แม้ว่านี่จะหายากมากก็ตาม   -  person Gerben    schedule 11.01.2012
comment
@Gerben สิ่งเดียวที่ทำให้ฉันไม่คิดว่าเป็นเพราะฉันยังสามารถส่งแบบฟอร์มเดียวกันได้ดีตราบใดที่ฉันไม่ได้รวมองค์ประกอบ html ในช่องข้อความที่ฉันพูดถึง มันส่งได้ดีและอัพเดตในฐานข้อมูล เมื่อพูดถึงฐานข้อมูล ทุกฟิลด์จะเหมือนกัน ดังนั้นจึงไม่มีความแตกต่างระหว่าง 4 ฟิลด์ที่ใช้งานไม่ได้กับฟิลด์อื่นๆ ที่ใช้งานไม่ได้   -  person n0nag0n    schedule 11.01.2012
comment
@Gerben ปกติแล้ว 403 จะถูกโยนโดย apache แต่ PHP สามารถทำให้เกิดมันได้โดย (a) โดยเจตนาโดยการส่งส่วนหัวข้อผิดพลาด 403; หรือ (b) ทำให้เกิดข้อผิดพลาด apache 403 โดยเปลี่ยนเส้นทางเพจไปยังทรัพยากรที่ต้องห้าม อย่างไรก็ตาม จากการตอบสนองของ Firefly ดูเหมือนว่าจะไม่ใช่ทั้งข้อจำกัด _POST หรือทริกเกอร์ php เมื่อพิจารณาจากสิ่งที่เขาอธิบาย ฉันมีความคิด...   -  person Ben D    schedule 12.01.2012
comment
ขออภัย ฉันไม่ได้อ่านคำถามของคุณอย่างละเอียด ลองใช้ <?=htmlentities($data['xxxx'])?>   -  person Gerben    schedule 12.01.2012
comment
@Gerben ขอบคุณสำหรับความคิด คุณทำให้ฉันเป็นคนที่มีความสุขมาก ถ้าฉันพาคุณไปกินพิซซ่า ฉันจะ....แต่คุณจะต้องทำเพื่อขอบคุณ   -  person n0nag0n    schedule 12.01.2012
comment
เป็นไปได้ที่ซ้ำกันของ 403 ห้ามในการส่งแบบฟอร์ม   -  person T.Todua    schedule 31.03.2015


คำตอบ (6)


เนื่องจากคุณสามารถโพสต์ได้ และเห็นได้ชัดว่าการจัดการหลังของคุณนั้นง่ายมาก และไม่น่าที่จะเกิดข้อผิดพลาด 403 หรือเปลี่ยนเส้นทางไปยังไดเร็กทอรีที่ต้องห้าม ฉันจะเสี่ยงต่อการเดาว่าคุณกำลังใช้งานระดับ apache ไฟร์วอลล์ ดูไฟล์กำหนดค่า Apache ของคุณ และตรวจดูว่าคุณกำลังใช้งาน mod_security หรือโหลดโมดูลไฟร์วอลล์อื่นๆ อยู่หรือไม่ สามารถกำหนดค่า mod_security ได้หลายวิธี รวมถึงการสแกนข้อมูล POST เพื่อหาเนื้อหา html และตอบสนองตามนั้น หากมีการกำหนดค่าเพื่อป้องกันการแทรก html นี่อาจเป็นปัญหาของคุณ (ดูรายละเอียดการกำหนดค่าที่นี่: http://www.modsecurity.org/projects/modsecurity/apache/feature_content_injection.html)

หากต้องการทดสอบ ให้ลองเพิ่มไฟล์ htaccess ลงในเว็บรูทของคุณ (สมมติว่าคุณได้รับอนุญาตให้แทนที่การตั้งค่า apache ด้วย htaccess) และตั้งค่า:

SecFilterEngine Off

รีสตาร์ท apache แล้วดูว่ายังเกิดขึ้นอยู่หรือไม่

หากนี่คือโฮสต์ที่ใช้ร่วมกัน หรือคุณไม่สามารถแก้ไขการตั้งค่า apache ได้ คุณสามารถลองวิธีแก้ปัญหาโดยใช้จาวาสคริปต์ที่ base64 เข้ารหัสข้อมูลทั้งหมดก่อนที่จะส่ง (เมื่อส่ง) จากนั้น base64_decode($_POST[key]) ในสคริปต์ php ที่ประมวลผลข้อมูลนั้น

person Ben D    schedule 11.01.2012
comment
ฉันคิดว่าฉันไม่สามารถแทนที่คุณสมบัตินั้นได้ ฉันทำ phpinfo(); และฉันไม่เห็นอะไรเกี่ยวกับไฟร์วอลล์หรือ mod_security ฉันพยายามป้อนรหัสลงในไฟล์ htaccess และมันทำให้ฉันมีข้อผิดพลาดเซิร์ฟเวอร์ภายใน 500 เป็นบัญชีลูกค้าอื่นและพวกเขาใช้ fastwebhost.com ซึ่ง....บล็อก IP ของคุณหากคุณหายใจผิด - person n0nag0n; 12.01.2012
comment
ขอบคุณสำหรับความช่วยเหลือของคุณ. ฉันคิดออกแล้วด้วยความช่วยเหลือของคุณและเกอร์เบน - person n0nag0n; 12.01.2012
comment
นั่นเป็นความคิดที่ดีเช่นกัน ของผมเป็นมากกว่า......มือใหม่ และ.....ใช่ครับ แค่มือใหม่ :) - person n0nag0n; 12.01.2012

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

ใช้รหัสนี้ ฉันคิดว่านี่จะช่วยแก้ปัญหาของคุณได้

person Anurag K    schedule 11.04.2018

เพิ่งมีปัญหาประเภทเดียวกันในการส่งซึ่งแสดงข้อผิดพลาด 403 แต่สำหรับฉัน มันง่ายเพราะแบบฟอร์มใหญ่เกินไปที่จะทำให้เกิดกฎใน mod_security

ยังคุ้มค่าที่จะเพิ่ม php.ini post_max_size และขนาดทดสอบโดยใช้: $_SERVER['CONTENT_LENGTH']

person John Magnolia    schedule 29.07.2014

ในกรณีของฉัน การปิดใช้งานความปลอดภัย MOD ใน cPanel ช่วยแก้ไขปัญหาให้ฉันได้

person Mekey Salaria    schedule 22.06.2019

อาจช้าไปหน่อย แต่วันนี้ฉันประสบปัญหาคล้ายกันขณะพยายามส่งแบบฟอร์มผ่าน POST มันจะไม่อนุญาตให้ฉันส่งข้อความพร้อมลิงก์และจะเกิดข้อผิดพลาด 403 Forbidden Acess Denied การปิดการใช้งาน modsecurity (ฉันทำสิ่งนี้จากแผงควบคุม) แก้ไขได้!

person Moses Kirathe    schedule 24.07.2017

ปัญหานี้เกิดจากม็อด Apache Firewall ซึ่งสามารถแก้ไขได้ผ่านไฟล์ .htaccess หากคุณไม่สามารถหรือไม่ต้องการแก้ไข httpd.conf

สร้างหรือแก้ไขไฟล์ .htaccess ที่มีอยู่ในไดเร็กทอรีที่มีการเรียกใช้สคริปต์ (โดยปกติจะเป็นที่ที่ index.php อยู่) และเพิ่มบรรทัดต่อไปนี้:

<IfModule mod_security.c>
#SecRuleEngine Off
SecRequestBodyAccess Off
</IfModule>
person sax    schedule 07.03.2019