Chuyển đến nội dung chính

[Secure coding - Part 1] Là developer cần làm gì để ứng dụng của mình an toàn và bảo mật hơn?

Phần lớn các vấn đề bảo mật đều liên quan đến các lỗi lập trình! Mặc dù không một lập trình viên nào khi viết ứng dụng lại mong muốn ứng dụng của mình sẽ có lỗi bảo mật, nhưng trên thực tế, do tính phức tạp của các hệ thống kỹ thuật, do tập trung quan tâm đến chức năng hấp dẫn của ứng dụng, đến tiến độ… việc đảm bảo ứng dụng không có lỗi bảo mật là cực kỳ khó khăn, ngay cả với những lập trình viên cao cấp. Nói chung, việc xây dựng phần mềm an toàn sẽ ít tốn kém hơn nhiều so với việc sửa chữa các vấn đề bảo mật sau khi phần mềm đã hoàn thành, chưa kể các chi phí có thể liên quan đến vi phạm bảo mật.
Chuỗi bài viết này được tham khảo từ: 
I. Input Validation
Yêu cầu này liên quan đến việc kiểm tra dữ liệu đầu vào, các lập trình viên cần đảm bảo kiểm tra toàn bộ dữ liệu đầu vào từ phía người dùng và xử lý hay kiểm tra chúng ở phía server (không xử lý ở phía client).
1. Tất cả dữ liệu đầu vào cần được xử lý ở một hệ thống an toàn, đáng tin cậy.
  • Hệ thống đáng tin cậy có thể là server do chúng ta quản lý, server của các bên thứ 3 đủ độ tin cậy và an toàn.
2. Xác định rõ ràng nguồn dữ liệu nào là tin cậy và không đáng tin cậy. Đối với các nguồn dữ liệu không tin cậy, cần thực hiện kiểm tra trên server trước khi thực hiện các tác vụ khác.
  • Các nguồn dữ liệu tin cậy: Dữ liệu đã được xử lý, dữ liệu từ các nguồn tin tưởng đã biết trước đó (google, facebook..)
  • Các nguồn dữ liệu không tin cậy: User input, databases, file streams, ...
3. Nên thực hiện kiểm tra dữ liệu tập trung cho ứng dụng
  • Việc thực hiện kiểm tra dữ liệu tập trung giúp giảm thiểu tài nguyên cũng như giúp kiểm soát dễ dàng các vấn đề về bảo mật có thể xảy ra. Ví dụ: Tất cả dữ liệu người dùng nhập vào từ form sẽ được xử lý tập trung để làm sạch dữ liệu qua một hàm hoặc thư viện nào đó để đảm bảo tất cả dữ liệu sẽ được xử lý trước khi đến bước tiếp theo.
4. Chỉ định các bộ ký tự chuẩn cho dữ liệu đầu vào (UTF-8) và thực hiện encode dữ liệu về một bộ encode chuẩn trước khi thực hiện việc kiểm tra.
  • Việc này đảm bảo dữ liệu được chuẩn hóa trước khi xử lý và giúp loại bỏ các ký tự nguy hiểm khỏi dữ liệu đầu vào.
5. Xác thực dữ liệu thất bại nên được xử lý để từ chối luôn đầu vào đó
  • Nếu người dùng nhập đầu vào không hợp lệ thì cần loại bỏ luôn chứ không thực hiện xử lý hay lưu trữ tiếp và có thông báo về việc nhập dữ liệu không hợp lệ để người dùng biết
6. Xác thực tất cả dữ liệu do khách hàng cung cấp trước khi xử lý, bao gồm tất cả các tham số, URL và nội dung HTTP header (ví dụ: tên và giá trị cookie).
  • Việc kiểm tra này giúp trán được các lỗ hổng liên quan như: path traversal, open url redirection, server-side injection
7. Xác minh rằng các giá trị header trong cả yêu cầu và phản hồi chỉ chứa các ký tự ASCII
  • Việc này giúp đảm bảo dữ liệu đầu vào chỉ gồm các ký tự hợp lệ tránh được các lỗ hổng liên quan đến các lỗ hổng về: host-header injection.
8. Xác thực dữ liệu từ chuyển hướng (Kẻ tấn công có thể gửi nội dung độc hại trực tiếp đến mục tiêu, do đó hacker có thể phá vỡ logic ứng dụng và bất kỳ xác thực nào được thực hiện trước chuyển hướng)
  • Thông thường website có các chức năng cho phép người dùng chuyển hướng sang các website khác, việc này nếu không được kiểm tra cẩn thận có thể bị hacker lợi dụng để chuyển hướng người dùng tới các website độc hại. Cách xử lý an toàn là whitelist các giá trị được phép chuyển hướng trong ứng dụng
9. Thực hiện kiểm tra kiểu dữ liệu (data-type, content-type), miền dữ liệu (data range), độ lớn của dữ liệu (data length, data volume) trên phía server một cách an toàn
  • Việc này giúp đảm bảo dữ liệu đầu vào được kiểm soát chặt chẽ ở phía server để tránh các lỗ hổng liên quan đến: Unrestricted file upload, dos, Cross-site Scripting...
10. Luôn luôn thực hiện validate dữ liệu bằng cách sử dụng "white list" khi có thể, tránh việc sử dụng "black list"
  • Ví dụ đối với việc validate dữ liệu với chức năng upload avtar: Thay vì thực hiện chặn các extension không được phép như (.php, .php3, .svg..) thì chúng ta thực hiện "white list" các extension được phép upload trên server (png, jpg). Việc đảm vừa đảm bảo an toàn mà tiết kiệm được công sức khi lập trình
11. Nếu bất kỳ ký tự nguy hiểm tiềm ẩn nào được cho phép trong ứng dụng, hãy đảm bảo rằng bạn triển khai tốt các biện pháp đảm bảo an toàn như mã hóa đầu ra, bảo mật các API và tính toán việc sử dụng dữ liệu đó trong toàn bộ ứng dụng.
  • Ví dụ về các ký tự nguy hiểm phổ biến bao gồm: <> "'% () & + \ ' "
12. Nếu quy trình xác thực dữ liệu của bạn không thể giải quyết các đầu vào sau, thì chúng nên được kiểm tra một cách riêng biệt
  • Kiểm tra các byte trống (% 00) : Chống các lỗi liên quan đến upload file, LFI (Local file inclusion)
  • Kiểm tra các ký tự dòng mới (% 0d,% 0a, \ r, \ n): Chống các lỗi về code injection, LFI, RFI (remote file inclusion)
  • Kiểm tra các ký tự ../ hoặc .. Trong trường hợp thực hiện encode UTF-8 thì cần kiểm tra các ký tự: %c0%ae%c0%ae/: Chống các lỗ hổng LFI, RFI, Path traversal
Các lỗi hổng thường gặp khi đầu vào không được kiểm duyệt tốt:
  • SQL Injection
  • OS Command Injection
  • Code injection
  • LDAP Injection
  • Unrestricted file upload
  • Buffer overflow
  • ...
II. Output Encoding
Yêu cầu này liên quan đến việc xử lý dữ liệu đầu ra trước khi cho dữ liệu hiển thị trên website. Việc này giúp đảm bảo dữ liệu khi hiển thị sẽ không bị sai về định dạng hay bị dính các lỗ hổng phía client-side.
1. Tất cả dữ liệu đầu ra cần được encode ở một hệ thống an toàn, đáng tin cậy.
  • Hệ thống đáng tin cậy có thể là server do chúng ta quản lý, server của các bên thứ 3 đủ độ tin cậy và an toàn.
2. Sử dụng các encode chuẩn đã được kiểm tra an toàn.
  • Việc sử dụng các chuẩn có sẵn sẽ mang lại một số lợi ích: Thuật toán đã được kiểm tra an toàn, không tốn công sức implement từ đầu, có tài liệu hướng dẫn cụ thể, dễ maintain và có thể được hỗ trợ từ cộng đồng
3. Thực hiện encode dữ liệu đầu ra đối với các dữ liệu từ các nguồn không tin cậy sẽ được hiển thị ở phía người dùng
  • Việc encode này để chống lại lỗ hổng Cross-site Scripting (XSS). Chúng ta có thể sử dụng HTML entity encoding để thực hiện việc encode dữ liệu
4. Encode toàn bộ dữ liệu trừ khi biết chắc chắn dữ liệu đó là từ nguồn tin tưởng.
  • Việc encode này để chống lại lỗ hổng Cross-site Scripting (XSS). Các nguồn dữ liệu tin cậy là dữ liệu đã được xử lý làm sạch (có thể sử dụng HTMl purifier) hoặc từ các nguồn tin tưởng khác (facebook, google, github...)
5. Làm sạch theo ngữ cảnh tất cả đầu ra của dữ liệu không đáng tin cậy cho các truy vấn cho SQL, XML và LDAP
  • Loại bỏ các dữ liệu khi hiển thị đối với dữ liệu là các truy vấn SQL, XML, LDAP. Việc nay giúp chống lại các lỗ hổng liên quan đến SQL Ijection, XML injection
6. Làm sạch tất cả đầu ra của dữ liệu không đáng tin cậy liên quan đến lệnh của hệ điều hành
  • Chúng ta cần làm sạch loại bỏ các dữ liệu liên quan đến cách lệnh của hệ điều hành (operating system commands) để tránh các lỗi liên quan đến Command injection, Code injection.
Các lỗ hổng thường gặp khi đầu ra không được xử lý đúng:
  • Cross-site Scripting (Reflected XSS, Stored XSS, DOM XSS)

III. Tổng kết

Đây là 2 nội dung quan trọng hàng đầu trong các yêu cầu về lập trình an toàn, nếu xử lý tốt 2 phần này, các website về cơ bản sẽ trở nên an toàn và tránh được các lỗ hổng nghiêm trọng cũng như tránh được các lỗ hổng được phát hiện bằng các công cụ scan tự động.


Tham khảo: 

Nhận xét

Bài đăng phổ biến từ blog này

So sánh giấy phép mã nguồn mở Apache, MIT, GPL

Mã nguồn mở ngày nay đã và đang trở nên phổ biến hơn bao giờ hết, những dự án mã nguồn mở có thể được tìm thấy hầu như ở bất kì đâu trên không gian mạng rộng lớn này. Tuy nhiên dù có “mở” đi chăng nữa thì những phần mềm mã nguồn mở phải tuân theo những giấy phép nhất định. Điển hình là 3 loại giấy phép phổ biến nhất là Apache, MIT và GPL. Vậy, giữa chúng có gì khác nhau. Trước hết, giấy phép mã nguồn mở là một loại giấy phép được sử dụng cho các phần mềm mã nguồn mở. Giấy phép này cho phép bất kì cá nhân hay tổ chức nào cũng có thể nghiên cứu, thay đổi, chỉnh sửa và cải tiến phần mềm, và phân phối ở các dạng khác nhau như thay đổi hoặc chưa thay đổi. Giấy phép Apache Giấy phép Apache ra đời bởi Quỹ Phần mềm Apache (Apache Software Foundation - ASF). Đây là một giấy phép phần mềm tự do, không có copyleft, bắt buộc trong việc thông báo bản quyển và lời phủ nhận. Giấy phép này hoạt động như các giấy phép phần mềm mã nguồn mở khác, trao cho người sử dụng phần mềm quyền tự do trong b

Mã hóa đối xứng và bất đối xứng

Hôm nay mình xin được nói về hai thuật toán cơ bản và quan trong nhất trong bảo mật đó là mã hóa đối xứng và mã hóa bất đối xứng . 1. Mã hóa đối xứng (mã hóa không công khai- symmetric-key algorithms ) - Là lớp thuật toán các mã hóa trong đó việc mã hóa và giải mã đều dùng chung cho 1 khóa (secret key) 1.1 Các loại thuật toán khóa đối xứng Thuật toán đối xứng có thể được chia ra làm hai thể loại, mật mã luồng ( stream ciphers ) và mật mã khối ( block ciphers ). Mật mã luồng mã hóa từng bit của thông điệp trong khi mật mã khối gộp một số bit lại và mật mã hóa chúng như một đơn vị. Cỡ khối được dùng thường là các khối 64 bit. Thuật toán tiêu chuẩn mã hóa tân tiến ( Advanced Encryption Standard ), được NIST công nhận tháng 12 năm 2001, sử dụng các khối gồm 128 bit. Các thuật toán đối xứng thường không được sử dụng độc lập. Trong thiết kế của các hệ thống mật mã hiện đại, cả hai thuật toán bất đối xứng ( asymmetric ) (dùng chìa khóa công khai) và thuật toán đối xứng được sử

Chuyện nghề Kiểm thử an toàn thông tin

Từ hồi đi làm đến giờ, tôi gặp nhiều tình huống không biết nên trả lời thế nào cho đúng, hôm nay ghi lại đây để mai mốt ai có gặp tham khảo. Khi được liên hệ, tôi thấy đa phần các đơn vị làm xong rồi mới nghĩ đến chuyện kiểm thử, thậm chí là bị hack rồi mới nghĩ tới. Việc pentest nên được triển khai ngay từ khi Phân tích thiết kế hệ thống . Các luồng đi của dữ liệu khi phác thảo ý tưởng ở trên giấy cũng cần kiểm tra tính an toàn, nếu để đến khi đã ra sản phẩm rồi thì đi sửa lại mất nhiều thời gian, công sức hơn nhiều, thậm trí sửa lại sinh ra lỗi mới. Nhiều người vẫn đánh giá các sản phẩm cầm nắm được giá trị hơn sản phẩm trí tuệ, hay sáng tạo. Giống thằng em tôi làm graphic designer hay "được nhờ" vẽ hộ logo hai cái này cái kia, có khi mất cả ngày hoặc nhiều hơn, trong khi không được đồng nào, có khi còn bị chê :)). Nếu làm tốt việc gì đó, đừng bao giờ làm miễn phí hoặc lấy giá quá rẻ . Nghe đồn Louis Vutton đốt trụi rũi hàng ế, chứ chưa bao giờ chịu giảm giá. Relax với chuy