3.1.4. Đánh giá bảo mật
Trong suốt vòng đời phát triển bảo mật, chúng ta cần luôn ghi nhớ rằng kẻ tấn công sẽ cố gắng khai thác những lỗ hổng trong chương trình của chúng ta. Do đó, sau khi viết code chúng ta cần đánh giá lại code đối với các rủi ro bảo mật. Để thực hiện đánh giá code thì chúng ta cần một nhóm các thành viên có kiến thức về lỗ hổng bảo mật và yêu cầu bảo mật để có thể tìm ra lỗ hổng cần khắc phục. Microsoft đã đề xuất thực hiện đánh giá code theo 4 bước như sau [2]:
3.1.4.1. Bước 1: Xác định các mục tiêu đánh giá bảo mật code
Bước đầu tiên là đặt mục tiêu và các ràng buộc cho đánh giá. Khi chúng ta đặt mục tiêu cho đánh giá bảo mật, chúng ta cần biết các vấn đề bảo mật phổ biến đối với bất kỳ ứng dụng nào cũng như mọi thay đổi code cụ thể cần được xem xét. Các nội dung cần đánh giá bao gồm:
Xác thực các dữ liệu đầu vào
Xác thực, ủy quyền, nhật ký, tài khoản
Các dữ liệu nhạy cảm
Các thông số cấu hình
Các đoạn mã không an toàn, quản lý các ngoại lệ
Mức truy cập dữ liệu
Tiêm mã, cross-site scripting
Quản lý đặc quyền và đặc quyền nâng cao
3.1.4.2. Bước 2: Rà soát sơ bộ
Việc thực hiện rà soát sơ bộ cần được thực hiện theo 2 cách thức là tự động và thông thường. Đối với việc đánh giá code nên đặt các câu hỏi hoặc các tình huống như sau:
Xác định vùng tin tưởng: tất cả các đối tượng trong đó có thể tin cậy được.
Xác định dữ liệu đầu vào: cần xác nhận từng dữ liệu đầu vào hợp lệ cho chương trình và loại bỏ các dữ liệu không hợp lệ.
Code xác thực người dùng: Chương trình có xác thực người dùng không? Kỹ thuật xác thực nào đã sử dụng? Mã xác thực có được chỉnh sửa không?
Code ủy quyền người dùng: Người dùng được tin cậy nhưng có được phép thực hiện các nhiệm vụ đặc quyền không? Vai trò nào được cho phép và làm thế nào để chúng tương tác?
Mã hóa: Ứng dụng có sử dụng mã hóa không? Loại thuật toán nào hệ thống sử dụng, đối xứng hoặc không đối xứng? Kích thước khóa nào đang sử dụng.
Các đoạn mã xử lý ngoại lệ: Chương trình có một kiến trúc xử lý lỗi nhất quán? Chương trình có bắt và đưa ra ngoại lệ có cấu trúc.
Độ đặc quyền sử dụng các chức năng: Có phần nào của chương trình cần được thực thi đặc trong quyền nâng cao không? Nếu có, nó được xử lý như thế nào?
Thư viện bên ngoài: Chương trình có sử dụng thư viện bên ngoài không? Nếu có, nó đáng tin đến mức nào?
3.1.4.3. Bước 3: Đánh giá các vấn đề bảo mật code
Đây là bước quan trọng nhất của tất cả, bước này sử dụng kết quả của bước 2 để phân tích. Đối với việc đánh giá các vấn đề bảo mật code, cần thực hiện:
Đánh giá các vùng tin cậy: Đánh giá mức độ tin cậy của nguồn đầu vào đến từ các nguồn nội bộ hoặc từ code được viết trong tổ chức, không nên tin tưởng bất kỳ đầu vào nào đến từ bên ngoài các thành phần của ứng dụng.
Phân tích luồng thực hiện chức năng: Thực hiện phân tích luồng điều khiển các bước thông qua các điều kiện logic bên trong code.
Phân tích luồng lưu trữ dữ liệu: Thực hiện phân tích luồng dữ liệu để theo dõi vòng đời của dữ liệu từ các điểm đầu vào đến các điểm đầu ra.
Đầu vào/đầu ra: Trong quá trình phân tích luồng dữ liệu, cần thực hiện đánh giá danh sách đầu vào và đầu ra.
Đặc điểm của các ngôn ngữ lập trình: Vẫn có thể có rủi ro bảo mật từ các phân đoạn code và thư viện khác nhau. Các thư viện hoặc code đã được chứng nhận là đáng tin cậy nhưng cũng trở nên không đáng tin cậy do những thay đổi từ môi trường bên ngoài.
3.1.4.4. Bước 4: Đánh giá các vấn đề bảo mật duy nhất trong kiến trúc
Sau khi đã hoàn thành bước 1, 2 và 3, cần thực hiện bước cuối cùng là tìm kiếm các vấn đề bảo mật liên quan đến kiến trúc duy nhất của ứng dụng. Đây là bước cuối cùng xác minh các tính năng bảo mật duy nhất cho kiến trúc ứng dụng.
3.1.5. Kiểm thử bảo mật
Kiểm thử phần mềm là một chức năng quan trọng trong vòng đời phát triển phần mềm. Tất cả các phần mềm cần phải được kiểm tra trước khi đưa vào sử dụng. Nội dung kiểm thử bảo mật bao gồm [2]:
3.1.5.1. Đánh giá lỗ hổng (Vulnerability Assessment)
Quá trình đánh giá lỗ hổng là tiến hành các phân tích và kiểm thử khác nhau trên một hệ thống cụ thể để đánh giá sự hiện diện của lỗ hổng bảo mật. Đánh giá lỗ hổng được chia thành 2 loại: đánh giá lỗ hổng bên ngoài và bên trong.
a) Đánh giá lỗ hổng bên ngoài
Nhóm đánh giá này xác định sự hiện diện của lỗ hổng bảo mật trong hệ thống khi sử dụng từ môi trường bên ngoài như một số mạng bên ngoài hoặc môi trường không
tin cậy, đặc biệt là môi trường Internet. Các lỗ hổng có thể liên quan đến các bộ định tuyến, máy chủ, modem và tường lửa hoặc trong các hệ điều hành và các ứng dụng máy chủ.
b) Đánh giá lỗ hổng bên trong
Nhóm đánh giá này thực hiện từ bên trong mạng tổ chức, mạng LAN, mạng tin cậy. Đánh giá lỗ hổng nội bộ sẽ cung cấp cho tổ chức những dữ liệu đưa ra cho các nhân viên trong tổ chức. Các lỗ hổng bên trong bao gồm các lỗ hổng liên quan đến ứng dụng, cơ sở dữ liệu và hệ điều hành của các thành phần mạng, các ứng dụng máy chủ trung gian của riêng tổ chức.
c) Công cụ đánh giá lỗ hổng
Có khá nhiều công cụ có thể được sử dụng để phân tích các hệ thống và xác định lỗ hổng. Có khá nhiều công cụ miễn phí và mở, các công cụ này có thể download tại trang web Insecure.org và Sectools.org. Một số công cụ phổ biến là Nessus, Snort và Tcpdump.
3.1.5.2. Công cụ phủ sóng mã
Đây là một loại công cụ xác nhận mã (code) lúc chạy và cho biết liệu người viết code đã đảm bảo độ bao phủ của code chưa. Bạn cần phải xác định điểm quan trọng của code để thực hiện kiểm tra.
Công cụ này sau đó sẽ chạy mã, phân tích các kết quả và cho biết liệu bạn đã kiểm tra hết các code chưa. Nếu một phần bảo mật quan trọng của code không được kiểm tra, bạn cần thực hiện kiểm tra lại.
3.1.5.3. Kiểm thử tính hợp lệ hoặc không hoạt động
Kiểm thử tính hợp lệ là kiểm tra xem hệ thống có đang làm một cái gì đó mà nó không phải làm hay không.
Kiểm thử không hoạt động là một phương pháp kiểm thử sử dụng các hồ sơ kiểm thử không tương ứng với các hồ sơ hoạt động dự kiến.
3.1.5.4. Kiểm thử thâm nhập
Kiểm thử xâm nhập giúp chúng ta hiểu được bảo mật bên ngoài của một hệ thống. Nó giúp đánh giá các lỗ hổng an ninh, các vấn đề về xác thực và việc phân quyền. Một số công cụ miễn phí như Nessus, Nmap và Tcpdump có thể giúp bạn trong quá trình kiểm tra này.
3.1.5.5. Hacker mũ trắng
Hacker mũ trắng gần giống như kiểm thử thâm nhập, tuy nhiên trong thực tế có một số khác biệt giữa hai khái niệm này:
Hacker mũ trắng hay còn gọi là hacker tốt, người được kiểm thử hệ thống nhưng không hack hệ thống cho mục đích xấu.
Trong kiểm thử thâm nhập, người kiểm thử có thể sử dụng một số công cụ kiểm tra thâm nhập và kiểm tra các lỗ hổng bảo mật. Hacker mũ trắng đòi hỏi một mức độ kỹ năng cao hơn so với kiểm thử thâm nhập.
Hacker mũ trắng sẽ kiểm tra cả sự an toàn và các vấn đề bảo mật của một chương trình, trong khi kiểm thử thâm nhập chủ yếu sẽ giải quyết vấn đề bảo mật.
3.1.5.6. Kiểm thử mờ (Fuzz Testing)
Kiểm thử mờ (Fuzz Testing) là một kỹ thuật kiểm thử phần mềm đối với việc cung cấp dữ liệu ngẫu nhiên cho đầu vào của một chương trình máy tính. Sau đó, chương trình sẽ được giám sát các trường hợp ngoại lệ như treo máy, lỗi code không được thực thi, tài nguyên bộ nhớ thất thoát nhằm để xác định các hành vi bất thường, phát hiện các lỗ hổng bảo mật tiềm ẩn của chương trình. Kiểm thử mờ thường được sử dụng để kiểm tra bảo mật chính cho việc phát hiện các lỗ hổng bảo mật nghiêm trọng ở các phần mềm lớn hoặc hệ thống máy tính.
3.1.5.7. Chèn lỗi (Fault Injection)
Chèn lỗi [2] là phương pháp lỗi được chèn tương tự như một lỗi trong môi trường ứng dụng để xem cách hệ thống phản ứng và liệu sẽ có một sự vi phạm bảo mật nào. Nếu không, hệ thống được coi là an toàn.
Có nhiều công cụ chèn lỗi mà có thể được sử dụng liên quan đến bảo mật như CECIUM, DOCTOR, ORCHESTRA, NTHAPE, và LOKI.
3.2. Bảo mật trong .NET
3.2.1. .NET Framework
3.2.1.1. Tổng quan về .NET Framework
.NET Framework là một nền tảng phát triển để xây dựng các ứng dụng cho web, Windows, Windows Phone, Windows Server và Microsoft Azure [6]. Nó bao gồm Common Language Runtime (CLR) và thư viện lớp .NET Framework, thư viện này bao gồm một loạt các chức năng và hỗ trợ cho nhiều tiêu chuẩn.
.NET Framework cung cấp nhiều dịch vụ, bao gồm quản lý bộ nhớ, kiểu và bộ nhớ an toàn, bảo mật, kết nối mạng và triển khai ứng dụng. Nó cung cấp các cấu trúc dữ liệu và API dễ sử dụng để trừu tượng hóa hệ điều hành Windows cấp thấp hơn. Bạn có thể sử dụng các ngôn ngữ lập trình khác nhau với .NET Framework, bao gồm C#, F# và Visual Basic.
3.2.1.2. Common Language Runtime (CLR)
CLR cung cấp nền tảng cho các nhà phát triển ứng dụng để xây dựng một ứng dụng tích hợp bao gồm các thành phần khác nhau đã được xây dựng bằng các nền tảng phát triển khác nhau. Nó cung cấp một hệ thống loại chung và ngôn ngữ trung gian (Intermediate Language - IL) để thực hiện các chương trình được viết bằng nhiều ngôn ngữ khác nhau và để tạo điều kiện cho khả năng tương tác giữa các ngôn ngữ đó. Nó mô tả việc sắp xếp dữ liệu thông qua định nghĩa giao diện ngôn ngữ (Interface Definition Language - IDL) cần thiết cho khả năng tương tác ngôn ngữ [2].
CLR được thực hiện thông qua một cơ chế gọi là cơ sở hạ tầng ngôn ngữ chung (Common Language Infrastructure - CLI). CLI cung cấp các lợi ích sau cho các nhà phát triển ứng dụng [5]:
Cải tiến hiệu suất.
Khả năng dễ dàng sử dụng các thành phần được phát triển trong các ngôn ngữ khác.
Các kiểu mở rộng được cung cấp bởi một thư viện lớp.
Các tính năng của ngôn ngữ như kế thừa, interface và overload cho lập trình hướng đối tượng.
Hỗ trợ phân luồng rõ ràng cho phép tạo các ứng dụng đa luồng, có thể mở rộng.
Hỗ trợ xử lý ngoại lệ có cấu trúc.
Hỗ trợ cho các thuộc tính tùy chỉnh.
Thu gom rác.
Sử dụng các đại diện thay cho các con trỏ hàm để tăng độ an toàn và bảo mật.
CLR giúp dễ dàng thiết kế các thành phần và ứng dụng có đối tượng tương tác qua các ngôn ngữ. Các đối tượng được viết bằng các ngôn ngữ khác nhau có thể giao tiếp với nhau một cách dễ dàng và hành vi của chúng có thể được tích hợp chặt chẽ. Ví dụ: bạn có thể định nghĩa một lớp trong C# và sau đó sử dụng ngôn ngữ Visual Basic để lấy một lớp từ lớp C# ban đầu của bạn hoặc gọi một phương thức trên lớp gốc. Bạn cũng có thể truyền một thể hiện của một lớp cho một phương thức của một lớp khác được viết bằng một ngôn ngữ khác.
CLR cung cấp hạ tầng cho phép thực hiện quản lý thực thi, nó cũng cung cấp các dịch vụ khác nhau được sử dụng trong quá trình thực thi. Trước khi một phương thức hoặc một chức năng có thể chạy được, mã nguồn phải được biên dịch để tạo mã thực thi dành riêng cho bộ xử lý. Môi trường phát triển dịch mã nguồn thành mã quản lý (managed code) dưới dạng ngôn ngữ trung gian MSIL (Microsoft Intermediate Language) hay IL (Intermediate Language). Khi thực thi mã ứng dụng, tuỳ thuộc vào
chỉ thị người dùng trình biên dịch tức thời JIT (Just In Time) của CLR cung cấp sẽ chuyển đổi mã quản lý (managed code) thành mã máy (native code) và JIT cất giữ mã máy phát sinh vào bộ nhớ đệm cho các thao tác tương tự.
3.2.2. .NET Runtime security
Runtime loader thực hiện tải cả Managed code và Unmanaged code và hướng dẫn bộ xử lý thực thi chúng [2]. Managed code thực thi dưới sự kiểm soát của runtime và do đó có quyền truy cập tới các dịch vụ được cung cấp bởi môi trường runtime như quản lý bộ nhớ, biên dịch JIT và quan trọng nhất là các dịch vụ bảo mật như hệ thống chính sách bảo mật và xác minh. Unmanaged code là code đã được biên dịch để chạy trên nền tảng phần cứng cụ thể và không thể sử dụng trực tiếp môi trường thực thi runtime. Khi trình biên dịch ngôn ngữ tạo ra managed code được biểu diễn dưới dạng MSIL, nó sẽ được JIT biên dịch thành mã gốc trước khi thực thi.
Có 2 hình thức xác minh trong quá trình runtime là MSIL verified và Assembly metadata validated.
MSIL verified
Managed code được xác minh trong quá trình runtime. Unmanaged code không thể xác minh trong quá trình runtime vì vậy nó phải được an toàn. MSIL được phân thành 4 loại như sau:
MSIL không hợp lệ (Invalid MSIL) là MSIL mà trình biên dịch JIT không thể tạo ra biểu diễn gốc.
MSIL hợp lệ (Valid MSIL) là tất cả các MSIL thỏa mãn ngữ pháp MSIL.
MSIL kiểu an toàn (Type-safe MSIL) loại chỉ tương tác với các loại khác thông qua các contract được công khai.
MSIL có thể kiểm chứng (Verifiable MSIL) là một loại MSIL an toàn có thể được chứng minh là loại an toàn bằng thuật toán xác minh.
Assembly metadata verified
Assembly metadata được verified khi một assembly được nạp vào trong Global Assembly Cache (GAC), hoặc tải xuống bộ đệm, hoặc khi nó được đọc từ ổ đĩa nếu nó không nạp vào GAC. GAC là trung tâm lưu trữ cho các assemplies. Bộ đệm tải xuống lưu giữ các assemplies được tải xuống từ các vị trí khác, ví dụ từ Internet. Metadata loại bỏ lỗi tràn bộ đệm khi không thể kiểm tra metadata token.
3.2.3. Kiến trúc bảo mật .NET
.NET Framework kết hợp với CLR và runtime cung cấp nhiều lớp và dịch vụ hữu ích cho phép các nhà phát triển dễ dàng viết code bảo mật và an toàn [2]. Các lớp và dịch vụ này cũng cho phép quản trị viên hệ thống để tùy chỉnh quyền truy cập mà code có thể truy cập tài nguyên được bảo vệ. Ngoài ra, runtime và .NET Framework cung
cấp các lớp và dịch vụ hữu ích tạo điều kiện thuận lợi cho việc sử dụng mật mã và bảo mật dựa trên vai trò.
.NET Framework cung cấp bảo mật truy cập code và bảo mật dựa trên vai trò để giải quyết các mối lo ngại về bảo mật về code di động và để cung cấp hỗ trợ cho phép các thành phần để xác định những gì người dùng có quyền thực hiện. Cả bảo mật truy cập code và bảo mật dựa trên vai trò đều được triển khai bằng cách sử một cơ sở hạ tầng chung được cung cấp bởi CLR.
3.2.3.1. Bảo mật ứng dụng Web .NET
Bảo mật ứng dụng Web .NET bao gồm bảo mật tầng web server, application server và database server. Hình 3.3 mô tả kiến trúc bảo mật ứng dụng web .NET [2]
Hình 3.3: Bảo mật ứng dụng web .NET. 3.2.3.1. Bảo mật trong web server IIS (Internet Information Services) 3.2.3.1. Bảo mật trong web server IIS (Internet Information Services)
IIS là một máy chủ web Windows có sẵn trên hầu hết các các phiên bản hệ điều hành Microsoft Windows và nó chiếm vị trí thứ hai về mức độ sử dụng chung sau