(Post 12/05/2006) Giao dịch thông qua Internet
ngày càng phát triển, hàng loạt ngôn ngữ và giao thức thiết kế trang web
cũng ra đời để phục vụ cho những mục đích nhất định, có thể kể các ngôn
ngữ phổ biến như HTML, Perl, ASP, PHP... Bài viết này đề cập đến một vấn
đề thường gặp là bảo mật và kinh nghiệm phòng tránh để tăng độ an toàn
cho trang web.
HTML (Hyper Text Markup
Language)
HTML được phát triển từ 1989 và được sử dụng rộng rãi
cho đến nay. Một trang HTML là một tệp dữ liệu dạng văn bản có phần mở
rộng .htm hay .html, bao gồm những thành phần HTML. Khi người dùng xem
một trang HTML, trình duyệt sẽ có nhiệm vụ phân tích và hiển thị thông
tin tương ứng với những thành phần đó. Ở đây chúng ta chỉ phân tích về
khía cạnh bảo mật của các thành phần HTML thông dụng.
<form>
Hình 1:
Trang web đăng nhập đơn giản |
|
Đây là đối tượng không thể thiếu khi trang web của bạn
cần nhận thông tin từ người sử dụng. Tuy nhiên xét về khía cạnh bảo mật,
các thành phần cho phép người dùng nhập thông tin lại là khởi đầu cho
nguy cơ bị khai thác – hay nói cách khác là mục tiêu đầu tiên mà hacker
nhắm đến. Ở các chương trình thiết kế không tốt, nếu thông tin nhận từ
người dùng không phù hợp định dạng hoặc không như mong muốn chúng có thể
tạo nên những kết quả khó lường. Chúng ta sẽ cùng phân tích một ví dụ
đơn giản về một trang HTML có form cho phép nhập tên người dùng và mật
khẩu, địa chỉ truy cập là http://www.sampleweb.com/login.html có nội dung
như sau:
<html>
<form method=POST action=”admin/login.asp”>
Hãy nhập thông tin đăng nhập vào trang quản trị:<br>
Username:
<input value=”” size=40 maxlength=80 name=”username”><br>
Password:
<input value=”” size=40 maxlength=80 name=”password”>
<input type=hidden name=”user_role” value=1>
<input type=hidden name=”tries” value=3>
<input type=submit value=”Login”>
</form>
</html>
HTML form ở ví dụ trên thoạt nhìn rất đơn giản nhưng
lại tiềm ẩn nhiều nguy cơ. Giả định khi người dùng truy cập vào địa chỉ
http://www.sampleweb.com/login.html và nhập tên người dùng là “admin”,
mật khẩu là “testpassword”, sau đó nhấn login. Nhiệm vụ của form là nhận
tên người dùng và mật khẩu rồi dùng phương thức POST để gửi yêu cầu đến
một ứng dụng web kiểm tra login ở máy chủ có tên là “login.asp”. Tuy nhiên,
nếu phân tích kĩ hơn ta có thể thấy trang login này bộc lộ nhiều sơ hở
mà hacker có thể lợi dụng. Điều rõ ràng nhất ta nhận thấy khi người dùng
truy cập vào địa chỉ http:// thì dữ liệu được truyền đi trên mạng từ browser
của người dùng đến máy chủ dưới dạng plaintext, tức là không được mã hóa.
Như vậy chỉ cần có trong tay một chương trình network sniffer (xem lén
nội dung các gói tin truyền trên mạng) như Ethereal và một chút may mắn
cộng kiên nhẫn, một tay hacker hạng xoàng ngồi ở một máy client khác cũng
có thể bắt được các thông điệp HTML truyền đi từ máy người dùng trên.
Dưới đây là nội dung một thông điệp như vậy:
[ POST /admin/login.asp HTTP/1.1Accept: image/gif, image/x-xbitmap,
image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint,
application/msword, application/x-shockwave-flash, */*Accept-Language:
en-usContent-Type: application/x-www-form-urlencodedAccept-Encoding: gzip,
deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;
SV1; .NET CLR 1.1.4322)Host: www.sampleweb.comContent-Length: 68Connection:
Keep-AliveCache-Control: no-cache
username=admin&password=testpassword& %3Fuser_role%3F=1&%3Ftries%3F=3
Date: Mon, 30 May 2005 09:00:34 GMTServer: ApacheExpires: Mon, 30
May 2005 10:00:34 GMTConnection: closeTransfer-Encoding: chunkedContent-Type:
text/html
]
Nội dung gói tin bắt được ở phần màu đậm cho thấy rõ
yêu cầu (POST request) gửi đi bao gồm tên người dùng (username), mật khẩu
(password), quyền hạn (user_role), số lần đăng nhập thử (tries) và các
thông tin quan trọng khác. Sẽ thật sự nguy hiểm hơn nếu bằng cách nào
đó hacker chiếm được quyền điều khiển của một máy chủ gateway (cổng ra
Internet) và chạy sniffer trên máy này, khi đó tất cả thông tin từ các
trạm làm việc trong mạng nội bộ sẽ bị tóm bởi sniffer này trước khi chúng
được gửi ra Internet. Với một tay hacker có hạng, gói tin bắt được có
thể bị thay đổi vài thông tin quan trọng sau đó tiếp tục được gửi đến
máy chủ và thông tin hồi đáp từ máy chủ có thể sẽ không như người dùng
thật sự mong muốn nhưng lại thoả mãn yêu cầu của hacker.
Kinh nghiệm phòng tránh:
Trước khi bàn đến chuyện phòng tránh, chúng ta cần hiểu
rằng không có hệ thống nào là bảo mật hoàn hảo, cũng không có biện pháp
nào phòng tránh tuyệt đối. Những nỗ lực đưa ra chỉ có hiệu lực ở mức độ
nhất định và tồn tại trong một thời gian nhất định đến khi người ta tìm
ra cách mới để vượt qua nó.
Để bảo đảm tính an toàn cao cho dữ liệu trao đổi qua
lại giữa người dùng và server, các nhà quản trị thường chọn giải pháp
sử dụng SSL (Secure Socket Layer) cho trang web (trong phạm vi bài viết
này tôi không mô tả chi tiết về SSL và cách thức cài đặt máy chủ hỗ trợ
SSL, bạn đọc có thể tham khảo các tài liệu trên Internet). Khi đó người
sử dụng sẽ truy cập vào trang web theo địa chỉ https:// thay vì http://
và những thông tin trao đổi sẽ được mã hoá trên đường truyền với mức độ
an toàn rất cao.
Quay lại chủ đề hiện tại, ở phía trình duyệt người dùng, các thông tin
được truyền đi từ HTML form cần được mã hóa trước khi gửi đi (trang đăng
nhập của Yahoo mail cũng áp dụng cách thức này). Như vậy trang web cần
cài đặt thêm mã lệnh để mã hóa dữ liệu người dùng nhập vào ở mức client
trước khi gửi yêu cầu đến máy chủ. Đối với các giá trị ngầm định được
đặt sẵn như trong ví dụ trên:
<input type=hidden name=”user_role” value=1>
<input type=hidden name=”tries” value=3>
Nếu trang web của bạn thật sự cần những thông số ngầm
định như vậy, hãy mã hóa chúng khi thiết kế và khi server nhận được yêu
cầu, server sẽ giải mã các tham số trước khi xử lý và trả kết quả về cho
người dùng. Ví dụ:
<input type=hidden name=”user_role” value=!”#$%>
<input type=hidden name=”tries” value=!”#$%Xxls3>
Ở phía server, khi thiết kế ứng dụng bạn luôn luôn nhớ
nguyên tắc sau:
Dữ liệu nhận được từ client luôn có thể bị thay đổi ngoài
ý muốn, đừng bao giờ tin cậy hoàn toàn các dữ liệu này. Ứng dụng của bạn
cần lọc và kiểm tra chặt chẽ các dữ liệu này ngay khi nhận được trước
khi tiến hành các bước xử lý tiếp theo.
<form action>
Thuộc tính action dùng để chỉ định một ứng dụng web trên
máy chủ cho đối tượng form có nhiệm vụ nhận, xử lý thông tin và trả kết
quả về cho người dùng. Ví dụ: <form action = “admin/login.asp”>
... Khi biết được tên chương trình, người ta có thể tìm hiểu thêm các
thông tin có giá trị về web server, về thư mục hiện hành của chương trình.
Thử phân tích thuộc tính action trong ví dụ trên, trước
hết ta có thể thấy trang web đăng nhập được đặt tại thư mục /admin trên
thư mục gốc của website (web root) - nhiều nhà thiết kế web có thói quen
đặt các tệp dữ liệu quan trọng như các tệp cơ sở dữ liệu, danh sách khách
hàng... vào thư mục /admin hoặc /database và đặt tên rất dễ đoán, điều
này sẽ tạo cơ hội cho hacker thử tài. Kế đến, ta biết được ngôn ngữ phía
server sử dụng là ASP, từ đó có thể suy ra máy chủ sử dụng là IIS và hệ
điều hành Windows Server. Với kinh nghiệm mày mò trên net, hacker có thể
dễ dàng tìm được rất nhiều lỗ hổng bảo mật liên quan đến các máy chủ Windows
IIS và ngôn ngữ ASP.
Kinh nghiệm phòng tránh:
Kết hợp với các phương pháp ở mức HTML form vừa đề cập,
ở mức <form action> cần hạn chế tối đa việc chỉ định tường minh
tên thư mục trên server như /admin... thay vào đó hãy tạo các thư mục
ảo (virtual directory) trên web server và cài đặt cấu hình web server
để chuyển hướng các yêu cầu đến URL cụ thể vào thư mục thật sự trên máy
chủ. Ngoài ra, hãy cài đặt và sử dụng giao thức https khi gọi một ứng
dụng web trên máy chủ, ví dụ <form action = “https://www.sampleweb.com/admin/login.asp”>
. Điều này đảm bảo thông tin truyền đi trong yêu cầu được mã hóa và giảm
thiểu khả năng bị khai thác.
<form method>
Phương thức của form, định nghĩa cách thức dùng để gửi
thông tin người dùng nhập vào đến máy chủ web cho chương trình xử lý.
Khi hiểu được cách thức gửi thông tin (POST, GET, PUT...), hacker có thể
theo dõi và “bắt” các thông tin được gửi trên mạng, thậm chí có thể thay
đổi chúng và gửi đi với giá trị khác để tạo ra những kết quả mà quản trị
viên không mong muốn, đặc biệt là các thông tin liên quan đến quá trình
đăng nhập vào trang web. Thực tế trên mạng có rất nhiều công cụ được tạo
ra để phục vụ mục đích này, điển hình như Brutus-AET hoặc WebCracker có
khả năng tạo tự động các yêu cầu GET hoặc PUT chứa username và password
thử đăng nhập vào trang web từ một danh sách các username và password
dạng từ điển có sẵn.
Trong các phương thức gửi yêu cầu đến ứng dụng trên server,
POST và GET được sử dụng hầu hết ở các HTML form. Xét về mặt bảo mật,
điểm khác biệt giữa 2 phương thức này ở cách thức hoạt động của chúng,
POST request được đặt trong phần header của thông điệp HTML gửi đến server
(xem lại phần bắt gói tin ở phần HTML form ở trên) do đó request này sẽ
không được ghi lại (log) trên server và client, trong khi đó GET request
sẽ được ghi lại vì các thông tin gửi đi được đặt ngay trên URL, ví dụ:
http://www.sampleweb.com/admin/login.asp?username=admin&
password=testpassword&%3Fuser_role%3F=1&%3Ftries%3F=3
Những yêu cầu đến ứng dụng web trên server thông qua
phương thức GET sẽ được ghi lại ở các nơi sau:
Nhật kí truy cập (access log) của web server và proxy
server
Vùng dữ liệu tạm (temporary cache và history) của trình
duyệt phía người dùng
Nhật kí truy cập của các chương trình tường lửa (firewall)
ở cả server và client.
Kinh nghiệm phòng tránh:
Việc lưu lại các thông tin và yêu cầu truy cập tạo điều
kiện thuận lợi cho hacker dò tìm các thông tin nhạy cảm, do đó để hạn
chế khả năng bị xem lén thông tin trên các log ta nên lưu ý như sau:
Tránh sử dụng phương thức GET trong HTML form, hãy sử
dụng POST.
Ứng dụng web phía server được viết để nhận dữ liệu theo
phương thức cụ thể nào (POST, GET, PUT...) cần kiểm tra yêu cầu nhận được
có đúng được gửi theo phương thức được hỗ trợ không, nếu không cần thông
báo lỗi cho người dùng. Điều này giúp tránh trường hợp hacker lợi dụng
các công cụ “dò” web bằng cách thử liên tục các giá trị tên người dùng
và mật khẩu thông qua các request dạng GET hoặc PUT.
<script language=<variable>>
Biến truyền vào là ngôn ngữ script phía client, chẳng
hạn như javascript, vbscript, XML... Ở các trang đăng nhập hệ thống hoặc
các trang buôn bán trực tuyến, người thiết kế web thường dùng các script
chèn vào trang html để kiểm tra tính hợp lệ của dữ liệu phía người dùng
(client). Bằng cách thay đổi loại ngôn ngữ hoặc thậm chí cài đặt thêm
mã bằng ngôn ngữ khác, hacker có thể vượt qua các bộ lọc kiểm tra được
cài đặt sẵn trong trang web.
Lấy ví dụ HTML form ở trên, để tránh trường hợp người
dùng nhập các kí tự đặc biệt vào cho trường dữ liệu tên và mật khẩu, người
ta viết thêm đoạn script kiểm tra như sau:
<html>
<script language=”javascript”>
function CheckForm(){
đoạn mã kiểm tra username để loại các kí tự đặc biệt như: - + = --
“”...
đoạn mã kiểm tra password để loại các kí tự đặc biệt như: - + = --“”
...
}
</script>
<form method=POST action=”admin/login.asp” onsubmit = “return
CheckForm();”>
....
<input type=submit value=”Login”>
</form>
</html>
Như vậy, chỉ cần tạo 1 bản sao của trang web đăng nhập
dùng chức năng View Source của browser và lưu lại trên đĩa, sau đó sửa
lại nội dung ở các phần kiểm tra và địa chỉ trình thực thi trong HTML
form thì hacker có thể gửi tên và mật khẩu với nội dung mong muốn đến
web server mà không còn chịu sự kiểm tra ở mức client.
Kinh nghiệm phòng tránh:
Trong trường hợp này, ngoài việc kiểm tra ở phía client,
trình thực thi cũng cần kiểm tra bổ sung ở phía server khi nhận được request.
Ở ví dụ trên, trong trường hợp hacker cố tình sửa đổi trang đăng nhập
để có thể gửi đi yêu cầu có mật khẩu chứa các kí tự đặc biệt ví dụ như
“testor 1=1--” thì trang login.asp phía server cũng có thể lọc lại các
giá trị không hợp lệ này và thông báo lỗi cho người dùng.
<input>
Thành phần textbox để người dùng nhập thông tin vào HTML
form. Nếu ứng dụng web không xử lý tốt các thông tin nhập vào, hacker
có thể lợi dụng nhập vào các giá trị đặc biệt đánh lừa hệ thống và tạo
nên những kết quả không mong muốn. Dưới đây là một số kiểu khai thác thường
được hacker sử dụng đối với đối tượng <input>:
Truyền những giá trị đặc biệt yêu cầu hệ thống cơ sở
dữ liệu thực thi lệnh khai thác dữ liệu. Ví dụ giá trị username và password
dạng “testor 1=1--” dùng trong kĩ thuật SQL Injection (tham khảo bài viết
về SQL Injection, TGVT A tháng 12/2002 - trang 96) giúp hacker dễ dàng
đăng nhập dưới quyền cấp cao, từ đó có thể tiếp tục lợi dụng thực thi
các lệnh hệ thống, điều khiển máy chủ.
Chèn script dạng Cross-site-scripting (CSS/XSS)
Ví dụ:
http://www.testweb.com/input.asp?data=<script>alert(Kiểm tra);</script>
hoặc
http://www.testweb.com/input.asp?data=<script>alert(document.cookie)</script>
Hacker có thể lợi dụng dạng sơ hở này để lấy trộm cookies
(thông tin người dùng và thông tin truy cập các trang web) của người dùng
đang truy cập.
Khai thác lỗi tràn bộ đệm (Buffer over flow). Trong trường
hợp ứng dụng web không kiểm tra chiều dài dữ liệu nhập, hacker có thể
truyền vào một giá trị rất lớn (ví dụ 1 chuỗi chứa một triệu kí tự A)
gây lỗi tràn bộ đệm phía server. Hậu quả có thể làm máy chủ ngừng hoạt
động, thậm chí chạy những mã nguy hiểm do hacker đính kèm.
<input type=hidden>
Kiểu đối tượng input không hiện trên trình duyệt. Một
số trang web dùng đối tượng input với thuộc tính hidden để chứa giá trị
mặc định như giá mua hàng ở các trang shopping hay gán quyền cho đối tượng
dữ liệu. Mặc dù là kiểu ẩn (hidden), không hiện ra khi người sử dụng vào
trang web, nhưng đối tượng dạng này không thật sự an toàn và có thể dễ
dàng bị xem nội dung bằng thao tác xem mã nguồn (View > Source). Lợi
dụng đặc điểm này, hacker có thể thay đổi giá trị này thành giá trị mong
muốn và lặp lại thao tác gửi đến máy chủ web. Ở các trang web buôn bán,
nếu không có những xử lý giá trị phía server, hacker có thể mua được những
món hàng với giá giảm đáng kể hoặc không tốn đồng nào.
Thực tế cho thấy đã có một số trang web bị lợi dụng trường
hợp này, nếu giả định role=1 là người dùng bình thường, role=0 là người
quản trị (administrator) và nếu khi nhận được yêu cầu ứng dụng web phía
server chỉ đơn giản mang những giá trị này so sánh với danh sách đặc quyền
trong cơ sở dữ liệu và trích ra dữ liệu tương ứng với quyền đó thì một
đối tượng nhập liệu mang giá trị định sẵn dạng:
<input type=hidden name=”user_role” value=1>
hoàn toàn có thể bị thay đổi thành:
<input type=hidden name=”user_role” value=0>
Và khi đăng nhập, người dùng đó nghiễm nhiên mang đặc
quyền người quản trị.
<input maxlength=<variable>>, <input size=<variable>>
Giá trị maxlength và size xác định chiều dài của giá
trị nhập vào đối tượng input. Hacker có thể thay đổi giá trị maxlength
cho phép nhập vào những giá trị hoặc chuỗi rất dài quá khả năng xử lý
của ứng dụng phía server. Nếu không được xử lý thích hợp, chúng có thể
gây nên những lỗi như tràn bộ đệm để thực thi các lệnh điều khiển hoặc
thậm chí có thể làm ngừng hoạt động của máy chủ web.
Kinh nghiệm phòng tránh:
Tương tự như ở phần <script> ở trên, các trang
web cần cài đặt các đoạn mã kiểm tra tính hợp lệ của dữ liệu nhập vào
từ người dùng cho cả dạng <input> và <input type=hidden> nhằm
hạn chế tối đa khả năng bị thay đổi thông tin ngoài ý muốn, bao gồm:
Lọc các kí tự đặc biệt để tránh bị chèn thêm các mã lệnh
nguy hiểm như dạng Code Injection hoặc SQL Injection. Các đoạn mã lọc
cần phải được cài đặt ở cả client và server.
Kiểm tra chiều dài dữ liệu nhận được phía server để tránh
trường hợp tràn bộ đệm.
Tránh không dùng dạng đối tượng input ẩn để chứa giá
trị phân đặc quyền người dùng ở các trang đăng nhập vào web.
Dưới đây là 1 đoạn mã ví dụ đơn giản sử dụng VBScript
để kiểm tra tính toàn vẹn của dữ liệu ở trang đăng nhập, đoạn mã này sẽ
được thực thi phía trình duyệt người dùng (lưu ý, bạn cũng cần những đoạn
mã kiểm tra tương tự cài đặt trong ứng dụng web phía server).
<html>
...
<script Language=”VBScript”>
<!--
function Form1_onsubmit()
Set theForm = document.FrontPage_Form1
If (theForm.Username.value = “”) Then
MsgBox “Hãy nhập tên người dùng”, 0, “Báo lỗi”
theForm.Username.focus()
Form1_onsubmit = False
Exit Function
End If
If (Len(theForm.Password.value) < 12) Then
MsgBox “Mật khẩu không hợp lệ”, 0, “Báo lỗi”
theForm.Password.focus()
Form1_onsubmit = False
Exit Function
End If
checkOK = “ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz0123456789”
checkStr = theForm.Username.value
allValid = True
For i = 1 to len(checkStr)
ch = Mid(checkStr, i, 1)
If (InStr(checkOK, ch) = 0) Then
allValid = False
Exit For
End If
Next
If (Not allValid) Then
MsgBox “Tên người dùng không hợp lệ. Hãy nhập lại.”, 0, “Báo lỗi”
theForm.Username.focus()
Form1_onsubmit = False
Exit Function
End If
checkStr = theForm.Password.value
allValid = True
For i = 1 to len(checkStr)
ch = Mid(checkStr, i, 1)
If (InStr(checkOK, ch) = 0) Then
allValid = False
Exit For
End If
Next
If (Not allValid) Then
MsgBox “Mật khẩu không hợp lệ. Hãy nhập lại.”, 0, “Báo lỗi”
theForm.Password.focus()
Form1_onsubmit = False
Exit Function
End If
Form1_onsubmit = True
End Function
-->
</script>
<form METHOD=”POST” ACTION=”kiemtra.asp” name=”Form1”>
...
</form>
</html>
<applet> - Java applet.
Thuộc tính này dùng để chạy Java applet. Java được thiết
kế với những tính năng bảo mật cho người dùng khi duyệt các trang web
có nhúng Java applet hoặc Java script, như hạn chế quyền truy cập tài
nguyên trên máy (bộ nhớ, đĩa...), hạn chế thực thi các lệnh hệ thống,
chỉ cho phép truy cập dữ liệu (file, thư mục) ở những vùng chỉ định của
người dùng hiện tại, hạn chế truy cập vào mạng - trừ việc cho phép tạo
kết nối ngược về server chứa applet.
Tuy nhiên những năm gần đây, nhiều sơ hở bảo mật của
Java được khám phá:
Java chạy và gửi thông tin thường dưới dạng plain text
nên có thể dùng các chương trình theo dõi gói tin để bắt các thông tin
này khi chúng đang lưu thông trên mạng.
Mã Java trong các applet có thể dịch ngược để xem mã
nguồn.
Mã Java khi chạy trên các hệ thống Windows 95/98/NT bị
lợi dụng gây lỗi tràn bộ đệm từ đó có thể tác động đến hệ thống file hoặc
thậm chí gây hỏng hệ thống.
Cơ chế bảo mật Java từng bị hạ gục ở một số trình duyệt
version trước và giúp hacker thực hiện các lệnh vốn không được phép.
Kinh nghiệm phòng tránh:
Hầu hết các lỗi bảo mật của Java xuất phát từ các điểm
yếu trong máy ảo Java (Java Virtual Machine) và trình duyệt phía người
dùng. Dưới đây là một số thủ thuật giúp tăng độ an toàn khi truy cập các
trang web có nhúng Java script hoặc Java applet:
Cập nhật các bản sửa lỗi cho hệ thống Windows và các
ứng dụng mới nhất tại http://windowsupdate.microsoft.com
Nếu dùng trình duyệt Internet Explorer 6.x, hãy vào menu
Tools/Internet Options, ở thẻ Security bạn chọn vùng Internet, mức an
toàn là “Medium” (trung bình) – hình 3, sau đó chọn phần “Custome level”,
trong hộp thoại “Security Settings” hãy di chuyển thanh trượt đến mục
Java VM/Permissions và chọn mức “High safety” (hình 4), tiếp tục xuống
dưới ở phần Scripting/Scripting Java applets, bạn chọn Disable (hình 5).
Phương pháp này sẽ hạn chế trình duyệt không cho phép chạy các Java script
và Java applet ở các trang web. Tuy nhiên mặt hạn chế của nó là phải bật
lại chức năng nếu bạn muốn cho phép mã Java chạy ở các trang web tin cậy.
<object>, <embed>
Thuộc tính này dùng để thể hiện các đối tượng ActiveX
và Java applet. Đặc biệt đối với ActiveX, lợi dụng thuộc tính này hacker
có thể gửi email dạng HTML có nhúng ActiveX control và đánh lừa người
dùng chạy các ActiveX control này để đoạt quyền điều khiển hệ thống hoặc
chạy những chương trình quấy rối, quảng cáo. Đây cũng là một trong những
phương pháp thường được lợi dụng để lan truyền virus trên mạng. Hầu hết
các phiên bản sau này của các trình duyệt đều cung cấp khả năng ngăn chặn
sự hoạt động của ActiveX control, tuy nhiên lại tạo ra những bất tiện
đáng kể cho người dùng.
Danh sách một vài bản sửa lỗi mới nhất được cài đặt cho Windows |
|
Kinh nghiệm phòng tránh:
Tương tự như cách phòng tránh cho thẻ <Java> vừa
đề cập, hầu hết các lỗi bảo mật liên quan đến đối tượng nhúng xuất phát
từ trình duyệt phía người dùng và một số dịch vụ của Windows. Sau đây
là 1 số cách bảo vệ trình duyệt và hệ thống của bạn:
Thiết lập các thông số cho trình duyệt. Tương tự như
phần <Java>, các trình duyệt thông dụng hiện nay như IE, Firefox
đều cho phép người dùng thay đổi các thiết lập ngầm định giúp duyệt web
an toàn hơn.
Sử dụng các phần mềm ngăn chặn popup/spyware/adsware
như CounterSpy, WebRoot SpySweeper, MS AntiSpy...
Hình 3 - Thiết lập Security cho IE |
|
PERL (PRATICAL EXTRACTION
AND REPORT LANGUAGE)
Perl là ngôn ngữ lập trình cấp cao được phát triển từ
năm 1987. Rất mạnh, tiện dụng và đồng thời là ngôn ngữ được phổ biến miễn
phí, hỗ trợ cho hầu hết các hệ thống từ Windows x/NT/2k/XP, các phiên
bản biến thể của Unix đến hệ thống AS/400, MacOS, Novell NetwarePerl...
Perl đã và đang được sử dụng rộng rãi trên Internet.
Perl được dùng chủ yếu cho các xử lý phía server, tuy
nhiên ta cũng có thể dùng perl để viết các ứng dụng client, thậm chí có
thể tạo nên ứng dụng chạy độc lập để thực hiện một tác vụ tính toán nào
đó.
Trên web server, perl thường được thực thi với CGI tạo
nên cơ chế xuất thông tin ra trình duyệt web. Hãy xem ví dụ dùng perl
để xử lý các thông tin nhập vào từ người dùng trong đoạn html dưới đây:
<form method=POST action=”/admin/login.pl”></form>
<html>
Username:
<input value=”” size=80 maxlength=80 name=”username”>
Password:
<input value=”” size=80 maxlength=80 name=”password”>
<input type=submit value=”Login”>
</html>
Sau khi người dùng nhập tên, mật khẩu và nhấn nút Login
những thông tin này sẽ được gửi đến chương trình perl có tên login.pl
nằm ở thư mục /admin/ trên web server. Chương trình login.pl sau khi xử
lý sẽ gửi kết quả ngược về trình duyệt web phía người dùng.
Hình 4 - Thiết lập bảo mật Java |
|
Kinh nghiệm phòng tránh:
Khi sử dụng perl để thực hiện các xử lý phía server,
ta cần lưu ý một số điểm quan trọng sau có khả năng gây nên những nguy
cơ về bảo mật nghiêm trọng:
Tránh thực thi các web server dưới quyền quản trị (root
trong Unix và administrator trong Windows). Các script ở web server được
chạy với quyền quản trị sẽ rất nguy hiểm nếu ai đó dùng nó để thực hiện
các lệnh điều khiển hệ thống. Script cgi-telnet được phổ biến trên Internet
là một ví dụ cụ thể.
Luôn thực hiện tiền xử lý các thông tin người dùng nhập
vào, như các giá trị tên người dùng, mật khẩu, giá cả... Tạo một chuỗi
các kí tự hợp lệ tương ứng với thông tin cần nhập và lọc ra những kí tự
được nhập không chính xác. Chẳng hạn với tên và mật khẩu người dùng, ta
có thể giới hạn ở các kí tự hợp lệ sau: “0..9”, “a..z”, “A..Z”; không
cho phép hoặc lọc bỏ các kí tự đặc biệt như: “/ \ + ) ( { } [ ] - _ =.|
& !”... Một ví dụ khác về việc dùng perl thực hiện tiền xử lý với
email người dùng, với yêu cầu email phải có kí hiệu @ và dấu chấm “.”
ở ít nhất là phần sau dấu @:
if ($email !~ /^[\w-]+\@[\w.-]+$/){
print “<br>#Error in your email. Please re-enter<br>”;
}else{
# thực hiện xử lý đối với thông tin email hợp lệ;
}
Hạn chế không cho phép thực thi các lệnh hệ thống (shell
command) như open(), fork(), system(), exec() hoặc cho thực hiện sau khi
đã kiểm tra chặt chẽ các tham số truyền vào. Ở các hệ thống bảo vệ lỏng
lẻo, hacker có thể lợi dụng truyền các tham số không thích hợp vào các
hàm trên để thực hiện các lệnh xem thông tin và điều khiển hệ thống.
Trên các hệ thống Unix, cần thiết lập các thông số $PATH
và $IFS bằng các giá trị chính xác cụ thể, tránh dùng các biến môi trường.
Ví dụ ta đặt như sau:
$ENV{“PATH”}=”/bin:/usr/bin:/opt”;
$ENV{“IFS”}=”/”;
Việc chỉ định không rõ ràng các thông tin trên có thể tạo điều kiện cho
hacker sửa đổi chúng và bắt các chương trình của chúng ta phải thực thi
một chương trình nguy hiểm nào đó ở nơi khác thay vì tại vị trí ta mong
muốn.
Hình 5 - Thiết lập bảo mật Java |
|
Kiểm tra kích thước và chiều dài của các thông tin người
dùng nhập vào hoặc dùng biến $ENV{CONTENT_LENGTH} để hạn chế chiều dài
của chuỗi dữ liệu cho các yêu cầu GET/POST. Nếu không được kiểm tra chính
xác, hacker có thể gửi đi một lượng dữ liệu có giá trị rất lớn hoặc rất
dài gây nên các lỗi tràn bộ đệm, hỏng web server và thậm chí tìm được
các điều kiện phát sinh lỗi tràn bộ đệm và thực thi các lệnh nguy hiểm
từ xa.
Tránh cho phép chỉ định đường dẫn cụ thể ở các trường
dữ liệu hoặc ở các tham số truyền vào các chương trình. Chỉ nên cho phép
các đường dẫn mang tính tương đối, cắt bỏ các giá trị có dạng dot dot
“..” hoặc slash “/\”. Ở rất nhiều chương trình web không kiểm tra đúng
đã cho phép người dùng nhập các tham số ví dụ /../../../../etc/passwd
(Unix) hoặc /../../../winnt/repair/sam._ (NT/2k) và dễ dàng lấy được các
thông tin về mật khẩu.
Các chương trình perl được lưu trữ dưới dạng text đơn
giản do đó có thể dễ dàng bị xem mã nguồn và lấy các thông tin có giá
trị như tên, mật khẩu truy cập cơ sở dữ liệu... nếu hacker đoạt được quyền
điều khiển hệ thống hoặc có quyền xem hệ thống file. Ta có thể dùng một
số chương trình ví dụ perl2exe cho phép chuyển đổi các tệp perl dạng text
sang dạng chương trình thực thi .exe, như vậy có thể tránh được việc tiết
lộ mã nguồn và không cần trình thông dịch perl khi chạy.
PHP (PERSONAL HOME PAGE)
Được phát triển từ năm 1995, PHP trở thành một trong
những ngôn ngữ script phía server phổ biến nhất bên cạnh Perl và ASP (Active
Server Pages). Tương tự như Perl, PHP có dạng cú pháp câu lệnh đơn giản,
dễ hiểu, đặc biệt thích hợp với các lập trình viên có hiểu biết về ngôn
ngữ C/C++ đồng thời có ưu điểm là thực thi rất nhanh và có thể chạy ở
máy client hoặc như một ứng dụng độc lập. Hiện nay người ta thường dùng
PHP để thực hiện các tác vụ xử lý phía server ở các web server trên nền
Unix, điển hình như Apache. Các chương trình PHP thường có phần mở rộng
là .php, .php3, .php4. Mã PHP cũng có thể nhúng vào một trang HTML. Hãy
xem ví dụ sau thực hiện in lên trình duyệt một chuỗi kí tự:
<!## PHP Example in HTML
<html>
<?php
echo “<br>Hello World!<br>”;
?>
</html>
Chú ý thẻ <? và ?> dùng để đánh dấu nơi bắt đầu và kết thúc mã
PHP.
Đoạn mã ví dụ sau là một trang Login đơn giản, thực hiện
kiểm tra thông tin người dùng và mật khẩu so với cơ sở dữ liệu:
<?
...
function check_user($user, $password){
if(connect()){
$password = substr($password, 0, 8);
$sql = “select * from users where username
= $user and password =$password”;
$result = mssql_query($sql);
if (mssql_num_rows($result) == 1){
setcookie(“user”,$user);
setcookie(“password”,$password);
return (true);
}
else{
?>
<h3>Đăng nhập không thành công!</h3>
<?
return (false);
}
}
}
if(!check_user($user, $password)){
?>
<h1>Nhập thông tin đăng nhập:</h1>
<form action = “Login.php” method=”post”>
<P>Tên người dùng: <input type=”text” name=”user”><br>
Mật khẩu: <input type=”password” name=”password”
maxlength=”8” size=”8”><br>
<input type=”submit” name=”submit” value=”Submit”>
</form>
<?
}
else{
?>
<h1>Đăng nhập thành công!</h1>
<?
}
?>
Ví dụ trên không kiểm tra giá trị tên người dùng và mật
khẩu trước khi kết nối vào cơ sở dữ liệu và hacker có thể lợi dụng để
chèn các kí hiệu và lệnh đặc biệt để thực thi các thao tác nguy hiểm.
Hình 6: Thiết lập kiểm soát ActiveX |
|
Kinh nghiệm phòng tránh:
Cho đến nay, những điểm yếu của PHP được phát hiện tương
tự như ở ngôn ngữ Perl. Đặc biệt khi sử dụng PHP để nhận các thông tin
nhập từ người dùng thông qua trình duyệt và xử lý cơ sở dữ liệu bên dưới;
hoặc thực thi các lệnh hệ thống như system(), shellexec(), exec(), passthru()...
ta cần chú ý thực hiện việc kiểm tra và lọc những dữ liệu truyền vào không
hợp lệ để tránh trường hợp người dùng nhập dữ liệu sai, đánh lừa hệ thống
sinh ra những kết quả không mong muốn, thậm chí thực thi các lệnh từ xa.
Ví dụ sau thực hiện việc kiểm tra đơn giản trên chuỗi
$value có kiểu số, dùng hàm định nghĩa sẵn trong thư viện PHP preg_match():
if (preg_match(“/^[0-9]+$/i”, $value))
echo “Invalid number!\n”;
return 1;
break;
Bổ sung cho ví dụ ở trên, ta thêm đoạn mã kiểm tra tính
hợp lệ của 2 trường tên và mật khẩu, giả định rằng tên và mật khẩu chỉ
được chứa các kí tự chữ và số:
<?
...
function check_user($user, $password)
{
//hàm ereg kiểm tra các kí tự đặc biệt trong trường Tên và Mật khẩu
if (!ereg (“([0-9,a-z,A-Z])”, $user))) return false;
if (!ereg (“([0-9,a-z,A-Z])”, $password))) return false;
if(connect()){
...
}
}
?>
Hàm ereg sử dụng Regular Expression để kiểm tra tính
hợp lệ của dữ liệu rất nhanh và hiệu quả. Dưới đây là các ví dụ trích
từ trang http://www.php.net sử dụng các hàm built-in của PHP để kiểm tra
và lọc dữ liệu:
// Hàm kiểm tra tính hợp lệ của e-mail:
function check_email ($string)
{
if (ereg(“^[A-Za-z0-9_\.\-]+@[A-Za-z0-9_\.\-]”+ “+\.[A-Za-z0-9_\-][A-Za-z0-9_\-]+$”,
$string, $result))
return (true);
return (false);
}
//Hàm loại bỏ các kí tự đặc:
function replace_data ($string)
{
$string = preg_replace(“/[^a-zA-Z0-9\-\.\@\_]/”, “”, $string);
return ($string);
}
Để tìm hiểu chi tiết thông tin về các hàm và các ví dụ cụ thể, các bạn
hãy tham khảo thêm tại trang chủ PHP
.
LỜI KẾT
Bảo mật ngôn ngữ web chỉ là một trong các bước tăng cường
an toàn cho hệ thống của bạn. Trong vai trò người phát triển và quản trị
web, một trang web được xem là an toàn khi máy chủ được bảo vệ và tối
ưu hóa ở mức cao nhất, các ứng dụng web cần được kiểm tra độ tin cậy và
tính toàn vẹn dữ liệu trước khi công bố rộng rãi đến người dùng, điều
đó cần một quy trình phát triển ứng dụng mang tính chuyên nghiệp và được
hoạch định rõ ràng.
Đối với người dùng, chúng ta cũng phải chủ động tự bảo
vệ hệ thống của mình trước những hiểm họa tiềm tàng trên Internet bằng
cách tăng cuờng các hệ thống phòng thủ như tường lửa, phòng chống virus
và spyware, liên tục cập nhật các bản sửa lỗi mới nhất và đặc biệt là
tuyệt đối tránh duyệt các trang web có nội dung không lành mạnh, vì chúng
là những điểm có nguy cơ lây lan cao.
Bảo mật máy tính, đó là một câu chuyện dài không bao
giờ kết thúc.
Nguyễn Văn Sơn
Global Cybersoft Vietnam
(theo PC World VN) |