Hình 11: Khoanh vùng web site

Một phần của tài liệu Xây dựng ứng dụng web ASP.NET an toàn (Trang 42 - 59)

Mặc định, các ứng dụng ASP.NET không impersonate, và tài khoản ASPNET ít đặc quyền nhất được dùng để thực thi các ứng dụng Web ASP.NET và cho việc truy nhập tài nguyên. Khuyến nghị sử dụng cấu hình mặc định. Có vài tình huống ta cần đến ngữ cảnh bảo mật khác của Windows cho việc truy cập tài nguyên. Bao gồm:

 Chạy nhiều ứng dụng trên cùng một server

Sử dụng IIS để cấu hình mỗi ứng dụng để sử dụng một tài khoản người dùng Internet ẩn danh. Mỗi ứng dụng có một đặc tính nhận dạng riêng cho việc truy cập tài nguyên

 Truy cập tới một tài nguyên ở xa với các yêu cầu xác thực cụ thể

Nếu cần truy cập tới các tài nguyên ở xa và được cấp một tài khoản Windows riêng để sử dụng, ta có thể cấu hình tài khoản này như một tài khoản người dùng Web ẩn danh cho ứng dụng.

d. Bảo vệ thông tin đăng nhập và các thẻ xác thực

Việc thiết kế nên quan tâm tới cách bảo vệ các thông tin nhận dạng và các thẻ xác thực. Các thông tin nhận dạng cần được bảo mật nếu chúng được truyền qua mạng và trong khi chúng được lưu trong các dạng cố định chẳng hạn như trong file cấu hình. Các thẻ xác thực phải được bảo mật qua mạng vì chúng là các lỗ hổng cho việc tấn công. Kỹ thuật mã hoá cung cấp một giải pháp SSL hoặc IPSec có thể được dụng để bảo vệ các thông tin nhận dạng và các vé qua mạng và DPAPI cung cấp một giải pháp tốt cho việc mã hoá các thông tin nhận dạng trong các file cấu hình.

e. Lỗi về bảo mật

Nếu ứng dụng của ta bị lỗi với một điều kiện ngoại lệ không thể khắc phục, cần đảm bảo các thông báo lỗi không được trả về phí trình duyệt của người dùng. Ta có thể sử dụng kỹ thuật nắm bắt ngoại lệ có cấu trúc để giải quyết vấn đề này.

d. Xem xét về chứng thực tập trung

Nếu ta cấu hình một thư mục yêu cầu xác thực thì tất cả người dùng có quyền truy cập như nhau tới các trang trong thư mục. Nếu cần thiết, ta có thể áp dụng các nguyên tắc chứng thực khác nhau cho mỗi trang dựa vào đặc tính nhận dạng, hoặc các vai thành viên bằng cách sử dụng thành phần <authorization> với thành phần <location>

e. Đặt các điều khiển web và các điều khiển người dùng trong các gói assemblies riêng biệt

Khi các điều khiển Web và các điều khiển người dùng được đặt trong các gói assemblies riêng thì ta có thể cấu hình bảo mật cho mỗi gói một cách độc lập bằng cách sử dụng chính sách code access security. Điều này cung cấp thêm sự linh hoạt cho người quản trị và cũng có nghĩa là bạn không bị ép buộc cấp các quyền rộng ra cho toàn bộ điều khiển chỉ để thoả mãn các yêu cầu của một điều khiển.

f. Đặt mã truy nhập tài nguyên trong một gói assembly riêng

Sử dụng các gói assemblies riêng biệt và gọi chúng từ các lớp của trang của ta hơn là nhúng mã truy nhập tài nguyên vào trong các bộ nắm bắt sự kiện của lớp của trang. Điều này cung cấp sự linh hoạt cho chính sách code access security và là điều quan trọng cho việc xây dựng các ứng dụng partial-trust Web.

3.2.3. Các kỹ thuật với các hiểm hoạ điển hình

a. Kiểm tra giá trị đầu vào

Việc kiểm tra kiểu, độ dài, định dạng hoặc phạm vi của dữ liệu vào sẽ tránh được một số vụ tấn công.

 Ràng buộc và cải tiến

Kiểm tra kiểu, độ dài, định dạng và phạm vi của giá trị đầu vào, đôi khi cần cải tiến giá trị đầu vào làm nó an toàn hơn

Yêu cầu Tuỳ chọn

Kiểm tra kiểu

.System.Parse biến đổi kiểu thành kiểu mạnh và nắm bắt ngoại lệ

FormatException

Sử dụng các biểu thức kiểm tra. Dùng điều khiển

RegularExpressionValidator hoặc lớp Regex.

Kiểm tra độ dài Các biểu thức thông thường

Sử dụng thuộc tính String.Length

Kiểm tra định dạng Dùng biểu thức thông thường

Hệ thống kiểu .NET Framework

Kiểm tra phạm vi (adsbygoogle = window.adsbygoogle || []).push({});

Điều khiển RangeValidator ( hỗ trợ dữ liệu kiểu currency, date, integer, double, và string)

So sánh kiểu dữ liệu

 Regular Expressions

Có thể sử dụng các biểu thức thông thường để hạn chế phạm vi các ký tự hợp lý và lược bỏ các ký tự không mong muốn, và để thực hiện việc kiểm tra độ dài và định dạng. ASP.NET cung cấp điều khiển RegularExpressionValidator và lớp Regex là có sẵn từ không gian tên System.Text.RegularExpressions.

Việc kiểm tra ở phía client và server là khác nhau. Phía client sử dụng cú pháp biểu thức của Jscript. Phía server sử dụng cú pháp System.Text.RegularExpression. Regex.

Regex regex = new Regex(@"

^ # anchor at the start

(?=.*\d) # must contain at least one digit (?=.*[a-z]) # must contain one lowercase

(?=.*[A-Z]) # must contain one uppercase .{8,10} # From 8 to 10 characters in length $ # anchor at the end",

RegexOptions.IgnorePatternWhitespace);

 String Fields

Để kiểm tra các trường dữ liệu kiểu xâu như tên, địa chỉ, …ta sử dụng các biểu thức thông thường để :

 Ràng buộc phạm vi có thể chấp nhận của các ký tự đầu vào.

 Áp dụng các nguyên tắc định dạng như: các mẫu ZIP code, postal code,..

 Kiểm tra độ dài

Tên:

Ví dụ dưới đây sử dụng điều khiển RegularExpressionValidator để kiểm tra trường tên.

<form id="WebForm" method="post" runat="server">

<asp:TextBox id="txtName" runat="server"></asp:TextBox> <asp:RegularExpressionValidator id="nameRegex"runat="server" ControlToValidate="txtName" ValidationExpression="[a-zA-Z'.`-´\s]{1,40}" ErrorMessage="Invalid name"> </asp:regularexpressionvalidator> </form>

<form id="WebForm" method="post" runat="server"> <asp:TextBox id="txtSSN" runat="server"></asp:TextBox> <asp:RegularExpressionValidator id="ssnRegex" runat="server" ErrorMessage="Invalid social security number"

ValidationExpression="\d{3}-\d{2}-\d{4}" ControlToValidate="txtSSN">

</asp:RegularExpressionValidator> </form>

Hoặc có thể sử dụng lớp System.Text.RegularExpression.Regex trong mã.

if (!Regex.IsMatch(txtSSN.Text, @"^\d{3}-\d{2}-\d{4}$")) {

// Invalid Social Security Number }

 Date Fields

Với các trường dữ liệu ta có thể biến đổi kiểu để kiểm tra. Chẳng hạn, để kiểm tra một ngày, ta có thể biến đổi giá trị vào thành một biến của kiểu System.DateTime và nắm bắt ngoại lệ nếu giá trị vào không tương thích.

try {

DateTime dt = DateTime.Parse(txtDate.Text).Date; }

// Nếu biến đổi sai sẽ phát sinh một ngoại lệ FormatException catch( FormatException ex ) (adsbygoogle = window.adsbygoogle || []).push({});

{

// thông báo lỗi }

Ngoài ra để định dạng và kiểm tra kiểu ta có thể thực hiện việc kiểm tra phạm vi trên một trường ngày . Cách này đựoc thực hiện dễ dàng hơn.

DateTime dt = DateTime.Parse(txtDate.Text).Date; if ( dt > DateTime.Now.Date )

throw new ArgumentException("Date must be in the past");

 Các trường số

Có thể sử dụng Int32.Parse hoặc Convert.ToIn32 và nắm bắt ngoại lệ

FormatException để kiểm tra.

try { int i = Int32.Parse(txtAge.Text); . . . } catch( FormatException) { . . . } Range Checks

Sử dụng điều khiển RangeValidator để kiểm tra phạm vi dữ liệu. Chẳng hạn kiểm tra giá trị vào là các số từ 0 đến 255.

<form id="WebForm3" method="post" runat="server">

<asp:TextBox id="txtNumber" runat="server"></asp:TextBox> <asp:RequiredFieldValidator

id="rangeRegex" runat="server"

ErrorMessage="Please enter a number between 0 and 255" ControlToValidate="txtNumber"

</asp:RequiredFieldValidator> <asp:RangeValidator

id="RangeValidator1" runat="server"

ErrorMessage="Please enter a number between 0 and 255" ControlToValidate="TextBox1"

Type="Integer" MinimumValue="0" MaximumValue="255"

style="LEFT: 10px; POSITION: absolute; TOP: 47px" > </asp:RangeValidator>

<asp:Button id="Button1" style="LEFT: 10px; POSITION: absolute; TOP: 100px" runat="server" Text="Button"> </asp:Button> </form> Hoặc có thể sử dụng lớp Regex: try { int i = Convert.ToInt32(sInput); if ((0 <= i && i <= 255) == true) {

// data is valid, use the number }

}

catch( FormatException ) {

. . . }

 Cải tiến đầu vào

Sử dụng phương thức Regex.Replace để cải tiến dữ liệu vào khi cần thiết. Đoạn mã dưới đây loại bỏ các ký tự không an toàn, bao gồm: < > \ “ ‘ % ; () &

private string SanitizeInput(string input) {

Regex badCharReplace = new Regex(@"^([<>""'%;()&])$"); string goodChars = badCharReplace.Replace(input, ""); return goodChars;

}

b. Cross-Site Scripting (adsbygoogle = window.adsbygoogle || []).push({});

Các tấn công XSS khám phá các lỗ hổng trong kiểm tra trang Web bằng cách nhúng đoạn mã từ phía client. Đoạn mã này sau đó được gửi trở về một người dùng mà không nghi ngờ gì và được thực thi bởi trình duyệt. Vì trình duyệt tải về đoạn mã từ một site tin cậy, trình duyệt không có cách nào xác định rằng đoạn mã không hợp lệ và các vùng an toàn của Internet Explorer không cung cấp rào cản. Các tấn công XSS cũng làm việc dựa trên các kết nối HTTP hoặc HTTPS(SSL). Một trong những khám phá quan trọng nhất xảy ra khi một kẻ tấn viết đoạn mã để lấy về cookie xác thực cung cấp thông tin truy cập tới site đáng tin và gửi nó tới một địa chỉ Web mà kẻ tấn công biết. Điều này cho phép kẻ tấn công giả dạng đặc tính nhận diện của người dùng hợp pháp và đạt được truy cập tới web site.

Sử dụng các phương án phòng chống sau để tránh các tấn công XSS. Kiểm tra giá trị đầu vào:

Kiểm tra bất kỳ đầu vào nào nhận được từ ngoài rào cản tin cậy của ứng dụng bao gồm: kiểu, độ dài, định dạng và phạm vi

Nếu viết đầu ra dạng văn bản cho một trang Web và ta không hoàn toàn chắc chắn rằng văn bản không chứa các ký tự đặc biệt HTML như: <, >, và &, thì phải đảm bảo sử lý trước nó bằng cách sử dụng phương thức HttpUtility.HtmlEncode. Sử dụng HttpUtility.UrlEncode để mã hoá các xâu URL. Phương thức HtmlEncode thay thế các ký tự có ý nghĩa đặc biệt trong HTML thành các biến HTML đại diện cho các ký tự này. Ví dụ: < thay thế với &lt và “ thay thế với &qout. Trình duyệt sẽ không thực thi dữ liệu được mã hoá. Thay vào đó dữ liệu được trả lại là mã HTML vô hại

Response.Write(HttpUtility.HtmlEncode(Request.Form["name"]));

 Phương án rào cản sâu

Để tránh tấn công kiểu XSS

 Đặt chế độ character encoding

 Sử dụng tuỳ chọn validateRequest ASP.NET version 1.1

 Cài đặt URLScan trên Web server

 Sử dụng tuỳ chọn cookie HttpOnly

 Sử dụng thuộc tính an toàn <frame>  Sử dụng thuộc tính innerText

Đặt chế độ Character Encoding:

ASP.NET cho phép ta chỉ ra bộ ký tự ở mức trang hoặc ở mức ứng dụng bằng cách sử dụng thành phần <globalization> trong Web.config. Để thiết đặt chế độ mã hoá ký tự ở mức trang, sử dụng thành phần <meta> hoặc thuộc tính mức trang ResponseEncoding

như sau:

<meta http-equiv="Content Type"

content="text/html; charset=ISO-8859-1" />

hoặc

<% @ Page ResponseEncoding="ISO-8859-1" %>

Để thiết đặt chế độ mã hoá ký tự trong Web.config, sử dụng cấu hình sau:

<globalization

requestEncoding="ISO-8859-1" responseEncoding="ISO-8859-1"/> </system.web>

</configuration>

Sử dụng đoạn mã sau để kiểm tra các ký tự Unicode trong một trang:

using System.Text.RegularExpressions; . . .

private void Page_Load(object sender, System.EventArgs e) {

// Tên phải chứa các ký tự alphanumeric từ 1 đến 40

if(!Regex.IsMatch(Request.Form["name"],@"^[\p{L}\p{Zs}\p{Lu}\p{Ll}] {1,40}$"))

throw new ArgumentException("Invalid name parameter"); // Sử dụng các biểu thực riêng để kiểm tra các tham số khác }

Giải thích: (adsbygoogle = window.adsbygoogle || []).push({});

+ {<name>} Chỉ ra một lớp ký tự Unicode được đặt tên

+ \p{<name>} Kiểm tra sự phù hợp các ký tự bất ký trong lớp ký tự được đặt tên được chỉ ra bởi {<name>}

+ {L} Thực hiện kiểm tra sự phù hợp từ trái sang phải + {Lu} Thực hiện kiểm tra phù hợp với chữ viết hoa + {Ll} Thực hiện kiểm tra phù hợp với chữ thường + {Zs} Ghép separator và space.

+ {1,40} Không nhỏ hơn 1 và không lớn hơn 40

Thuộc tính validatRequest là một đặc điểm trong .NET Framework version 1.1. Thuộc tính này mặc định được thiết lập thành true trong thành phần <pages> trong Machine.config. Nó chỉ dẫn cho ASP.NET để kiểm tra tất cả dữ liệu nhận được từ trình duyệt đối với đầu vào nguy hiểm, ví dụ: giá trị vào chứa thành phần <script>. Có thể áp dụng cho mỗi trang bằng cách sử dụng thẻ @page như sau:

<% @ Page validateRequest="True" %>

Sử dụng tuỳ chọn cookie HttpOnly:

Internet Explorer 6 Service Pack 1 hỗ trợ thuộc tính HttpOnly, tránh client-side script từ việc truy cập tới cookie từ thuộc tính document.cookie. Thay vào đó một xâu rỗng được trả về. Cookie vẫn được gửi về server bất cứ khi nào người dùng duyệt một Web site trong miền hiện tại. Lớp System.Net.Cookie không hỗ trợ thuộc tính HttpOnly. Để thêm thuộc tính HttpOnly cho cookie, ta cần sử dụng một bộ lọc ISAPI, hoặc là nếu muốn sử dụng một giải pháp mã được bảo mật thì thêm đoạn mã vào Application_EndRequest của ứng dụng trong Global.asax., ,

protected void Application_EndRequest(Object sender, EventArgs e) {

string authCookie = FormsAuthentication.FormsCookieName; foreach (string sCookie in Response.Cookies)

{

// Chỉ thiết lập thuộc tính HttpOnly trong cookie Forms authentication if (sCookie.Equals(authCookie))

{

// Force HttpOnly to be added to the cookie header Response.Cookies[sCookie].Path += ";HttpOnly"; }

} }

c. Xác thực

Xác thực yếu nảy sinh nguy cơ giả dạng đặc tính nhận dạng. Nếu các thông tin đăng nhập của người dùng rơi vào tay kẻ xấu, kẻ tấn công có thể giả dạng đặc tính nhận dạng của người dùng và đạt được truy cập tới ứng dụng. Kẻ tấn công chia sẻ tất cả các đặc quyền của người dùng trong ứng dụng. Các thông tin đăng nhập phải được bảo vệ khi chúng được truyền qua mạng. Cookie xác thực đại diện cho đặc tính nhận dạng đã được xác thực cho ứng dụng sau khi đăng nhập cũng phải được bảo vệ để giảm rắc rối của kiểu tấn công session và tấn công cookie replay.

Forms Authentication

Nguy cơ tấn công session hijacking và cookie replay là đáng kể với các ứng dụng sử dụng Forms authentication. Ta phải đặc biệt quan tâm khi truy vấn cơ sở dữ liệu bằng cách sử dụng các thông tin đăng nhập của người dùng để tránh tấn công SQL injection. Ngoài ra để tránh identity spoofing, ta phải đảm bảo rằng user store là an toàn và ép buộc strong password.

một cấu hình "secure" Forms authentication trong Web.config:

<forms loginUrl="Restricted\login.aspx" Login page in an SSL protected folder protection="All" Privacy and integrity

requireSSL="true" Prevents cookie being sent over http timeout="10" Limited session lifetime

name="AppNameCookie" Unique per-application name path="/FormsAuth" and path

slidingExpiration="true" > Sliding session lifetime </forms>

Khi sử dụng Forms authentication cần chú ý:

 Khoanh vùng Web site

 Bảo mật các trang được chế truy cập với SSL

 Sử dụng URL Authorization

 Sử dụng URL để điều hướng

 Quản lý các thông tin đăng nhập (adsbygoogle = window.adsbygoogle || []).push({});

Khoanh vùng web site:

Trong thiết kế site đảm bảo các trang an toàn và các trang truy cập yêu cầu xác thực phải được đặt trong một thư mục con tách biệt với các trang có thể được truy cập ẩn danh.

Bảo mật các trang được hạn chế truy cập với SSL:

Thiết lập thuộc tính AccessSSL = true cho thư mục trong IIS Sử dụng URL Authorization:

Sử dụng thành phần <authorization> để cho phép các truy cập ẩn danh tới các trang công cộng. <system.web> <authorization> <allow users="*" /> </authorization> </system.web>

Sử dụng thành phần <authorization> trong thành phần <location> trong

Web.config để từ chối truy cập người dùng không được xác thực và ép buộc một điều hướng tới trang đăng nhập được chỉ ra trong thành phần <forms>.

<location path="Secure" > <system.web> <authorization> <deny users="?" /> </authorization> </system.web> </location> Bảo mật cookie xác thực:

Để tránh các tấn công session hijacking và cookie replay, cookie phải được truyền qua các kết nối SSL bằng cách sử dụng giao thức HTTPS. Để giảm rắc rối ta nên mã hoá cookie trước khi gửi nó tới client và giới hạn thời gian cho cookie đúng giá trị. Để cho cookie authentication được an toàn, ta cần thực hiện:

 Hạn chế authentication cookie với các kết nối HTTPS

 Mã hoá cookie

 Giới hạn thời gian sống của cookie

 Sử dung khoảng thời gian hết hạn cố định  Không lưu authentication cookies.

 Giữ authentication và personalization cookíe riêng biệt  Sử dụng tên và đường dẫn cookie phân biệt

Hạn chế authentication cookie với các kết nối HTTPS:

Các cookie hỗ trợ thuộc tính “secure” để xác định các trình duyệt có gửi cookie về server hay không. Khi thuộc tính này được thiết lập, cookie được gửi bởi trình duyệt tới trang an toàn được yêu cầu với HTTPS URL

Nếu sử dụng .NET Framework version 1.1, thiết lập thuộc tính secure bằng cách sử dụng requireSSL =”true” trong thành phần <forms> :

<forms loginUrl="Secure\Login.aspx" requireSSL="true" . . . />

Mã hoá cookie:

Mã hoá nội dung cookie kể cả khi sử dụng SSL. Điều này tránh một kẻ tấn công xem hay chỉnh sửa cookie nếu hắn cố gắng lấy nó qua một tấn công XSS. Trong sự kiện này kẻ tấn công vẫn có thể sử dụng cookie để đạt được truy cập tới ứng dụng. Cách tốt nhất để giảm rắc rối là thực thi phương án phòng chống tương ứng để tránh các tấn công

Một phần của tài liệu Xây dựng ứng dụng web ASP.NET an toàn (Trang 42 - 59)