NhaLapTrinh.comNhà Lập Trình
Bảo mật cơ bản

Không bao giờ tin dữ liệu người dùng gửi lên

Mọi thứ đi vào từ bên ngoài, ô nhập liệu, đường dẫn, tệp tải lên, kể cả dữ liệu ứng dụng của chính bạn gửi về, đều có thể bị sửa. Kiểm tra lại ở máy chủ, dùng truy vấn có tham số thay vì ghép chuỗi, và mã hoá đầu ra khi hiện lên trang là ba thói quen phòng thủ cơ bản nhất.

🎙️
📑 Nội dung theo chương
  1. 0:35 Kiểm tra ở trình duyệt chỉ là lịch sự
  2. 1:27 Đừng ghép dữ liệu người dùng vào câu lệnh
  3. 2:23 Xử lý an toàn khi hiện lên trang
  4. 3:13 Tệp tải lên là cửa ngõ rộng nhất
  5. 4:07 Nguồn nội bộ cũng là bên ngoài
  6. 4:44 Câu hỏi thường gặp
🔊 Bản audio (lồng nhạc nền)

Mọi thứ đi vào hệ thống từ bên ngoài đều có thể bị sửa: ô nhập liệu, đường dẫn, tệp tải lên, và kể cả dữ liệu mà ứng dụng của chính bạn gửi về. Ba thói quen phòng thủ cơ bản nhất là kiểm tra lại mọi thứ ở phía máy chủ, dùng truy vấn có tham số thay vì ghép chuỗi, và xử lý an toàn dữ liệu trước khi hiện lên trang.

Chào bạn, đây là Nhà Lập Trình. Nếu chỉ được chọn một câu để dạy người mới về bảo mật, mình sẽ chọn câu trong tiêu đề. Phần lớn lỗ hổng phổ biến trong ứng dụng web đều quy về việc tin tưởng một thứ không đáng tin. Tập này kể cách nghĩ đó ở góc người phòng thủ.

Kiểm tra ở trình duyệt chỉ là lịch sự

Người mới hay làm thế này: ô số lượng trên trang có kiểm tra chỉ cho nhập số từ một tới mười. Ô giá bị khoá không cho sửa. Nút xoá chỉ hiện với quản trị viên. Họ nghĩ vậy là an toàn.

Nhưng mọi thứ chạy trên trình duyệt đều nằm trong tay người dùng. Bất kỳ ai cũng có thể mở công cụ dành cho nhà phát triển, sửa trang, hoặc gửi thẳng yêu cầu tới máy chủ mà không cần qua trang nào. Ô bị khoá có thể mở. Giới hạn một tới mười có thể bỏ. Nút bị ẩn có thể gọi trực tiếp.

Kiểm tra ở trình duyệt vẫn nên có, vì nó giúp người dùng bình thường biết họ nhập sai ngay lập tức. Nhưng đó là lịch sự, không phải bảo vệ. Mọi quy tắc quan trọng phải được kiểm tra lại ở máy chủ.

Ví dụ kinh điển: giá sản phẩm được gửi từ trang lên khi đặt hàng. Máy chủ tin giá đó và tạo đơn. Ai đó sửa giá thành một đồng. Máy chủ nên tự tra giá từ cơ sở dữ liệu, không bao giờ lấy giá từ những gì người dùng gửi.

Đừng ghép dữ liệu người dùng vào câu lệnh

Một trong những lỗ hổng lâu đời và vẫn còn phổ biến là chèn lệnh vào truy vấn cơ sở dữ liệu. Nó xảy ra khi chương trình tạo câu truy vấn bằng cách ghép chuỗi, dán thẳng thứ người dùng gõ vào giữa câu lệnh.

Vấn đề là nếu người dùng gõ vào những ký tự có ý nghĩa đặc biệt với ngôn ngữ truy vấn, thứ họ gõ không còn được hiểu là dữ liệu nữa mà thành một phần của câu lệnh. Ở mức nhẹ, truy vấn báo lỗi. Ở mức nặng, người ngoài có thể đọc hoặc sửa những dữ liệu họ không được phép.

Cách phòng rất đơn giản và gần như mọi ngôn ngữ đều hỗ trợ: truy vấn có tham số. Bạn viết câu lệnh với những chỗ trống được đánh dấu, rồi đưa dữ liệu vào riêng. Cơ sở dữ liệu biết chắc phần nào là lệnh, phần nào là dữ liệu, và không bao giờ nhầm lẫn, dù dữ liệu chứa ký tự gì.

Quy tắc là không bao giờ ghép chuỗi để tạo truy vấn với dữ liệu từ bên ngoài. Không có ngoại lệ vì thấy dữ liệu này chắc an toàn. Thói quen đúng thì không cần suy nghĩ lúc nào an toàn, lúc nào không.

Xử lý an toàn khi hiện lên trang

Chiều ngược lại cũng nguy hiểm. Người dùng nhập một bình luận, bạn lưu lại và hiện cho người khác xem. Nếu bình luận chứa những đoạn mã chạy được trên trình duyệt, và bạn hiện nó nguyên văn, đoạn mã đó sẽ chạy trên máy của mọi người xem.

Hậu quả có thể là đánh cắp phiên đăng nhập, thực hiện thao tác thay người dùng, hiện nội dung giả mạo. Người trong nghề gọi đây là chèn mã vào trang.

Cách phòng là mã hoá đầu ra: trước khi hiện dữ liệu người dùng lên trang, biến những ký tự đặc biệt thành dạng chỉ để hiển thị, không để trình duyệt hiểu là mã. Hầu hết khung ứng dụng và công cụ tạo khuôn trang hiện đại làm việc này tự động theo mặc định.

Cẩn thận ở những chỗ bạn cố tình tắt cơ chế tự động đó, ví dụ để hiện nội dung có định dạng. Đó là những chỗ cần xem xét kỹ nhất, và nên dùng thư viện lọc chuyên dụng chỉ cho phép một số định dạng an toàn.

Tệp tải lên là cửa ngõ rộng nhất

Cho người dùng tải tệp lên là mở một cánh cửa lớn. Tệp có thể không phải là thứ nó nói mình là. Một tệp mang đuôi ảnh nhưng bên trong là mã có thể chạy trên máy chủ. Một tệp khổng lồ làm đầy ổ đĩa. Một tệp nén nhỏ nhưng giải nén ra cực lớn.

Các nguyên tắc phòng thủ: kiểm tra loại tệp dựa trên nội dung thật chứ không chỉ dựa vào đuôi tên. Giới hạn kích thước. Đặt tên mới cho tệp do hệ thống tạo, không dùng tên người dùng đặt. Lưu tệp ở nơi máy chủ không chạy mã, hoặc ở dịch vụ lưu trữ riêng.

Với ảnh, nhiều hệ thống xử lý lại ảnh sau khi tải lên, như đổi kích thước và lưu lại thành định dạng chuẩn. Việc này vừa tiết kiệm dung lượng, vừa loại bỏ những thứ lạ có thể ẩn trong tệp gốc, kể cả thông tin vị trí chụp mà người dùng có thể không muốn công khai.

Và nhớ dọn dẹp: tệp tạm, tệp tải lên dở dang, tệp người dùng đã xoá. Chúng nằm lại trên ổ đĩa lâu ngày vừa tốn chỗ vừa là dữ liệu cần bảo vệ mà không ai còn nhớ.

Nguồn nội bộ cũng là bên ngoài

Có một cái bẫy tinh vi hơn: tin dữ liệu vì nó đến từ nguồn quen. Tệp đồng bộ từ đối tác, dữ liệu từ một hệ thống khác của chính công ty, thông tin đọc từ thư khách gửi tới.

Những nguồn đó cũng có thể chứa dữ liệu lỗi, hoặc bị ai đó chen vào giữa. Hệ thống của đối tác có thể bị xâm nhập. Một nhân viên có thể dán nhầm thứ gì đó vào bảng tính trước khi gửi.

Nguyên tắc vẫn vậy: mọi dữ liệu vượt qua ranh giới hệ thống của bạn đều được kiểm tra kiểu, độ dài, giá trị hợp lệ, và được đưa vào truy vấn bằng tham số.

Hãy coi ranh giới đó như cửa khẩu. Mọi thứ đi qua đều được kiểm tra, dù trông vô hại đến đâu, dù đến từ ai.

Câu hỏi thường gặp

Vì sao phải kiểm tra dữ liệu ở máy chủ khi trình duyệt đã kiểm tra?

Vì người dùng có thể sửa trang hoặc gửi yêu cầu thẳng tới máy chủ mà không qua trình duyệt. Kiểm tra ở trình duyệt chỉ giúp trải nghiệm, bảo vệ thật phải nằm ở máy chủ.

Truy vấn có tham số là gì?

Là cách viết câu truy vấn với chỗ trống được đánh dấu và truyền dữ liệu vào riêng, để cơ sở dữ liệu luôn phân biệt được đâu là lệnh, đâu là dữ liệu. Đây là cách phòng chèn lệnh vào truy vấn hiệu quả nhất.

Chèn mã vào trang web là gì?

Là khi dữ liệu người dùng chứa mã chạy được và bị hiện nguyên văn lên trang, khiến mã đó chạy trên trình duyệt của người xem. Cách phòng là xử lý an toàn dữ liệu trước khi hiển thị.

Làm sao cho người dùng tải ảnh lên an toàn?

Kiểm tra loại tệp theo nội dung thật, giới hạn kích thước, đặt tên mới, lưu ở nơi không chạy mã, và nên xử lý lại ảnh sau khi tải lên để loại bỏ nội dung lạ.

Dữ liệu từ ứng dụng điện thoại của chính mình có cần kiểm tra không?

Có. Yêu cầu từ ứng dụng có thể bị chặn và sửa trên đường đi, hoặc bị giả lập hoàn toàn. Máy chủ phải kiểm tra mọi dữ liệu như thể đến từ người lạ.

Cần tư vấn cụ thể cho trường hợp của bạn?

Chúng tôi sẽ liên hệ trong vòng 24 giờ.

Đăng ký tư vấn ngay

Bài viết liên quan

Bạn cần hỗ trợ thêm?

Để lại thông tin, chúng tôi sẽ liên hệ trong 24 giờ.