เรื่องเล็กๆ แต่ยิ่งใหญ่ ของ Database กับ Text Box
อัปเดท : 15 พฤษภาคม พ.ศ.2547 , แสดง : 42,189 , ความคิดเห็น : 7
การพัฒนาเวบไซต์ ไม่ว่าจะใช้ asp,asp.net,php,jsp หรือภาษาอื่น ๆ พัฒนาเวบแอบปลิเคชั่นร่วมกับฐานข้อมูล ต่าง ๆ โดยมีการแสดงผล และรับข้อมูลผ่าน FROM ที่จัดเตรียมไว้ มีเริ่องเล็ก ๆที่ควรใส่ใจซึ่งจะพูดถึงในบทความนี้คือ "การรับค่าจาก TextBox แล้วเก็บลงฐานข้อมูล หรือนำไปประมวลผลต่อ" มันมีตรงไหนที่ควรระวัง ควรใส่ใจ ? ที่เจอบ่อยมีอยู่ 2 แบบ ก็คือ HTML Syntax และ Query String(SQL) Syntax เนื่องจากมันมีผลกับการประมวลผล นอกจากนี้ยังมีผลต่อความมั่นคง(Security)ของข้อมูลด้วย โดยเฉพาะอย่างยิ่งตรง Query String(SQL) ซึ่งมันมีช่องโหว่นึงที่สามารถทำ SQL Injections คือเป็นการ Hack หรือเจาะระบบผ่าน SQL Command ได้
HTML Syntax
มาดู HTML Syntax ที่มีผลต่อการแสดงผลก่อนเช่น <hr>, <br>, <table> </table> ,<td></td> และอื่น ๆ (ก็ทุก Syntax อ่ะครับ) ลองคิดดูถ้าเราเขียนเวบขึ้นมาแล้วให้ผู้ใช้กรอกค่าผ่าน TextBox แล้วเก็บลงฐานข้อมูล จะเกิดอะไรขี้นถ้าผู้ใช้พิพพ์ HTML Syntax ลงมาโดยตั้งใจหรือไม่ก็ตาม หลังจาก Submit ผลที่เกิดก็คือข้อมูลนั้นก็จะเก็บลงฐานข้อมูลปรกติ ไม่มีอะไรผิดปรกติ แต่ก้าเราดึงข้อมูลที่ Submit แล้วนั้นมาแสดงผล ก็จะเห็นการเปลี่ยนแปลงหน้าตาเวบ ทั้งนี้หน้าตาเวบจะเปลี่ยนไปมากน้อยหรือไม่เปลี่ยนเลยขึ้นอยู่กับ HTML Syntax นั้น เช่น ถ้าผู้ใช้พิมพ์ "<hr" ตอนดึงฐานข้อมูลมาแสดงผล ก็จะเกิดแนวนอน 1 เส้น ถือว่ายังดีอยู่พอรับได้ แต่ถ้า ถ้าผู้ใช้พิมพ์ "</table" ล่ะ จะเกิดอะไรขึ้น ? ถ้าเวบหน้านั้นมีการใช้ตาราง <Table> Browser ก็จะตีความว่าสิ้นสุดตาราง ทั้งที่จริง ๆ แล้วยังไม่สิ้นสุด ทำให้การแสดงผลผิดเพี้ยนไปดังตัวอย่าง Code ด้านล่าง
<table border="1" >
<tr> <td colspan="2"><%=txtValue1%></td></tr>
<tr> <td><%=txtValue2%></td><td><%=txtValue3%></td></tr>
</table>
สมมุติ ค่าตัวแปร txtValue1 , txtValue2 , txtValue3 เป็นค่าที่ดึงจากจากฐานข้อมูลหรือค่าที่รับจาก TextBox ตรง ๆ ก็ได้
txtValue1="Hello</Table>"
txtValue2="[email protected]"
txtValue3="15-05-47 12:23"
ตอนแสดงผลจะได้ Code ด้านล่าง
<table border="1" >
<tr> <td colspan="2">Hello</Table></td></tr>
<tr> <td>[email protected]</td><td>[email protected]</td></tr>
</table>
สังเกตุน่ะครับ ตรง </Table> ถ้าให้ Web Browser แสดงผลก็จะเพี้ยนทันทีซึ่งตรงนี้ต้องระวังน่ะครับ
แนวทางแก้ไข/ป้องกัน
ต้องแทนที่อักขระเช่น"<",">" หรือคอนโทรลโค๊ดอื่น ๆด้วย โค๊ดบางตัวก่อนโดยแทกโค๊ดตัวอย่างด้านล่าง ก่อน Submit ลงฐานข้อมูล
Value1= Request("Value1") ' ค่าที่รับมาจาก TextBox
Value1=Replace(Value1,chr(32)," ")
Value1=Replace(Value1,chr(13,"<BR>"))
Value1=Replace(Value1,"<","<")
Value1=Replace(Value1,">",">") 'Value1 นำไปเก็บลงฐานข้อมูลได้
Query String Syntax
สำหรับ ปัญหาของ Query String Syntax ก็คล้าย ๆ กับ HTML แต่ปัญหาของ Query String Syntax จะอยู่ที่เครื่องหมาย" '" เกิดอะไรขึ้นถ้า ผู้ใช้กรอกค่าผ่าน TextBox แล้วเก็บลงฐานข้อมูล แล้วค่านั้นมี " ' " เป็นส่วนประกอบ ผลก็คือ Syntax Error ไม่สามารถ Add ฐานข้อมูลได้ เนื่องจาก Query Analyser ตีความผิดพลาด เพราะอ่านเจอ " ' " ดัง ตัวอย่าง นอกจากนี้ยังเป็นช่องทางที่ Hacker จะใช้ SQL Injections ได้
ตัวอย่าง Script SQL ที่ใช้เพิ่มข้อมูลใน Table
SQL= "[[insert]] into myTable (myMessage,MyEmail,MyDate) values('& txtmyMessage &','& txtMyEmail &','& MyDate &')"
ถ้าค่าที่กรอกคือ
txtmyMessage="hello' "
txtMyEmail="[email protected]"
MyDate="15-05-47 12:23"
เมื่อโปรแกรมประมวลผลก็จะได้ SQL ทั้งหมดคือ
[[insert]] into myTable (myMessage,MyEmail,MyTime) values('hello' ','[email protected]','15-05-47 12:23')
ซึ่งตรง txtmyMessage ="hello ' " จะมีเครื่องหมาย ' อยู่ ทำให้ Syntax Error
แนวทางแก้ไข/ป้องกัน
แทกโค๊ดตัวอย่างด้านล่าง ก่อน Submit ลงฐานข้อมูล
Value1= Request("Value1") ' ค่าที่รับมาจาก TextBox
Value1=Replace(Value1,"'",") ' Replace เอา ' ออกหรือเอาแบบที่ใช้กับ HTML Syntax มาใช้เลยก็ได้ คือ Replace คอนโทรลโค๊ดที่สำคัญออกทั้งหมด
SQL Injections
เป็นการ Hack ผ่าน SQL ครับ ขอยกตัวอย่างที่เจอบ่อย ๆ เกิดจากความไม่ระวังของ Programmer เองขอยกตัวอย่างหน้า Login น่ะครับที่เปิด DB เพื่อตรวจสอบ Username และ Password
SQL="[[select]] * from tableUser Where username='" & txtUsername & "' and password='" & txtPassword & "'"
โดย SQL ด้านบนจะ Run ผ่านหน้า Login เมือผู้ใช้กรอก Username และ Password แล้ว
สมมุติน่ะครับ ว่าถ้า User กรอกข้อมูลดังนี้
txtUsername= "user"
txtPassword= "pass' or 'x'='x'"
ตอนที่นำมาประมวลผลก็จะได้ Query String เต็ม ๆ คือ
SQL="[[select]] * from tableUser Where username='user' and password=pass' or 'x'='x' "
จุดที่น่าสนใจของ Query String ด้านบนคือ 'x'='x' ถ้าเปรียบเทียบทางลอจิกมันจะเท่ากัน ดังนั้นเงื่อนไขก็เป็นจริง และเมื่อนำ 'x'='x' ไป OR กับ เงื่อนไขอื่น ๆ ก็เป็นจริงไปด้วย ดังนั้น Query String ด้านบนมันก็จะไม่สนใจแล้วว่า username และ password จะถูกต้องหรือไม่ เพราะ Query String เป็นจริงแล้วก็เข้าสู่ระบบต่อได้
แนวทางแก้ไข/ป้องกัน
แทกโค๊ดตัวอย่างด้านล่าง ก่อน Submit ลงฐานข้อมูล
Value1= Request("Value1") ' ค่าที่รับมาจาก TextBox
Value1= Replace(Value1,"'","") ' Replace เอา ' ออกหรือเอาแบบที่ใช้กับ HTML Syntax มาใช้เลยก็ได้ คือ Replace คอนโทรลโค๊ดที่สำคัญออกทั้งหมด
อีกวิธีที่ควรใช้ร่วมกันกับวิธีแรก คือเทคนิคการเขียนโปรแกรมเช่น
DBCommand = New OleDBDataAdapter( "[[select]] * from tableUser Where username='" & txtUsername &"' and password='" & txtPassword & "'"
)" ,myConnection)
DBCommand.Fill(DSPageData,"tableUser")
' อ่านค่าจากฐานข้อมูลที่ได้ มาใส่ตัวแปรอีกครั้ง
DBusername = DSPageData.Tables("tableUser").Rows(0).Item("username")
DBpassword = DSPageData.Tables("tableUser").Rows(0).Item("password")
' แล้วก็เช็คกับ TextBox อีกที ว่าตรงกัน TextBox หรือไม่ เพราะถ้าตรงกันแสดงว่าเค้าได้กรอก
' ข้อมูลจริง ๆ เพราะไม่มี DBPassword และ DBusername ในตาราง มีค่าเป็น"pass' or 'x'='x' "
' มีช่องโหว่อีกนิดเป็นตอนสมัคร/Add ข้อมูล ต้อง Replace คอนโทรลโค๊ดออกด้วย เพราะ Hacker
' อาจใช้ username="user" ,และ password="pass' or 'x'='x' " ในตอนสมัคร/Add เลยก็ได้
' เพราะต่อให้ตรวจสอบแบบนี้มันก็ ผ่านได้
if DBusername = txtUsername.text and DBpassword = txtPassword.text then
' ตรงกันเข้าหน้า Admin ได้
else
' ไม่ตรงกัน
end if
Code ด้านบนก็พอที่จะป้องกันการ SQL Injections ได้ระดับนึงเท่านั้น
อีกอย่างที่ควรทำคือการกำหนดให้ TextBox กรอกข้อมูลได้ เฉพาะ a-z,0-9 ด้วยก็ได้ ทั้งนี้ขึ้นอยู่กับนโยบายหรือแผนที่คุณวางไว้ว่าจะป้องกันแค่ไหนดี
Code ด้านบนที่อ้างถึงเป็น asp.net ถ้าคุณใช้ภาษาอื่น Concept ก็คล้าย ๆ กัน ลองดู Function "Replace" ของภาษานั้นใช้ยังงัยนะครับ
บทความนี้เขียนจากประสบการณ์และการศึกษาเพิ่มเติมครับ มีคำแนะนำหรือเทคนิคอื่น ๆ เขียนไว้ตรง Comment ได้เลยนะครับ
ผู้เขียน/อ้างอิง : จักรกฤษณ์ แร่ทอง
เวบ/อินเตอร์เน็ตเทคโนโลยี
ท่ามกลางความอบอ้าวของตลาดนัดจตุจักร ชายหนุ่มหลุดจากความเบียดเสียดของคนที่เดิน...
โปรแกรมใหม่นี้ได้เริ่มมี อาการแปลกๆ รวมถึงกินพื้นที่และทรัพยากรอันมีค่าเป็นอันมาก และอาการที่เกิดขึ้นนี้ไม่มีการกล่าวถึง
เมื่อเครื่องของเรามีปัญหา เช่น Boot ไม่ขึ้น หรือ Boot แล้วเข้าสู่วินโดวส์ได้แล้ว แต่ทำงานผิดปกติไป
กฎ 24 ข้อในการเขียนซีจีไอสคริปต์ให้มีความปลอดภัย โปรแกรมสำหรับขายสินค้าบนเว็บ โปรแกรมสำหรับสนทนาบนเว็บ โปรแกรมเว็บบอร์ด
การทำให้ข้อมูลเป็นความลับ (Confidentiality) เพื่อป้องกันไม่ให้ผู้ที่ไม่มีสิทธิ์ในการเข้าถึงข้อมูลสามารถเข้าถึงข้อมูลได้
เบื้องลึกของ ตัวอักษรภาษาไทย, ตัวอักษรภาษาญี่ปุ่น และภาษาอื่นๆ
concept เดียวกัน ชื่อต่างกันเพราะ ค่ายต่างกันแค่นั้นเหรอ..
เมื่อ เว็บเซอร์ฟเวอร์ เกิดหลงๆลืมเหมือนคนแก่
แนวโน้มของเวบไซต์และเทคโนโลยีอนาคตเมื่ออินเตอร์เน็ตความเร็วสูงขึ้น
เบื้องลึกเบื้องหลัง หลักการทำงาน ของระบบอีเมลล์
ความคิดเห็น/แนะนำ/ติชม/อื่นๆ
- ViperZX [24 May 2005 , 02:24 AM]
$sql = "SELECT uid,username,passwd FROM users WHERE username='carnix';"; ... if($db_password == $html_password){ return true; }
- อรรถวุฒิ [19 Jun 2005 , 09:37 PM]
ผมขอสอบถามหน่อยนะคับ คืนผมจะทำเวปที่มีการทำข้อสอบออนไลร์ มีการเก็บคะแนน แล้วส่งเข้าเก็บในฐานข้อมูล ผมจะสามาถรทำได้รึปล่าวคับ แล้วผมจะต้องทำยังไงดี แล้วจะใช้VB.netเขียนจะดีรึปล่าวคับ
- apisak [09 พ.ค. 2549 , 09:06 AM]
ผมขอถามเรื่องการกรอกข้อมูลของ TextBox ใน vb.net ครับ เพราะว่าผมอยากจะเช็คการกรอกข้อมูลอย่างเช่น ผมอยากกรอกข้อมูลได้เฉพาะภาษาไทย หรือภาษาอังกฤษ หรือกรอกทั้งภาษาไทยและภาษาอังกฤษจะต้องทำการเช็คค่าในการกรอกข้อมูลได้อย่างไรครับ
- M [18 ส.ค. 2551 , 02:37 PM]
พี่ๆ ที่รู้เรื่องนี้ครับ Error Type: Microsoft OLE DB Provider for ODBC Drivers (0x80004005) [Microsoft][ODBC Microsoft Access Driver] Operation must use an updateable query. /ynaddnews.asp, line 56 มันคืออะไรครับ
- M [18 ส.ค. 2551 , 02:37 PM]
พี่ๆ ที่รู้เรื่องนี้ครับ Error Type: Microsoft OLE DB Provider for ODBC Drivers (0x80004005) [Microsoft][ODBC Microsoft Access Driver] Operation must use an updateable query. /ynaddnews.asp, line 56 มันคืออะไรครับ
- หนึ่ง [02 ส.ค. 2554 , 08:55 AM]
ขอบคุณสำหรับบทความดีๆนะครับ
- y [30 เม.ย. 2555 , 12:01 PM]
คือจะให้ส่ง e-mail ทีละ 2 คน แล้วเก็บid ของเทเบิ้ลหนึ่ง เป็น lastlist ของอีกเทเบิ้ลไว้เพื่อ ส่งอีก 3-4 แล้วทำไปเรื่อยๆๆจนหมด แล้วก็ให้ค่ากลับไปเป้น 0 ตอนสุดท้าย