ช่องโหว่ด้านความปลอดภัยของ PHP: การลักลอบเซสชัน, การเขียนสคริปต์ข้ามไซต์, การแทรก SQL และวิธีแก้ไข

ความปลอดภัยใน PHP

เมื่อเขียนโค้ด PHP เป็นสิ่งสำคัญมากที่จะต้องคำนึงถึงช่องโหว่ด้านความปลอดภัยต่อไปนี้เพื่อหลีกเลี่ยงการเขียนโค้ดที่ไม่ปลอดภัย

ประเภทของช่องโหว่

นี่คือช่องโหว่ทั่วไปที่คุณจะพบเมื่อเขียนโค้ด PHP เราจะพูดถึงในเชิงลึกเพิ่มเติมด้านล่าง

  • การปลอมแปลงคำขอข้ามไซต์ช่องโหว่ในแอปพลิเคชันที่เกิดจากโปรแกรมเมอร์ไม่ได้ตรวจสอบว่าคำขอถูกส่งมาจากที่ใดการโจมตีนี้จะถูกส่งไปยังผู้ใช้ระดับสิทธิ์สูงเพื่อเข้าถึงแอปพลิเคชันในระดับที่สูงขึ้น
  • การเขียนสคริปต์ข้ามไซต์ช่องโหว่ในแอปพลิเคชันที่เกิดจากการที่โปรแกรมเมอร์ไม่ทำความสะอาดอินพุตก่อนที่จะส่งออกอินพุตไปยังเบราว์เซอร์ (เช่นความคิดเห็นในบล็อก) โดยทั่วไปจะใช้เพื่อเรียกใช้จาวาสคริปต์ที่เป็นอันตรายในเบราว์เซอร์เพื่อทำการโจมตีเช่นการขโมยคุกกี้เซสชันท่ามกลางการกระทำที่เป็นอันตรายอื่น ๆ เพื่อให้ได้รับสิทธิ์ระดับที่สูงขึ้นในแอปพลิเคชัน
  • Local File Inclusion ช่องโหว่ในแอปพลิเคชันที่เกิดจากโปรแกรมเมอร์ต้องการอินพุตไฟล์ที่ผู้ใช้จัดเตรียมไว้และไม่ได้ทำการล้างข้อมูลอินพุตก่อนที่จะเข้าถึงไฟล์ที่ร้องขอ ส่งผลให้มีการรวมไฟล์ในที่ที่ไม่ควรอยู่
  • การรวมไฟล์ระยะไกลช่องโหว่ในแอปพลิเคชันที่เกิดจากโปรแกรมเมอร์ที่ต้องการอินพุตไฟล์ที่จัดเตรียมโดยผู้ใช้และไม่ได้ล้างข้อมูลอินพุตก่อนที่จะเข้าถึงไฟล์ที่ร้องขอ ซึ่งส่งผลให้ไฟล์ถูกดึงจากเซิร์ฟเวอร์ระยะไกลและรวมไว้ในที่ที่ไม่ควรอยู่
  • Session Hijacking ช่องโหว่ที่เกิดจากผู้โจมตีเข้าถึงตัวระบุเซสชันของผู้ใช้และสามารถใช้บัญชีของผู้ใช้รายอื่นที่แอบอ้างเป็นพวกเขาได้ ซึ่งมักใช้เพื่อเข้าถึงบัญชีผู้ใช้ที่เป็นผู้ดูแลระบบ
  • Session Identifier Acquirement Session Identifier Acquirement เป็นช่องโหว่ที่เกิดจากผู้โจมตีสามารถเดาตัวระบุเซสชันของผู้ใช้หรือใช้ประโยชน์จากช่องโหว่ในแอปพลิเคชันเองหรือเบราว์เซอร์ของผู้ใช้เพื่อรับตัวระบุเซสชัน
  • SQL Injection ช่องโหว่ในแอปพลิเคชันที่เกิดจากโปรแกรมเมอร์ไม่ล้างข้อมูลอินพุตก่อนที่จะรวมไว้ในแบบสอบถามลงในฐานข้อมูล สิ่งนี้นำไปสู่การโจมตีที่มีสิทธิ์อ่านเต็มและบ่อยกว่าไม่เขียนเข้าถึงฐานข้อมูล ด้วยการเข้าถึงประเภทนี้ผู้โจมตีสามารถทำสิ่งที่เลวร้ายได้

ตอนนี้เรามาดูรายละเอียดช่องโหว่ทั่วไปกันดีกว่า

การหักหลังเซสชัน

Session Hijacking เป็นช่องโหว่ที่เกิดจากการที่ผู้โจมตีเข้าถึงตัวระบุเซสชันของผู้ใช้และสามารถใช้บัญชีของผู้ใช้รายอื่นที่แอบอ้างได้ ซึ่งมักใช้เพื่อเข้าถึงบัญชีผู้ใช้ที่เป็นผู้ดูแลระบบ

การป้องกันการโจมตี Session Hijacking ใน PHP

ในการป้องกันการโจมตีด้วย Session Hijacking คุณต้องตรวจสอบเบราว์เซอร์ของผู้ใช้ปัจจุบันและข้อมูลตำแหน่งกับข้อมูลที่จัดเก็บเกี่ยวกับเซสชัน ด้านล่างนี้คือตัวอย่างการใช้งานที่สามารถช่วยลดผลกระทบจากการโจมตีด้วยการจี้เซสชันได้ ตรวจสอบที่อยู่ IP ตัวแทนผู้ใช้และหากเซสชันหมดอายุการลบเซสชันก่อนที่จะดำเนินการต่อ

 ($_SESSION['lastaccess'] + 3600)) { session_unset(); session_destroy(); } else { $_SESSION['lastaccess'] = time(); }

การเขียนสคริปต์ข้ามไซต์

Cross Site Scripting เป็นช่องโหว่ประเภทหนึ่งในเว็บแอปพลิเคชันที่เกิดจากการที่โปรแกรมเมอร์ไม่ทำความสะอาดอินพุตก่อนที่จะส่งออกอินพุตไปยังเว็บเบราว์เซอร์ (ตัวอย่างเช่นความคิดเห็นในบล็อก) โดยทั่วไปจะใช้เพื่อเรียกใช้จาวาสคริปต์ที่เป็นอันตรายในเว็บเบราว์เซอร์เพื่อทำการโจมตีเช่นการขโมยคุกกี้เซสชันท่ามกลางการกระทำที่เป็นอันตรายอื่น ๆ เพื่อให้ได้รับสิทธิ์ระดับที่สูงขึ้นในเว็บแอปพลิเคชัน

ตัวอย่าง Cross Site Scripting Attack

บล็อกอนุญาตให้ผู้ใช้จัดรูปแบบความคิดเห็นด้วยแท็ก HTML อย่างไรก็ตามสคริปต์ที่เปิดใช้งานบล็อกจะไม่ตัดแท็กออกเพื่อให้ผู้ใช้สามารถเรียกใช้จาวาสคริปต์บนหน้าเว็บได้ ผู้โจมตีสามารถใช้สิ่งนี้ให้เป็นประโยชน์เพื่อเรียกใช้จาวาสคริปต์ที่เป็นอันตรายในเบราว์เซอร์ อาจทำให้ผู้ใช้ติดมัลแวร์ขโมยคุกกี้เซสชันและอื่น ๆ

 alert('Cross Site Scripting!'); 

ปกป้องเว็บไซต์ของคุณจากการโจมตีด้วยสคริปต์ข้ามไซต์ใน PHP

ใน PHP มีฟังก์ชันหลักสองอย่างhtmlspecialchars()และstrip_tags()สร้างขึ้นเพื่อป้องกันตัวเองจากการโจมตีด้วยสคริปต์ข้ามไซต์

htmlspecialchars($string)ฟังก์ชั่นจะป้องกันไม่ให้สตริง HTML จากการแสดงผลเป็น HTML และแสดงเป็นข้อความธรรมดากับเว็บเบราว์เซอร์ htmlspecialchars () ตัวอย่างโค้ด

The other approach is the strip_tags($string, $allowedtags) function which removes all HTML tags except for the HTML tags that you’ve whitelisted. It’s important to note that with the strip_tags() function you have to be more careful, this function does not prevent the user from including javascript as a link, you’ll have to sanitize that on our own.

strip_tags() code example

" ; echo strip_tags($usercomment, $allowedtags);

Setting the X-XSS-Protection Header:

In PHP you can send the X-XSS-Protection Header which will tell browsers to check for a reflected Cross Site Scripting attack and block the page from loading. This does not prevent all cross site scripting attacks only reflected ones and should be used in combination with other methods.

Writing your own sanitization function Another option, if you would like more control over how the sanitization works, is to write your own HTML Sanitization function, this is not recommended for PHP Beginners as a mistake would make your website vulnerable.

Defending your website from cross site scripting attacks with a Content Security Policy

An effective approach to preventing cross site scripting attacks, which may require a lot of adjustments to your web application’s design and code base, is to use a content security policy.

Set a Content Security Policy as an HTTP Header

The most common way of setting a Content Security Policy is by setting it directly in the HTTP Header. This can be done by the web server by editing it’s configuration or by sending it through PHP.

Example of a Content Security Policy set in a HTTP Header

Set a Content Security Policy as a Meta tags

You can include your Content Security Policy in the page’s HTML and set on a page by page basis. This method requires you to set on every page or you lose the benefit of the policy.

Example of a Content Security Policy set in a HTML Meta Tag

Original text


SQL Injection

SQL injection is a vulnerability in the application caused by the programmer not sanitizing input before including it into a query into the database. This leads to the attacker having full read and more often than not write access to the database. With this type of access an attacker can do very bad things.

Example SQL Injection attack

The below PHP Script runs an SQL Statement to get a user’s email by ID. However the input is not sanitized making it vulnerable to SQL Injection

connect_error) { die("Connection failed: " . $conn->connect_error); } $sql = "SELECT email FROM users WHERE idemail"]; } } else { echo "no results"; } $conn->close();
SELECT email FROM users WHERE id = `$input`;

So with the above the input is not type casted (I.e. casting the input with (int) so only a number is allowed) nor escaped allowing someone to perform an SQL Injection attack - for example the URL getemailbyuserid.php?id=1'; My Query Here-- - would allow you to run arbitrary SQL queries with little effort.

Defending your website from sql injection attacks in PHP

There are a few approaches to defend your website from SQL Injection Attacks. These approaches are Whitelisting, Type Casting, and Character Escaping

Whitelisting: The whitelisting approach is used in cases where only a few inputs are expected. You can list each expected input in a PHP Switch and then have a default for invalid input. You do not have to worry about a type casting issue or a character escape bypass but the allowed input is extreamly limited. It remains an option, see the example below.

Type Casting: The type casting approach is commonly used for an application using numeric input. Simply cast the input with (int) $input and only a numeric value will be allowed.

Character Escaping: The character escaping approach will escape characters such as quotes and slashes provided by the user to prevent an attack. If you are using MySQL Server and the MySQLi library to access your database, the mysqli_real_escape_string($conn, $string) function will take two arguments, the MySQLi connection, and the string and will properly escape the user’s input to block an sql injection attack. The exact function you use depends on the database type and php library you are using check the php library’s documentation for more information on escaping user input.

More on PHP:

  • PHP best practices
  • Best PHP code examples
  • How to prevent a slow loris attack on a PHP server
  • How to set up a local debugging environment in PHP