header-object

Bảo mật trong lập trình web bằng PHP và MySQL - Phần 1

Bảo mật là một trong những vấn đề đáng ngại nhất dành cho giới lập trình web động trên ngôn ngữ PHP và cơ sở dữ liệu là mySQL (riêng vấn đề thứ 3 thì tương tác trên html và javascript nên khá khó trong việc bảo mật). Với loạt bài này sẽ được đề cập tới 4 vấn đề quan trọng trong bảo mật trang web của bạn, và các vấn đề được đề cập ở đây đều nằm ở mức báo động đến các người lập trình web mà họ không mấy quan tâm.

bao mat 1-1

Ở đây, sẽ không giới thiệu đến các bạn 4 vấn đề trước mà sẽ tuần tự giới thiệu các vấn đề theo khung từ mức độ cao dần về thấp trong các lỗi bảo mật khi lập trình web của đa số các lập trình viên.

1. Vấn đề thứ nhất: SQL INJECTION

Mục đích chính của vấn đề này đó chính là khai thác các quá trình trong cơ sở dữ liệu(CSDL) cụ thể đó chính là hệ CSDL mySQL, ví dụ như: can thiệp vào các truy vấn dữ liệu của người lập trình như SELECT, INSERT, UPDATE, DELETE, DROP, TRUNCATE, UNION,....

Khi mà can thiệp vào các truy vấn đó thông qua bề mặt giao diện người dùng là web của chúng ta thì có thể làm hỏng hóc CSDL, gây ra các lỗi bảo mật nghiêm trọng như: Lộ thông tin quản trị, lộ thông tin tín dụng với các web thanh toán trực tuyến,... Đặc biệt bên cạnh đó còn có vấn đề include shell (mã độc) vào CSDL nhằm thực thi các lệnh trên linux và bị get source code full CSDL.

Thế các mục đích đó được thực thi bằng các tuyệt chiêu gì? Lợi hại như thế nào?

Dạng tấn công vượt qua kiểm tra lúc đăng nhập

Với dạng tấn công này, tin tặc có thể dễ dàng vượt qua các trang đăng nhập nhờ vào lỗi khi dùng các câu lệnh mySQL thao tác trên cơ sở dữ liệu của ứng dụng web. Thông thường để cho phép người dùng truy cập vào các trang web được bảo mật, hệ thống thường xây dựng trang đăng nhập để yêu cầu người dùng nhập thông tin về tên đăng nhập và mật khẩu.

Sau khi người dùng nhập thông tin vào, hệ thống sẽ kiểm tra tên đăng nhập và mật khẩu có hợp lệ hay không để quyết định cho phép hay từ chối thực hiện tiếp. Ví dụ ta có file login.html và file và file kiểm tra điều kiện đăng nhập là login.php như sau:

bao-mat-1-2

File login.html

bao mat 1-3

File login.php

Và khi đó ta có một trang đăng nhập với giao diện:

bao mat 1-4

Demo giao diện login

Và một CSDL mySQL với 1 bảng user như sau:

bao mat 1-5

Database kèm theo

Xét vấn đề bị vượt chứng thực đăng nhập ở đây nằm ở 3 chỗ:
Thứ nhất: $u=$_POST['u'];  không chặn các ký tự đặc biệt như ‘,”,\,...
Thứ hai: $p=$_POST['p']; cũng không chặn các ký tự đặc biệt như ‘,”,\,...
Thứ ba: câu kiểm tra SELECT:

$sql=  "select * from user where username= '$u' and password='$p' ";

Thường thì các bạn có thói quen chết người là k quan trọng vấn đề nguy hiểm hay không mà chỉ quan trọng là chương trình chạy được là OK, nên viết như thế này:

$sql= "select  * from user where username= $u and password=$p ";

Để đăng nhập vào được hệ thống thì ta có các user tương ứng bên trên bảng user trong CSDL, có tài khoản là: admin/123456  |  Diem Kute/12345   |   aaaa1/123

Nhưng các bạn mà viết theo cách k chú tâm như cách kiểm tra SELECT này:

$sql= "select  * from user where username= $u and password=$p ";

Thì không chỉ có số tài khoản bên trên mà đăng nhập được mà đơn giản mọi đoan code (điền vào user và pass giống nhau) tương tự như sau đều đăng nhập được:

 1 OR 1=1     |    2 OR 2=2  |   ....   |    0=0 OR 1=1   |   0=0 OR 2=2    |  .....

Vậy bạn đã mất tài khoản quản trị của mình rồi ư? Không bạn không mất gì cả ngược lại bạn còn có thêm một người nữa quản trị tiếp mình ! Quan trọng là bạn có muốn điều đó xảy ra không ? Không! Không nhà quản trị web nào mà muốn người khác có tải khoản quản trị trái phép cả. Thế làm sao để khắc phục tình trạng này đây? Bên trên có 3 điều bị coi là vượt chứng thực thì bây giờ cần phải giải quyết 3 vấn đề đó để cho tin tặc không còn cơ hội vượt chứng thực nữa

2. Vấn đề thứ 2

Vấn đề thứ nhất và thứ 2 giống nhau đó là không check các ký tự đặc biệt thì giờ mình sẽ tiến hành xét các ký tự đặc biệt xử lý 2 cách như sau:

$u=addslashes($_POST['u']);  |   $p=addslashes($_POST[‘p’]); $u=mysql_real_escape_string($_POST['u']);  |   $p=mysql_real_escape_string($_POST['p']);

3. Vấn đề thứ 3

Vấn đề thứ ba cần viết lại câu truy vấn SELECT một cách an toàn như sau:

$sql=  "select * from user where `username`= '".$u."' and `password`='".$p."' ";

Cuối cùng ta sẽ được một file login.php để kiểm tra đăng nhập hoàn chỉnh như sau:

bao mat 1-6

Còn tiếp......

P/S: Trong phần tiếp theo sẽ trình bài tiếp về SQL injection: Dò tìm user, triệt tiêu sử dụng 1/0  và trình bày một vấn đề bảo mật mới trong loạt bài này.

Phần 2 xem tại đây

GV Huỳnh Công Đức

 

Bình luận  

 
0 #1 GiaiTriVip.Pro Thứ 6-03-13 15:24
cậu lệnh sql của em thê này đúng chưa anh anh xem giùm em với
$b=mysql_query("select url, name, thoigian, id, icon from top where `idm` = '".$ar['idm']." ' AND id != '".$ar['id']."' ORDER
BY RAND() LIMIT 5");
có cần thêm ` ` vào trong url, name ... không anh
Trích dẫn
 

Thêm ý kiến


Security code
Làm mới


2

Facebook

Thống kê truy cập

Hiện có 819 khách đang truy cập
2491980