Bài giảng Lập trình an toàn - Chương 1: Kiểm tra đầu vào trình bày các nội dung: Các nguyên tắc kiểm tra, các hàm định dạng xâu, tràn bộ đệm, tràn số học, kiểm tra tên file và đường dẫn, giải mã URL, Cross - Site Scripting, SQL Injection. Hi vọng đây là một tài liệu hữu ích dành cho các bạn sinh viên Công nghệ thông tin dùng làm tài liệu học tập và nghiên cứu.
LẬP TRÌNH AN TỒN Secure Programming Lương Ánh Hồng hoangla@soict.hut.edu.vn Mục đích • Cung cấp các kiến thức, kỹ thuật cơ bản để xây dựng các ứng dụng an toàn Yêu cầu • Yêu cầu về kiến thức: – An ninh mạng – Ngơn ngữ lập trình C/C++ • Lên lớp đầy đủ Thời lượng mơn học • Thời lượng: 45 tiết – Lý thuyết: 30 tiết – Bài tập:15 tiết Tài liệu • Secure Program Cookbook for C and C++, Matt Messier, John Viega, O'Reilly 2003 Nội dung • • • • • • • • Chương 1 Kiểm tra đầu vào Chương 2 Kiểm soát truy nhập Chương 3 Kiểm soát xung đột Chương 4 Mã hóa đối xứng Chương 5 Hàm băm và xác thực thông điệp Chương 6 Mã hóa cơng khai Chương 7 Anti-‐Tampering Chương 8 Các vấn đề khác Đánh giá • Bài tập lớn: 70% • Q trình: 30% Chương 1 Kiểm tra đầu vào Input Validation Lương Ánh Hoàng hoangla@soict.hut.edu.vn Nội dung 1.1 Nguyên tắc kiểm tra 1.2 Các hàm định dạng xâu (string formatting) 1.3 Tràn bộ đệm 1.4 Tràn số học 1.5 Kiểm tra tên }ile và đường dẫn 1.6 Giải mã URL 1.7 Cross-‐Site Scripting 1.8 SQL Injection 10 1.3 Tràn bộ đệm • Tràn bộ đệm (Buffer Over}low): copy dữ liệu vượt quá biên của một bộ đệm nào đó => đè lên vùng nhớ của biến (cấu trúc) khác • Phần lớn các hàm xử lý xâu trong C đều không thực hiện kiểm tra biên bộ đệm: gets, strcpy, … • VD1: Dữ liệu bị hỏng int x = 0; char buff[8]; strcpy(buff,”Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAAA”); printf(“%d”,x); • VD2: Stack bị hỏng char name[8]; gets(name); printf(name); 14 1.3 Tràn bộ đệm • VD3: Khơng trở về được từ chương trình con void Hello() { char name[8]; printf(“What is your name ?”); gets(name); printf(“Hello %s !”, name); } void main() { Hello(); printf(“Bye”); } 15 1.3 Tràn bộ đệm • VD4: Tấn cơng có chủ ý trên bộ đệm void Bye() { printf(“Bye”); } void Hello() { void (*p)() = Bye; char name[8]; printf(“What is your name ?”); gets(name); printf(“Hello %s !”, name); p(); } void main() { Hello(); } 16 1.3 Tràn bộ đệm • Giải pháp: – Sử dụng các hàm strncpy, memcpy…và những hàm có kiểm sốt kích thước đệm một cách tường minh – Sử dụng Stack Guard trong các trình biên dịch hỗ trợ – Sử dụng DEP (Data Execution Preventation) trên hệ điều hành hỗ trợ – Sử dụng ASLR (Address Space Layout Randomization) trên trình biên dịch và hệ điều hành hỗ trợ 17 1.4 Tràn số học • Dữ liệu nhận về có thể có sai sót trong trường liên quan đến kích thước • Các thao tác liên quan đến số nguyên lớn có thể bị tràn, lẫn lộn giữa số ngun khơng dấu và có dấu • VD1: Tràn số unsigned int x = 0xFFFFFFFF; // MAX_INT if ( x+5 > 5 ) printf (“X > 0” ) else printf(“X < 0”); • VD2: Dùng sai kiểu có/khơng dấu if (x < MAX_SIZE) { // x, số byte cần cấp phát tùy theo giải thuật tính được if (!(ptr = (unsigned char *)malloc(x))) abort( ); } else { /* Handle the error condition */ } 18 1.5 Kiểm tra tên qile và đường dẫn • Dữ liệu nhận về có thể là tên }ile, ứng dụng cần xác định đường dẫn tuyệt đối nếu cần thiết • Dùng hàm realpath() trên Unix/Linux và GetFullPathName trên Windows • Sử dụng realpath() § Nguyên mẫu: char *realpath(const char *pathname, char resolved_path[MAXPATHLEN]); § Thận trọng: Có thể tràn resolved_path và khơng thread-‐safe § Thư viện: stdlih.h § VD char resolved[1024]; char * result = realpath("printf.c",resolved); printf("%s",result); 19 1.5 Kiểm tra tên qile và đường dn ã S dng GetFullPathName() Đ Th vin: windows.h § Nguyên mẫu: DWORD GetFullPathName(LPCTSTR lpFileName, DWORD nBufferLength, LPTSTR lpBuffer, LPTSTR *lpFilePath); § VD: int nBufferLen = 0; LPTSTR lpBuffer; nBufferLen = GetFullPathName(L"test.c",0,0,0); if (nBufferLen>0) { lpBuffer = new TCHAR[nBufferLen+1]; GetFullPathName(L"test.c",nBufferLen,lpBuffer,0); wprintf(L"%s",lpBuffer); } 20 1.6 Giải mã URL • RFC 1738 quy định cách mã hóa các ký tự khơng nhìn thấy được trong URL dưới dạng “%” • VD: http://m%61il.google.com http://m%25%36%31il.google.com • Cách giải mã: duyệt từ đầu đến cuối , tìm các ký tự % và thay thế bằng mã ASCII tương ứng • Không sử dụng các hàm xử lý xâu chuẩn vì có thể có ký tự NULL trong URL 21 1.7 Cross-‐Site Scripting • Cross-‐Site Scripting (XSS) là hình thức tấn cơng vào trình duyệt người dùng bắt nguồn từ việc kiểm tra lỏng lẻo từ server • Có thể dẫn đến thất thốt thơng tin nhạy cảm: mật khẩu, session, cookie… • Thực hiện bằng cách chèn mã HTML/JAVASCRIPT vào dữ liệu sẽ hiển thị ra trình duyệt => đoạn mã sẽ chạy trên trình duyệt của nạn nhân • VD Một ứng dụng web có hai trang – Hello.php: Hiển thị form và nhận tên của người dùng – Chao.php: hiển thị tên nhận được lại cho người dùng 22 1.7 Cross-‐Site Scripting • File Hello.php Xin chào, vui lòng nhập tên bạn