18/09/2018, 11:45

Những kinh nghiệm cơ bản để lập trình web an toàn

Trong bài viết này, chúng tôi sẽ nói về các cuộc tấn công có thể xảy ra với các ứng dụng web và cách để giúp bạn có thể lập trình web an toàn. 1) Lập trình web An toàn để phòng chống lỗ hổng SQL Injection SQL Injection là lỗ hổng phổ biến nhất trong ứng dụng web. Trên thực thế việc ngăn chặn ...

Trong bài viết này, chúng tôi sẽ nói về các cuộc tấn công có thể xảy ra với các ứng dụng web và cách để giúp bạn có thể lập trình web an toàn.

1) Lập trình web An toàn để phòng chống lỗ hổng SQL Injection

SQL Injection là lỗ hổng phổ biến nhất trong ứng dụng web. Trên thực thế việc ngăn chặn SQL Injection không hề khó. Lỗ hổng SQL Injection xảy ra khi một ứng dụng web không kiểm tra các thông số nhận được từ trình duyệt và trực tiếp thực thi chúng trong máy chủ cơ sở dữ liệu. Vì vậy hãy kiểm tra thật kỹ các thông số, bạn sẽ có thể ngăn chặn tất cả các loại SQL Injection.

Cách thức lập trình web an toàn: Bạn có thể sử dụng hàm mysql_real_escape_string và nó sẽ chặn hầu hết các cuộc tấn công SQL Injection, nhưng hãy tưởng tượng rằng:

$id = mysql_real_escape_string($_POST['id']); $mQuery = "SELECT * FROM Users WHERE id = $id";

Nếu tin tặc nhập “1049 OR 1=1” vào giá trị id, mysql_real_escape_string sẽ không giúp được gì nhiều bởi vì không có gì được loại bỏ từ chuỗi này và nó là hợp lệ “1049 OR 1=1”.  Thêm vào lớp bảo mật bổ sung luôn an toàn hơn các lớp bảo mật có sẵn trong thiết kế ứng dụng của bạn.

Ví dụ nếu bạn biết ID luôn là một giá trị số nguyên, hãy kiểm tra nó. Đơn giản gọi hàm is_int trong PHP để kiểm tra thông số. Ngoài ra kinh nghiệm bảo mật tốt sẽ là sử dụng Prepared Statements. Thay vì sử dụng đoạn code bên trên, chúng ta dùng:

$id = mysql_real_escape_string($_POST['id']); if (!is_int($id)) display_error_and_return(); $stmt = $dbh->prepare("Select * from Users WHERE id = ?"); $stmt->bindParam(1, $id); $stmt->execute();

Bạn cũng có thể làm tương tự với ngôn ngữ ASP.NET:

SqlParameter[] myparm = new SqlParameter[1]; param[0] = new SqlParameter("@Id", postID); myQuery = "SELECT * FROM Users WHERE ID=@Id";

Hoặc sử dụng hàm TryParseif (!Int32.TryParse(postID, out integer)) display_error_and_return();

Luôn giữ trong đầu việc bạn những việc sau khi phát triển một ứng dụng web có tương tác với cơ sở dữ liệu:

Không bao giờ cấp các quyền không cần thiết cho tài khoản kết nối tới CSDL của ứng dụng web trong hệ quản tị CSDL. Đơn giản tạo một người dùng trong cơ sở dữ liệu và chỉ cấp quyền truy vấn SELECT nếu người dùng không INSERT hay UPDATE.

Thực hiện việc loại bỏ các chuỗi kí tự, bên trên chúng ta đã sử dụng TryParse và is_int bởi vì chúng ta biết thông số là một số nguyên. Nếu bạn có một thông số là một chuỗi kí tự như tên Category, khi bạn nắm được Category của mình là một từ đơn, hãy kiểm tra dấu “cách”; nếu bạn biết được trong tên Category không được có những kí tự không mong muốn như dấu “=”, hãy kiểm tra lại.

Lỗ hổng SQL injection

2) Quản lý việc Upload File

Khi bạn sử dụng một chương trình File Uploader, nếu không quản lý và kiểm soát tốt bạn sẽ tạo các cửa trên máy chủ tiếp cận các tệp tin từ bên ngoài. Bạn cần có những biện pháp phòng ngừa tin tặc. Nếu có thể, hãy mã hóa tên file và không bao giờ chứa tên file gốc trên ổ cứng của máy chủ. Ví dụ, nếu bạn tải lên file Test.jpg, hãy tạo tên như sau:

$mNow = date("Y-m-d H:i:s"); $mOrigName = $OriginalFileName; $NewName = md5($mNow + " --- " + $mOrigName;

Giờ thì lưu trữ tên file trong cơ sở dữ liệu và lưu file đó vào ổ đĩa với tên mới được tạo và không có phần mở rộng hay những phần mở rộng trung gian như .tmp hay .usrfile

Không bao giờ hiển thị đường dẫn nơi bạn lưu trữ những file được tải lên. Ví dụ không gửi thông báo “Thank you for uploading your file, you can see your file here yourwebsite.com/uploadedfiles/Test.jpg”.

Lưu trữ các tệp tin vào một thư mục có tên ngẫu nhiên thay vì có tên như Upload, Uploads, UserFiles, UserUploads… Chỉ cần tạo ra chuỗi 10 kí tự ngẫu nhiên như qS2lVDOL6o.

Không bao giờ cho phép thực thi các tập tin như .php, .asp, .jsp trên thư mục tải lên, bạn có thể cấu hình bằng cách sử dụng .htaccess  trong Apache hay cấu hình trong IIS.

Ngoài ra, bạn có thể đơn giản là lưu trữ các file này trong cơ sở dữ liệu dạng binary.

3) Tấn công Local hoặc Remote File Inclusion

PHP khá dễ bị tấn công trước kiểu tấn công này nhất. Nó xảy ra khi một đoạn code cố gắng include một trang khác sử dụng tham số là biến được lấy vào từ người dùng. Ví dụ:

NewsId = $_POST['nid']; include $NewsID; hoặc require_once($NewsID);

Điều này thực sự rất nguy hiểm. Thậm chí tin tặc có thể thực thi mã lệnh trên chính máy chủ của bạn bằng cách tạo các mã PHP code vào tệp tin apache log và sau đó lợi dụng điểm yếu của lỗ hổng File Inclusion để đọc các đoạn mã này từ file log. Vì vậy, để lập trình web an toàn bạn nên tránh xa việc sử dụng các hàm include, require với dữ liệu đầu vào động và được thay đổi bởi người dùng.

  • Với mỗi file, có một địa chỉ và ID riêng trên cơ sở dữ liệu, hãy tạo đường dẫn như sau: downloadfile.php?ID=49 và trong code của bạn truy vấn cơ sở dữ liệu với tên file có ID=49, đọc nó và xử lý.
  • Nếu xử lý file trực tiếp, bạn có thể kiểm tra sự tồn tại những kí tự như “..” “/” “http” “ftp” “https” … Nhưng phương pháp này không thực sự tốt.

4) Lỗ hổng XSS

Để ngăn chặn và lập trình web an toàn với XSS trong PHP sử dụng:

$UserParam = strip_tags($UserParam);

ASP.NET:

UserParam = Microsoft.Security.Application.Sanitizer.GetSafeHtmlFragment(UserParam);

Những điều được giải tích phía trên là những khái niệm cơ bản nhất về lập trình web an toàn, nhưng nếu làm tốt điều này bạn có thể ngăn chặn được phần lớn các cuộc tấn công vào ứng dụng web.

0