|
สิ่งที่ทุกคนต้องรู้ ในการเขียนโปรแกรมแสดงผลในรูปแบบ HTML (ทำเว็บไซต์) ด้วย PHP หากไม่อยากให้ระบบที่เขียนนั้นถูก HACK ได้ !!! |
ติดตามบทความล่าสุดของผู้เขียนได้ที่ phpinfo() Facebook Page
สิ่งที่ทุกคนต้องรู้ ในการเขียนโปรแกรมแสดงผลในรูปแบบ HTML (ทำเว็บไซต์) ด้วย PHP หากไม่อยากให้ระบบที่เขียนนั้นถูก HACK ได้ !!!
คงเป็นที่ทราบกันดีอยู่แล้วว่า HTML/XML มีรูปแบบอย่างไร
<b> tag เปิด
<a href="https://www.thaicreate.com"> tag เปิดที่มี attribute
<a href='https://www.thaicreate.com'> tag เปิดที่มี attribute แบบใช้ ' เป็นเครื่องหมายเปิดและปิด
</a> tag ปิด
<br /> empty tag
<img src="images/test.jpg" /> empty tag ที่มี attribute
entity reference
จะสังเกตเห็นได้ว่า ตัวอักษรที่สำคัญ ที่ทำให้มองว่าเป็น HTML/XML นั้นได้แก่
< เครื่องหมายน้อยกว่า entity reference คือ <
> เครื่องหมายมากกว่า entity reference คือ >
" เครื่องหมายคำพูด entity reference คือ "
' เครื่องหมายคำพูด entity reference คือ ' หรือ '
& แอมเพอร์แซนด์ entity reference คือ &
ซึ่งหากเราจะใช้ตัวอักษรเหล่านี้ใน HTML เรา "ควรใช้" entity reference
และ "ต้องใช้" ใน XML สำหรับ < และ &
เช่น
น่ารักจุงเบย ><
อยากกินเค้ก S&P อ่ะ
<img title="นี่คือภาพวาดที่สวย "ที่สุด" ในโลก" src="images/painting.jpg" />
PHP มีฟังก์ชั่นที่จะช่วยแปลงตัวอักษรพิเศษเหล่านี้ให้เป็น entity reference นั่นก็คือฟังก์ชั่นที่มีชื่อน่าเกลียดที่สุดในโลก htmlspecialchars() นั่นเอง โดยมีรูปแบบการใช้
htmlspecialchars($string [, $flags [, [$encoding [, $double_encode]]])
$string คือค่าที่ต้องการจะแปลง เป็นชนิดสตริง
$flags คือตัวเลือกที่จะกำหนดว่าจะแปลงอะไรบ้าง โดยมีค่าคงที่ที่ควรรู้ดังนี้
- ENT_COMPAT จะแปลง " แต่ปล่อย ' ไว้เหมือนเดิม
- ENT_QUOTES จะแปลงทั้ง " และ '
- ENT_NOQUOTES ไม่แปลงทั้ง " และ '
หากไม่กำหนด ค่าปกติคือ ENT_COMPAT
$encoding คือ encoding ที่ใช้ในการค้นหาตัวอักษรเพื่อแปลง หากไม่กำหนด ค่าปกติคือ 'ISO-8859-1' (แต่เป็น 'UTF-8' ใน PHP 5.4+)
$double_encode หากเป็น true จะแปลง & ทุกตัวที่เจอให้เป็น & โดยไม่สนว่าหลัง & นั้นๆ มันเป็น entity reference อยู่แล้วหรือไม่
เช่น " จะกลายเป็น &quot;
ค่าปกติคือ true
echo htmlspecialchars('1 < 10'); // 1 < 10
echo htmlspecialchars('100 > 10'); // 100 > 10
echo htmlspecialchars('A&W'); // A&W
echo htmlspecialchars('PHP, which stands for "PHP: Hypertext Preprocessor"'); // PHP, which stands for "PHP: Hypertext Preprocessor"
echo htmlspecialchars("I'm a boy."); // I'm a boy.
echo htmlspecialchars("I'm not a girl.", ENT_QUOTES); // I'm a girl.
echo htmlspecialchars('สวัสดี "ชาวโลก"', ENT_COMPAT, 'UTF-8');
// $double_encode = true จะทำการแปลง & ซ้ำ แม้จะเป็น entity reference อยู่แล้ว
// สวัสดี &quot;ชาวโลก&quot;
echo htmlspecialchars('สวัสดี "ชาวโลก"', ENT_COMPAT, 'UTF-8', false);
// $double_encode = false จะไม่แปลง entity reference ซ้ำ
// สวัสดี "ชาวโลก"
ทำไมต้องใช้?
อาจจะสงสัยกันว่าที่บ่นมายืดยาวนี่เพื่ออะไร เกี่ยวกับการป้องกันการ HACK อย่างไร
สมมติว่าเราเขียนเว็บบอร์ด ซึ่งโดยพื้นฐานเป็นโปรแกรมที่ต้องรับค่ามาจากผู้ใช้ ไม่ว่าจะเป็นข้อความ หรือชื่อ
และผู้ใช้พิมพ์ข้อความที่มี HTML Tag หรือ javascript และเรา output ค่าที่รับมาออกไปตรงๆ โดยไม่ผ่าน htmlspecialchars() ก็จะทำให้เกิดผลที่ไม่คาดคิด
<?php while (($row = mysql_fetch_assoc($result))): ?>
<div class="message">
<?php echo $row['message']; ?>
<hr />
<?php echo $row['username']; ?>
</div>
<?php endwhile; ?>
จากโค้ดตัวอย่างข้างบน ซึ่งเป็นโค้ดที่จะแสดงข้อความของผู้ใช้จากฐานข้อมูล
หากมีผู้ใช้สักคนตั้งกระทู้และพิมพ์ข้อความแบบนี้
อยากทราบว่าจะเริ่มต้นศึกษา PHP ได้อย่างไร
<hr />
มือใหม่
</div>
<div class="message">
คุณนี่มันโง่จริงๆ
<hr />
webmaster
</div>
<div class="message">
อ้าว ทำไมเว็บมาสเตอร์พูดอย่างนี้ล่ะครับ T T
ก็จะสามารถจัดรูปแบบให้ดูเหมือนมีคนหลายคนกำลังคุยโต้ตอบกันได้
หรือหากมีใครพิมพ์ข้อความแบบนี้
<script>while(true)alert("555");</script>
จะทำให้มี alert popup โผล่ขึ้นมาไม่รู้จบเมื่อเปิดกระทู้นั้นดู
การกระทำแบบนี้เรียกว่า XSS (Cross-site scripting)
ดังนั้นเวลาที่จะแสดงผลข้อมูลที่รับมาจากผู้ใช้
หากข้อมูลนั้นไม่ได้มีรูปแบบที่แน่ชัด เช่น id หรือ วันที่
เราควรที่จะต้องใช้ htmlspecialchars() เพื่อแปลงตัวอักษรพิเศษให้เป็น entity reference
แม้แต่ข้อมูลที่สั้นๆ เช่น ชื่อ นามสกุล อย่าคิดเอาเองว่าจะไม่มีโอกาสที่การก่อกวน หรือการ HACK ดังกล่าวจะเกิดขึ้น
เพราะการก่อกวนด้วย javascript นั้น
แค่ <script>for(;;)alert(1);</script>
ก็สามารถสั่งให้มี alert popup โผล่ขึ้นมาไม่รู้จบได้แล้ว โดยโค้ดยาวแค่ 34 ตัวอักษรเท่านั้น
แต่หลายๆ คนคงขี้เกียจจะใช้ htmlspecialchars() เนื่องด้วยความยาวของชื่อ และบ่อยครั้งอาจจะสะกดผิด
เราสามารถแก้ปัญหานี้ด้วยการสร้างฟังก์ชั่นใหม่ที่ชื่อสั้นลง ซึ่งทำให้เราสามารถกำหนดค่าอื่นๆ ได้ด้วย แต่การทำงานจะช้าลง (แต่ใครจะสน ถ้าไม่ใช่เครื่องเซิร์ฟเวอร์ของตัวเอง)
function h($string)
{
// แปลง < > & " แต่ไม่แปลง ' และใช้ encoding แบบ UTF-8 เสมอ
return htmlspecialchars($string, ENT_COMPAT, 'UTF-8');
}
echo h('A&W M&M S&P');
บทความที่เกี่ยวข้อง
ศึกษาเพิ่มเติม
ติดตามบทความล่าสุดของผู้เขียนได้ที่ phpinfo() Facebook Page
|
|
|
|
|
|
|
|
By : |
phpinfo()
|
|
Article : |
บทความเป็นการเขียนโดยสมาชิก หากมีปัญหาเรื่องลิขสิทธิ์ กรุณาแจ้งให้ทาง webmaster ทราบด้วยครับ |
|
Score Rating : |
|
|
Create Date : |
2013-02-20 |
|
Download : |
No files |
|
Sponsored Links |
|
|
|
|
|
|