0. Khai bút đầu xuân
Chào mừng năm mới 2024! Xin chúc toàn thể thành viên của Viblo một năm tràn đầy thành công, hạnh phúc và ngày càng đóng góp nhiều bài viết chất lượng cho cộng đồng.
I. Tổng quan về NoSQL
1. NoSQL là gì?
NoSQL là thuật ngữ dùng để chỉ các hệ thống quản lý cơ sở dữ liệu không dựa trên mô hình quan hệ SQL (Structured Query Language) để tổ chức dữ liệu. Nói cách khác, NoSQL tập trung vào việc cung cấp những mô hình lưu trữ dữ liệu linh hoạt hơn, phù hợp với nhu cầu xử lý dữ liệu lớn và phân tán. Các loại cơ sở dữ liệu NoSQL phổ biến bao gồm:
- Cơ sở dữ liệu Key-Value (Ví dụ: Redis, DynamoDB): Lưu trữ dữ liệu dưới dạng cặp key-value, giúp truy xuất dữ liệu nhanh chóng.
- Cơ sở dữ liệu Document (Ví dụ: MongoDB, CouchDB): Lưu trữ dữ liệu dưới dạng các tài liệu (document), sử dụng định dạng như JSON hoặc BSON.
- Cơ sở dữ liệu Wide-Column Store (Ví dụ: Apache Cassandra, HBase): Tổ chức dữ liệu dưới dạng cột thay vì hàng, tối ưu cho việc truy xuất dữ liệu theo cột.
- Cơ sở dữ liệu Graph (Ví dụ: Neo4j, ArangoDB): Lưu trữ dữ liệu có mối quan hệ phức tạp như mạng lưới mối quan hệ giữa các đối tượng.
Ví dụ về MongoDB
Nếu sử dụng MongoDB, bạn có thể lưu trữ thông tin về một người dùng trong collection (tương đương với bảng trong SQL) dưới dạng tài liệu JSON như sau:
{
"_id": ObjectId("5a934e000102030405000000"),
"username": "example_user",
"email": "user@example.com",
"age": 25,
"address": {
"city": "Example City",
"country": "Example Country"
}
}
2. Ưu điểm của NoSQL
NoSQL mang lại một số ưu điểm đáng kể so với cơ sở dữ liệu quan hệ SQL truyền thống:
- Khả năng mở rộng tốt: Có thể thêm các node mới để mở rộng mà không ảnh hưởng đến hiệu suất.
- Linh hoạt về schema: Hỗ trợ schema linh hoạt, giúp ứng dụng dễ dàng thích ứng với thay đổi.
- Hiệu suất cao: Tối ưu hóa cho những truy vấn cụ thể.
- Hỗ trợ dữ liệu phi cấu trúc: Thích hợp cho dữ liệu có cấu trúc linh hoạt như JSON.
- Tương thích với môi trường đám mây: Phù hợp với các kiến trúc phân tán.
- Giảm chi phí: Giúp giảm bớt chi phí cho hệ thống xử lý dữ liệu lớn.
- Dễ tích hợp: Có thư viện hỗ trợ nhiều ngôn ngữ lập trình phổ biến.
3. Ví dụ truy vấn NoSQL
Dưới đây là một số ví dụ về truy vấn NoSQL với MongoDB:
Tìm kiếm
- Tìm tất cả người dùng có độ tuổi lớn hơn 21:
db.users.find({ "age": { $gt: 21 } })
- Tìm người dùng có tên đăng nhập là "exampleuser":
db.users.find({ "username": "example_user" })
Thêm dữ liệu
- Thêm một người dùng mới:
db.users.insertOne({ "username": "new_user", "email": "new_user@example.com", "age": 30, "address": { "city": "New City", "country": "New Country" }})
Cập nhật dữ liệu
- Cập nhật độ tuổi của người dùng có tên đăng nhập là "exampleuser":
db.users.updateOne({ "username": "example_user" }, { $set: { "age": 26 } })
Xóa dữ liệu
- Xóa tất cả người dùng có độ tuổi dưới 18:
db.users.deleteMany({ "age": { $lt: 18 } })
II. NoSQL Injection
1. NoSQL Injection là gì?
Trả lời cho câu hỏi tiêu đề bài viết: NoSQL Injection không phải là Không có SQL Injection. Khi sử dụng NoSQL, bạn vẫn có thể bị tấn công injection. NoSQL injection là một lỗ hổng cho phép kẻ tấn công can thiệp vào các truy vấn mà ứng dụng gửi đến cơ sở dữ liệu NoSQL. Các tác động của NoSQL injection có thể bao gồm:
- Vượt qua cơ chế xác thực.
- Trích xuất hoặc chỉnh sửa dữ liệu.
- Tấn công từ chối dịch vụ.
- Thực thi mã tùy ý trên máy chủ.
Có hai loại NoSQL injection:
- Syntax injection: Phá vỡ cú pháp truy vấn NoSQL.
- Operator injection: Sử dụng các toán tử truy vấn NoSQL để thao tác truy vấn.
2. NoSQL Syntax Injection
Để kiểm tra lỗ hổng NoSQL injection, có thể sử dụng ký tự đặc biệt và chuỗi fuzz phù hợp.
Phát hiện lỗ hổng syntax injection trong MongoDB
Giả sử có một ứng dụng mua sắm cho phép người dùng chọn danh mục sản phẩm. Khi người dùng chọn danh mục "fizzy", ứng dụng gửi truy vấn JSON:
this.category == 'fizzy'
Để kiểm tra, bạn có thể gửi một chuỗi fuzz trong tham số category
. Ví dụ:
'%22%60{\n;$Foo}\n$Foo \xYZ\u0000
Nếu gửi chuỗi fuzz làm ứng dụng trả về phản hồi khác, điều này chỉ ra rằng đầu vào không được xử lý đúng cách.
Kiểm tra điều kiện câu truy vấn
Thực hiện hai yêu cầu với điều kiện khác nhau để xác định nếu có khả năng ảnh hưởng đến truy vấn.
Ghi đè các điều kiện hiện tại
Thử tình huống chèn điều kiện luôn đúng:
this.category == 'fizzy'||'1'=='1'
Sử dụng ký tự null
Sử dụng ký tự null
kiểm tra ứng dụng có thực hiện xử lý ký tự này không. Nếu ký tự null
có thể hủy bỏ phần còn lại của truy vấn, điều này có thể dẫn đến lỗ hổng.
III. Demo tấn công NoSQL Syntax Injection
Mở đầu thử nghiệm với truy vấn ban đầu và tiến hành kiểm tra.
IV. Tổng kết
Trong phần 1 của bài viết, chúng ta đã thảo luận rất nhiều về NoSQL và các khía cạnh của lỗ hổng NoSQL injection. Ở phần tiếp theo, chúng ta sẽ khám phá nhiều phương pháp tấn công hơn và cách phòng tránh lỗ hổng này. Mong mọi người theo dõi.
Tài liệu tham khảo:
https://portswigger.net/web-security/nosql-injection
source: viblo