Trong phần 1, chúng ta đã nghiên cứu và tìm cách khắc phục những lỗi phổ biến trong lập trình. Trong phần này chúng ta sẽ tìm hiểu sâu hơn những lỗi bảo mật và tìm cách khắc phục những lỗi có thể xảy ra để ngăn chặn các cuộc tấn công không đáng có.
Phụ mục
File hệ thống
Hầu hết các hệ thống website bằng cách này hay cách khác đều có những hệ thống thư mục giống hoặc tương tự nhau. Bạn hãy thử nghĩ xem, có phải nhiều hệ thống website đều có những thư mục tương tự như những thư mục được liệt kê dưới đây:
1. /include
2. /includes
3. /template
4. /images
Phía trên chỉ là một vài thư mục phổ biến hay được sử dụng để chứa đựng mã nguồn của website. Còn nhiều thứ phổ biến nữa mà tôi không liệt kê ở đây. Nếu những thư mục này không được phân quyền hợp lý, một người truy cập bình thường cũng có thể dễ dàng dự đoán được những thư mục này và tìm hiểu những file hệ thống được bạn chứa đựng bên trong nó.
Hãy tưởng tượng, nếu bạn có 1 file kết nối cơ sở dữ liệu dùng để kết nối cơ sở dữ liệu trên toàn bộ website được chứa trong thư mục includes/ được đặt tên connect.inc chẳng hạn. Đây là một trường hợp rất phổ biến và nhiều bạn thường đặt tên như vậy (hoặc config.inc). Vấn đề ở chỗ file *.inc là một file thường được đọc dưới dạng văn bản (text) chứ không được xử lý như một script PHP. Điều đó có nghĩa là nếu người dùng gõ chính xác tên file kết nối này họ có thể đọc được toàn bộ nội dung chứa trong file đó và có thể tìm được thông tin đăng nhập cơ sở dữ liệu của bạn.
Đặt những tập tin quan trọng ở những vị trí dễ dự đoán làm gia tăng nguy cơ bảo mật của bạn lên cao. Cách tốt nhất trong trường hợp này là bạn nên đặt chúng ở thư mục gốc, đặt ở một thư mục mà tên của nó không dễ dàng được đoán ra. Bạn cũng nên chắc chắn là đã tắt thông báo lỗi (Error Message đã nói ở phần trước) nhằm ngăn cản sự dự đoán của hacker. Một trong những cách mà bạn nên thử đó là thiết lập quyền hạn truy cập các file quan trọng. Bạn phải lên danh sách các file không được xem bằng trình duyệt, các thư mục nên đặt thêm 1 file “index.html” nhằm không cho những kẻ tò mò tìm được danh sách các file nằm bên trong thư mục đó.
Tóm lại, trong vấn đề này bạn nên nhớ một số qui tắc bảo mật quan trọng sau đây:
- Đừng bao giờ đặt tên file quan trọng với phần mở rộng là .inc. Bạn có thể sử dụng *.inc.php để file được xử lý như một script PHP. Như vậy, nội dung sẽ không được dễ dàng bị đọc được.
- Đảm bảo thư mục của bạn nằm ngoài webroot (phần này bản thân babyinternet cũng chưa rõ lắm – http://vnwebmaster.com) và có tên không dễ đoán được.
- Luôn luôn chắc chắn rằng bạn có 1 file “index.html” trắng nằm ở các folder ngay cả thư mục chứa hình ảnh. Nếu thư mục cho phép người dùng xem, file này cũng giúp ngăn cản những kẻ tò mò tìm ra cấu trúc và danh sách file bên trong thư mục này.
- Đảm bảo phân quyền cho các file quan trọng và không muốn người dùng đụng đến (có thể làm việc này bằng .htaccess hoặc trong httpd.conf).
Bonus: sẵn tiện viết bài này, tác già Dave Child đã thử xem tính phổ biến của loại lỗi này. Ông sử dụng công cụ Google kết hợp với vài từ khóa chính xác và tìm ra khoảng 30 website mắc các lỗi này để lộ các thông tin quan trọng như tài khoản phpMyAdmin, hay FTP …. Chỉ mất 10″, tác giả đã có thể xâm nhập vào 1 hệ thống website mắc lỗi. Số lượng website bị tác giả đột nhập lên đến con số 50.
Hệ thống đăng nhập
Bất kì website nào có cơ sở dữ liệu động (web động) đều có một khu vực riêng giành cho người quản trị để quản lý và thay đổi thông tin trên website mà không cần dùng FTP. Trong phần trước, chúng ta đã đặt vấn đề bảo vệ khu vực này bằng cách đặt tên khu vực này một cách đặc biệt nhằm gây khó khăn cho những kẻ tò mò. Tuy nhiên như vậy là chưa đủ để tránh được con mắt tò mò của những kẻ thích phá hoại :(
Hầu hết các CMS cho phép người dùng thay đổi mật khẩu thành bất kì điều gì họ thích và họ dễ dàng nhớ. Người dùng có xu hướng đặt mật khẩu với những tên gọi của họ, những điều đặc biệt có liên quan đến họ hoặc một cụm từ nào đó họ yêu thích, những người thân yêu của họ… Lợi dụng điều này, hacker có thêm một hình thức để dò tài khoản người dùng gọi là dictionary attack (hoặc brute force attack). Kiểu tấn công này bắt đầu bằng việc tạo ra một danh sách các từ ngữ thường được sử dụng và thay thế chúng cho đến khi tìm ra mật khẩu tương ứng với tài khoản truy cập đó.
Cách tốt nhất để bảo vệ tài khoản của mình trong trường hợp này là tạo nên một hệ thống bảo mật thứ 3 bên cạnh tên đăng nhập và mật khẩu. Lớp bảo mật này được hình thành từ 3 lớp:
- Trước tiên, bạn cần tạo ra một trang xác nhận truy cập dạng người dùng. Bạn có thể tạo ra một chuỗi số và chữ và yêu cầu người dùng nhập đúng những kí tự này để có thể đăng nhập. Bạn phải chắc chắn chuỗi kí tự này được thay đổi ngẫu nhiên (random) mỗi khi người dùng đăng nhập và dạng hình ảnh(để ngăn chặn các chương trình đọc tự động). Nó chỉ có thể được vượt qua khi người dùng quan sát bằng mắt và nhập bằng tay.
- Tiếp theo, thêm vào một bộ đếm lượt truy cập đơn giản. Nếu sau một số lần nhất định người dùng không thể nhập đúng mật khẩu. Bạn hãy khóa trang đăng nhập của người dùng lại trong một khoản thời gian nhất định (vài tiếng nếu muốn :D ). Việc này sẽ làm nản lòng nhiều kẻ tò mò lắm đây.
- Cuối cùng, hãy luôn nhớ rằng bạn phải ghi lại IP của tất cả các phiên đăng nhập thành công và không thành công. Việc này giúp bạn nhanh chóng phát hiện ra kẻ phá hoại và ngăn chặn việc truy cập vào website của bạn luôn
Tất nhiên, việc này có vẻ bất tiện cho người dùng bình thường có nhu cầu chính đáng nhưng là việc làm cần thiết để đảm bảo cho website của bạn an toàn và tránh xa những rủi ro không cần thiết.
Phân quyền cho database
Đây là việc làm cần thiết, nhất là khi cơ sở dữ liệu của bạn bị truy cập trái phép mà bạn chưa phát hiện được lỗi. Bạn có thể phân quyền cho user đăng nhập database của mình các quyền thêm, sửa, xóa record và table. Hầu hết các cơ sở dữ liệu MySQL và SQL Server đều hỗ trợ việc phân quyền này khá tốt. Thông thường tôi chỉ cho phép người dùng thêm và sửa dữ liệu. Còn việc xóa dữ liệu được tôi lưu vào một bảng tạm và tôi sẽ kiểm tra lại lần nữa trước khi cho lệnh này thao tác trực tiếp lên cơ sở dữ liệu của tôi.
Bạn có thể thực hiện việc này bằng cách đơn giản là tạo ra thêm 1 column dạng cờ (flag) với tên gọi “item_deleted”. Nếu người dùng xóa dữ liệu, column này sẽ được đánh dấu và không xuất hiện nữa (nhưng về căn bản trong cơ sở dữ liệu vẫn còn nguyên dữ liệu này).
Phân quyền các hàm
Thư viện của PHP bao gồm rất nhiều hàm trong đó có nhiều hàm quan trọng và có khả năng thực hiện những tác vụ hệ thống. Trừ khi nào bạn cần sử dụng những hàm cụ thể, còn không thì bạn nên vô hiệu hóa nó để giảm các nguy cơ bảo mật về lâu dài.
PHP cho phép bạn điều chỉnh các hàm sử dụng thông qua disable_functions trong php.ini. Bạn kiểm tra các hàm không sử dụng và khóa chúng lại. Các hàm bạn nên khóa như ini_set(), exec(), fopen(), popen(), passthru(), readfile(), file(), shell_exec() và system().
Nội dung được dịch từ bài viết Writing Secure PHP, Part 2 bởi babyinternet.
Ghi rõ nguồn http://vnwebmaster.com khi phát hành tại website khác