Trong thiết kế web một số lỗi bảo mật cơ bản nhưng nếu chúng ta bỏ qua thì cũng ảnh hưởng rất lớn đến website của mình. Sau đây là 11 nguyên tắc dành cho các bạn phát triển một trang web giảm bớt được sự tấn công của những kẻ phá hoại.
1. An toàn trước khả nǎng bị tấn công CSS (Cross-Site Scripting)
Kiểu tấn công CSS điển hình nhất xảy ra khi tin tặc cố tình chèn một đoạn vǎn bản có chứa script độc hại vào các form nhập dữ liệu. Nội dung nhập vào có thể chứa các thẻ <OBJECT> hoặc <SCRIPT> cùng các đoạn mã hết sức nguy hiểm. Trình duyệt, khi truy nhập site, cho rằng các srcipt này do máy chủ gửi tới, hoàn toàn vô hại nên sẽ chạy nó ở cấp độ bảo mật bình thường, gây ra hậu quả tai hại cho máy tính của người sử dụng .
Để bảo vệ khỏi bị tấn công theo kiểu CSS, cần chú ý ít nhất những điểm sau:
- Cập nhật thường xuyên các bản sửa lỗi bảo mật mới nhất của IIS và Windows.
- Lọc các ký tự đặc biệt do người sử dụng nhập vào như < > " ' % ( ) & + -
- Lọc để loại bỏ các ký tự đặc biệt, kết xuất trên cơ sở thông tin nhập vào của
người sử dụng. Xem kỹ các dữ liệu từ:
Code:
- Request.Form Collection
- Request.QueryString Conllection
- Request Object
- Database
- Cookie
- Các biến Session và Application
Để có thể lọc được, cần xác định cụ thể lược đồ mã hoá ký tự trên các trang Web,
trong thẻ META, ở phần header. Ví dụ:
<head> <META http-equiv="Content-Type" Content="text/html; charset=ISO-8859-1">
</head>
2. Ứng dụng có thể không cần sử dụng các cookie thường trực
Cookie thường trực là những tệp, được các ứng dụng Web gửi tới máy tính người sử dụng và vẫn tồn tại trên ổ cứng của máy tính ngay cả khi họ không còn duyệt site. Chúng lưu một số thông tin về người sử dụng để các ứng dụng Web tuỳ biến nội dung cho phù hợp với từng đối tượng người sử dụng hoặc cho phép họ bỏ qua giai đoạn đǎng ký đǎng nhập. Các cookie không thường trực được lưu trong bộ nhớ máy tính của người sử dụng và chỉ tồn tại trong thời gian người sử dụng duyệt site. IIS dựa vào các cookie không thường trực để xác định một phiên ASP. Không có nó, IIS không thể duy trì bất kỳ các thông tin về phiên làm việc, chẳng hạn như các biến phiên.
Nếu site của bạn sử dụng cookie thường trực, không nên yêu cầu IIS lưu trữ chúng trong tệp log của IIS. Nếu tệp log lưu lại tất cả các thông tin đǎng nhập của
người sử dụng thì rất có nhiều khả nǎng, do một thoả hiệp nào đó, những thông tin này có thể được tiết lộ ra ngoài.
3. Sử dụng SSL cho tất cả các trang nhạy cảm được chuyển trên mạng Internet
SSL mã hoá nội dung của các thông điệp TCP/IP để nó không bị nhòm ngó trên đường truyền. SSL, hoặc một giải pháp mã hoá khác VPN chẳng hạn, rất cần thiết khi gửi các thông tin nhạy cảm (như số thẻ tín dụng) qua mạng. Cơ hội thâm nhập đường truyền và lấy cắp các thông tin bí mật là thấp song không phải không thể có. Người sử dụng sẽ không đặt niềm tin vào site của bạn nếu các thông tin nhạy cảm không được mã hoá.
Tuy nhiên, mặt trái của SSL là làm chậm lại hiệu nǎng thực hiện của ứng dụng. Mức sử dụng tài nguyên hệ thống CPU đòi hỏi trong tiến trình mã hoá và giải mã cho một trang SSL có thể cao hơn từ 10 đến 100% so với các trang không được bình thường. Nếu máy chủ của bạn có lưu lượng các trang SSL cao, bạn có thể phải cân nhắc tới việc sử dụng thêm một bộ tǎng tốc SSL phần cứng.
4. Yêu cầu người sử dụng đǎng nhập mỗi khi sử dụng ứng dụng
Nguyên tắc này áp dụng cho các ứng dụng có yêu cầu thủ tục đǎng nhập. Điều này có nghĩa là việc đǎng nhập tự động dựa trên cookie là không được phép. Mặc dù người sử dụng có thể thấy phiền hà nhưng nếu cho họ đǎng nhập tự động dựa trên cookie sẽ có rất nhiều nguy hiểm (và như ta đã thấy ở phần trước, sử dụng các cookie thường trực không phải lúc nào cũng phù hợp).
Một biện pháp tiếp theo cần thiết để bảo vệ mật khẩu là huỷ tính nǎng Autocomplete của IE trên các trường mật khẩu. Điều này có thể thực hiện bằng cách thêm thuộc tính AUTOCMPLET ="OFF" cho thẻ <FORM> hoặc <INPUT>.
Ví dụ:
<input type="password" name="pwd" size=16 maxlength=16 AUTOCOMPLETE="OFF">
5. Log out người sử dụng ra khỏi hệ thống ngay khi họ rời site
Giả sử một người sử dụng đang xem một trang web trên site của bạn, sau đó họ truy cập một site mới nhưng cuối cùng lại quyết định quay trở lại trang của bạn bằng cách ấn phím BACK. Trong trường hợp này, ứng dụng phải yêu cầu người sử dụng đǎng nhập lại một lần nữa. Phát hiện những tình huống tương tự như tình huống vừa rồi của người sử dụng phải dựa hoàn toàn vào các script chạy ở phía trình duyệt mà không thể dựa vào server vì nó không biết người sử dụng đã ở những đâu. Cách giải quyết đầy đủ nhất cho vấn đề này là sử dụng một giải pháp bảo mật Proxy Server như của Netegrity SiteMinder (CA Completes Netegrity Acquisition Advancing its Security Management Strategy). Giải pháp Proxy Server sẽ giám sát mọi yêu cầu Web từ trình duyệt và ghi lại mọi địa chỉ trình duyệt đã truy nhập để ứng dụng có thể kiểm tra.
Một cách thức không đầy đủ trong việc kiểm tra các giới hạn site có thể thực hiện bằng cách thiết lập Request.ServerVariables("HTTP_REFERER"). Nếu người sử dụng có gắng truy nhập bất kỳ trang nào khác với trang đǎng nhập, từ một URL của một site khác, thì họ sẽ bị từ chối. Tuy nhiên, phương pháp này không thể ngǎn ngừa một người sử dụng rời bỏ site của bạn để tới một site khác nhưng sau đó lại quay trở lại site của bạn và tiếp tục phiên làm của họ.
6.Cắt kết nối khi người sử dụng không tương tác với site trong một khoảng thời gian nhất định
Có hai giải pháp cho vấn đề này, một giải pháp ở phía máy chủ và một giải pháp sử dụng script ở phía trình duyệt. Trong giải pháp thứ nhất, chúng ta sử dụng IIS Manager và đặt giới hạn phiên ASP là một khoảng thời gian mong muốn nào đó (giá trị mặc định là 20 phút). Trong ứng dụng, lưu trữ thông tin truy nhập vào một biến phiên làm việc và kiểm tra nó trên mọi trang người sử dụng duyệt qua. Nếu thông tin truy nhập không thuộc về một biến phiên, người sử dụng đã bị cắt kết nối với site và ứng dụng cần định hướng họ sang trang truy nhập hệ thống. Hơn nữa, mặc dù chưa phải có thể tin cậy tuyệt đối, bạn cũng có thể viết mã để xử lý cắt kết nối người sử dụng trong sự kiện Session_OnEnd ở tệp Global.asa.
Giải pháp phía client sử dụng chút ít JavaScript. Chèn thêm đoạn mã sau vào đầu của mọi trang Web kết xuất bởi ứng dụng:
Code:
<script Language="JavaScript">
window.setTimeout("window.navigate('Logout.asp')", 900000); </script>
'Logout.ASP' là trang để cắt kết nối người sử dụng với ứng dụng. 9000000 là khoảng thời tối đa tính bằng mily giây người sử dụng vẫn duy trì phiên làm việc của họ trong trường hợp không có tương tác nào với site.
7. Ứng dụng không cho phép login đồng thời
Yêu cầu này có nghĩa là tại một thời điểm, người sử dụng không thể truy nhập ứng dụng với 2 phiên làm việc khác nhau. Đây cũng là nguyên tắc áp dụng cho phần lớn các ứng dụng client/server và máy trạm khác.
Trong môi trường IIS/ASP, việc đáp ứng yêu cầu này không có gì khó khǎn. 2 sự kiện Session_OnStart và Session_OnEnd trong Global.asa có thể sử dụng để kiểm tra phiên truy nhập hiện thời của người sử dụng. Bạn cũng có thể áp dụng một giải pháp của cơ sở dữ liệu để huỷ một phiên làm việc đang tồn tại khi một phiên làm việc mới được bắt đầu.
8. Mã nguồn ứng dụng không chứa chú thích của người phát triển
Bất cứ cấp bảo mật nào cũng có thể thất bại. Trong những trường hợp khi đã truy nhập được vào các tệp mã nguồn của Website thì những chú thích của người phát triển sẽ là những trợ giúp đắc lực cho tin tặc, nguy hiểm nhất là trong trường hợp mã nguồn có chứa những "viên ngọc" như tên và mật khẩu dùng trong quá trình chạy thừ ứng dụng. Yêu cầu này chỉ áp dụng cho những tệp script, chằng hạn như các trang ASP, không áp dụng cho các đoạn mã trong các đối tượng COM đã được biên dịch.
Trước đây, những điểm yếu về bảo mật chưa được khắc phục của IIS làm cho các script ASP trên một số site rất dễ bị đọc trộm. Nhiều tin tặc biết rằng học có thể đọc các script này bằng cách thêm chuỗi "::$DATE" vào cuối yêu cầu truy xuất trang. Để tránh các rủi ro có thể xảy ra, cần loại bỏ mọi chú thích trên trang ASP, HTML hoặc mã JavaScript. Bạn có thể thực hiện bằng tay nhưng cách nhanh nhất là viết một chương trình để loại bỏ các chú thích từ các loại tệp khác nhau.
9. Không lưu trữ thông tin kết nối cơ sở dữ liệu trong global.asa
Thông tin kết nối cơ sở dữ liệu gồm tên server , tên cơ sở dữ liệu, thông tin truy nhập SQL Server. Vì là một tệp vǎn bản, những thông tin trong global.asa có
thể bị lộ và rơi vào tay những đối tượng sử dụng không đúng mục đích. Những thông tin này nên được lưu trữ ở những nơi khác. Hai cách phổ biến là lưu trữ nó
trong một tệp hoặc trong một Register.
Lưu trữ thông tin kết nối cơ sở dữ liệu trong một tệp và sau đó có thể đọc được bằng File System Object hoặc XML Parser là cách an toàn hơn lưu trong
global.asa. Một giải pháp lưu thông tin trên tệp khác là sử dụng tệp UDL vì nó cho phép lưu tất cả các chi tiết về kết nối. Chuỗi kết nối ADO sẽ trở thành "FILE Name =C:\ Path_That_IUSR_<machinename>_Can_Get_To\MyDataLink .UDL" trong đó tài khoản dịch vụ IIS, IUSR_<machinename>phải có quyền truy nhập để đọc được tệp này.
Lưu các thông tin kết nối dưới hình thức được mã hoá trong registry là cách an toàn nhất. Điều này yêu cầu ứng dụng phải viết các thông tin mã hoá vào trong registry và các thành phần COM phải thu về và giải mã nó ở thời gian chạy.
Đối với IS 5, nếu sử dụng thành phần COM+, còn có một lựa chọn registry khác. COM+ cho phép mỗi thành phần có Constructor được thiết lập trong Component
Services Manager. Vì không mã hoá thông tin, cách này cho phép người quản trị site kiểm soát việc truy nhập cơ sở dữ liệu và thay đổi nó vào bất cứ lúc nào.
10. Các tệp audit log của cơ sở dữ liệu nên ghi nhận tất cả các thay đổi đối với dữ liệu
Các tệp audit log của cơ sở dữ liệu cung cấp các thông tin quá khứ về những thay đổi đối với dữ liệu trong các bảng. Một cách thông thường là tạo các trigger của cơ sở dữ liệu để ghi lại tất cả các thao tác Insert, Update và Delete. Tuy nhiên, ghi nhận tất cả thay đổi đối với mọi bản ghi có thể làm tǎng kích cỡ cơ sở dữ liệu của bạn lên nhiều lần. Để giảm khối lượng dữ liệu lưu, cần phải cân nhắc kỹ những thay đổi dữ liệu ở các bảng nào cần được ghi nhận. Mặc dù có thể tạo các bảng và viết trigger bằng tay, nhưng để giảm nhẹ khối lượng công việc, chúng ta có thể sử dụng giải pháp tự động. Một số sản phẩm và script miễn phí tại địa chỉ http://www.sqldevpro.com/articles/MagicAuditingCode.htm có thể giúp bạn thực hiện điều này.
11. Sử dụng các thủ tục lưu sẵn (stored procedure) để truy nhập cơ sở dữ liệu
Giới hạn việc truy nhập cơ sở dữ liệu, chỉ cho phép thực hiện thông qua các thủ tục lưu sẵn có nhiều ưu điểm về bảo mật và hiệu nǎng thực hiện. Cách tiếp cận
này nên được tính đến ngay từ khi bắt đầu phát triển ứng dụng để việc triển khai về sau được dễ dàng hơn.
Sử dụng thủ tục lưu sẵn an toàn hơn sử dụng ADO Recoredset hoặc các lệnh SQL bởi vì qua nó cho phép chỉ có người sở hữu cơ sở dữ liệu, dbo, mới có quyền quyền truy nhập tới bảng của tất cả những người sử dụng khác. Người sử dụng có quyền thi hành trên các thủ tục lưu sẵn nhưng không có quyền đọc hoặc sửa đổi dữ liệu trong các bảng một cách trực tiếp. Chỉ có dbo và người quản trị mới được phép sử dụng Query Analyzer hoặc Crystal Reports để làm việc với dữ liệu. Vì vậy, yêu cầu này có nghĩa là nếu Crystal Reports hoặc các công cụ tương tự khác được sử dụng trên Website, việc thu nhận dữ liệu phải được triển khai qua các thủ tục lưu sẵn.
Với cách tiếp cận này, chúng ta cần tạo 4 thủ tục cho mỗi bảng cho các lệnh Select, Insert, Update and Delete. Bạn cũng có thể tạo một lớp bao (wrapper
class) đóng vai trò là giao diện của thủ tục trong tầng truy nhập cơ sở dữ liệu của ứng dụng.
Dưới đây là thí dụ về thủ tục chèn dữ liệu vào bảng Authors trong cơ sở dữ liệu của một nhà xuất bản:
Code:
CREATE PROCEDURE dp_authors_ins @au_id varchar(11), @au_lname varchar(40),
@au_fname varchar(20), @phone char(12) = NULL OUTPUT , @address varchar(40) =
NULL , @city varchar(20) = NULL , @state char(2) = NULL , @zip char(5) = NULL ,
@contract bit AS IF @phone IS Null SET @phone = ('UNKNOWN')
INSERT INTO authors WITH (ROWLOCK) ( au_id, au_lname, au_fname, phone, address,
city, state, zip, contract) VALUES (@au_id, @au_lname, @au_fname, @phone,
@address, @city, @state, @zip, @contract)
SELECT @phone = phone FROM authors WHERE au_id = @au_id
GO
Đọc và thay đổi dữ liệu có hơi khác với cách tiếp cận thủ tục lưu sẵn. Thay vì làm việc với các recorset ADO hoặc tạo các câu lệnh SQL để thi hành trên server, tất cả việc truy nhập cơ sở dữ liệu đều thông qua đối tượng điều khiển ADO. Các đối tượng điều khiển ADO sẽ thi hành thủ tục lưu sẵn này.