Loading
April 1, 2024By Harry Ha

SQL Loose Comparison

Loose Comparison là phương thức so sánh giữa hai giá trị mà không kiểm tra kiểu dữ liệu của chúng. Khi thực hiện phép so sánh trong một số hệ quản trị cơ sở dữ liệu, nó sẽ tự động chuyển đổi về một kiểu dữ liệu nào đó để có thể “hợp lý” khi so sánh.

Loose Comparison

Lỗ hổng “Loose Comparison” trong lập trình hay truy vấn cơ sở dữ liệu có thể dẫn đến những vấn đề bảo mật nghiêm trọng nếu không được xử lý cẩn thận. Có thể tham khảo lỗ hổng SQL Truncation Attack để thấy minh hoạ về việc thực hiện việc so sánh Loose Comparison

Giả sử bạn có một trường dữ liệu là chuỗi, nhưng lưu trữ giá trị số (ví dụ: chuỗi ‘1’, ‘2’, v.v.). Khi so sánh trường này với một giá trị số trong một truy vấn, hệ quản trị cơ sở dữ liệu có thể tự động chuyển đổi giá trị chuỗi thành số để thực hiện so sánh. Ví dụ:

MariaDB [chh]> SELECT '0' = 0;
+---------+
| '0' = 0 |
+---------+
|       1 |
+---------+
1 row in set (0.000 sec)
MariaDB [chh]> SELECT '0.0' = 0;
+-----------+
| '0.0' = 0 |
+-----------+
|         1 |
+-----------+
1 row in set (0.000 sec)
MariaDB [chh]> SELECT '0      ' = '0';
+-----------------+
| '0      ' = '0' |
+-----------------+
|               1 |
+-----------------+
1 row in set (0.000 sec)

Trong trường hợp này, nó sẽ thử và chuyển đổi chuỗi “cookiehanhoan” thành số. Nhưng thực tế thì đây không thế là số được. Nên bất kỳ chuỗi nào không thể chuyển được (không có ý nghĩa là số) thì mặc định sẽ là 0.

MariaDB [chh]> select 0 = 'cookiehanhoan';
+---------------------+
| 0 = 'cookiehanhoan' |
+---------------------+
|                   1 |
+---------------------+
1 row in set, 1 warning (0.001 sec)

Điều này khác với “Strict Comparison” (so sánh chặt chẽ), kiểu so sánh này sẽ thực hiện kiểm tra cả giá trị và kiểu dữ liệu. Hai thằng phải phải giống nhau thì kết quả của phép so sánh mới là TRUE.

Cách thức và quy tắc chuyển đổi kiểu dữ liệu có thể khác nhau giữa các hệ quản trị cơ sở dữ liệu, cấu hình hoặc phiên bản của mỗi cơ sở dữ liệu.

Một số hệ thống có thể yêu cầu rõ ràng về kiểu dữ liệu khi thực hiện so sánh, trong khi những hệ thống khác có thể linh hoạt, lỏng lẻo hơn. Ví dụ, Postgres áp dụng kỹ thuật Strict Comparison mặc định. Xem ví dụ cụ thể ở bảng dưới.

Lỗ hổng liên quan đến “Loose Comparison” thường được phân loại dưới nhóm “Security Misconfiguration” (Cấu hình bảo mật không chính xác) hoặc có thể liên quan đến “Injection” (Chèn mã độc) trong danh sách OWASP Top 10

MySQL Loose Comparison

Bảng này cho thấy kết quả của các phép so sánh lỏng lẻo (loose comparison) giữa các loại giá trị khác nhau trong MySQL. Mỗi ô của bảng mô tả kết quả của phép so sánh bằng = giữa hai giá trị ở hàng và cột tương ứng. “True” có nghĩa là MySQL coi hai giá trị là bằng nhau theo so sánh lỏng lẻo, trong khi “False” có nghĩa là chúng không bằng nhau.

MySQL Loose Comparison
  • Giá trị Boolean và Số: Có sự chuyển đổi giữa các giá trị Boolean (True và False) và số (1, 0, -1). Trong MySQL, True thường được chuyển đổi thành 1 và False thành 0. Điều này dẫn đến việc True bằng 1 và False bằng 0 khi so sánh.
  • Chuỗi và Số: Chuỗi có thể chứa các ký tự số (‘1’, ‘0’, ‘-1’) thường được chuyển đổi thành các số tương ứng khi so sánh với các số. Điều này có thể dẫn đến kết quả không mong đợi, ví dụ chuỗi ‘0e462097431906509019562988736854’ được coi là 0
  • NULL: Khi so sánh bất kỳ giá trị nào với NULL, kết quả luôn là NULL, điều này tương đương với “không xác định” trong logic của SQL. Điều này phản ánh tính chất đặc biệt của NULL trong SQL, nó không bằng bất kỳ giá trị nào, kể cả chính nó.
  • So Sánh Chuỗi: Các chuỗi không chứa chỉ số (‘John’, ‘1John’, v.v.) khi so sánh với các số hoặc các giá trị Boolean sẽ trả về kết quả là False, trừ khi chuỗi đó có thể được mô tả dưới dạng một số.
  • So Sánh Chuỗi Không Phù Hợp: Khi so sánh hai chuỗi không phù hợp mà không chứa các ký tự số ở đầu (‘John’ vs ‘1John’), kết quả là False, bởi vì chúng là hai chuỗi rõ ràng khác biệt.

MariaDB Loose Comparison

MariaDB và MySQL có nguồn gốc chung và cách xử lý so sánh lỏng lẻo rất giống nhau, nếu không muốn nói là giống hệt trong nhiều trường hợp.

MariaDB Loose Comparison

Postgres (No) Loose Comparison

Khác biệt lớn nhất giữa PostgreSQL và MySQL/Mariadb trong bảng so sánh này là PostgreSQL không thực hiện các phép so sánh lỏng lẻo (Loose Comparison) giữa các kiểu dữ liệu khác nhau. Có rất nhiều so sánh không đúng kiểu trả về trạng thái Error (kiểu dữ liệu không tương thích). Điều này chứng tỏ Postgres yêu cầu các giá trị phải có cùng kiểu dữ liệu khi thực hiện so sánh.

Postgres Loose Comparison

PostgreSQL nghiêm ngặt hơn trong việc thực hiện so sánh kiểu dữ liệu. Do đó, có thể coi là an toàn hơn khi thực hiện các phép toán so sánh. Nên nó có thể ngăn chặn một số loại lỗ hổng bảo mật liên quan đến Loose Comparison mà bạn có thể gặp phải khi sử dụng MySQL/MariaDB.

SQLite Loose Comparison

SQLite và MySQL/MariaDB có xu hướng giống nhau trong việc chuyển đổi kiểu dữ liệu và cho phép so sánh lỏng lẻo. Điều này dẫn đến kết quả không nhất quán và lỗ hổng bảo mật có thể xảy ra.

SQLite Loose Comparison

References

Harry Ha

Whitehat hacker, Founder at Cookie Hân Hoan, Co-founder at CyRadar, Senior Penetration Tester, OSCP, CPENT, LPT, Pentest+

svg

What do you think?

It is nice to know your opinion. Leave a comment.

Leave a reply