SELECT BINARY trong MySQL

Hôm nay được chị tester thông báo 1 bug: Khi user login thì hệ thống không phân biệt username & password dạng chữ hoa, chữ thường 😐

Câu query chỉ đơn giản là:

SELECT user_login	
FROM sys_user 
WHERE user_login = '$user_login' 
          AND user_passwd = '$password'

Hóa ra thằng MySQL nó không phân biệt chữ hoa, chữ thường nếu field type là varchar :-s

Cách fix: Có nhiều cách nhưng đơn giản nhất là “ép” về dạng binary để so sánh theo byte

SELECT user_login	
FROM sys_user 
WHERE BINARY user_login = '$user_login' 
          AND BINARY user_passwd = '$password'

Nguồn: http://dev.mysql.com/doc/refman/5.0/en/cast-functions.html#operator_binary

Posted in MySQL
It's me ;-)

Nam Khanh Do

Khanh is a full stack web developer with over 10 years of experience developing for the web. You can reach him on Twitter, like him on Facebook and connect with him on LinkedIn.

4 thoughts on “SELECT BINARY trong MySQL

  1. Theo tui nghĩ thì cái vụ đó không phải là bug “to tác” lắm.
    Nhìn xem, thằng Yahoo vẫn login theo Username chữ in vẫn được mặc dùng account là chữ thường.

  2. Uh, nếu trường hợp check theo username có lẽ không cần, nhưng password thì phải cần đúng không? Mà thật ra cái này bà tester chỗ tôi yêu cầu thôi chứ mình cũng chả quan tâm lắm vì thường password tôi md5 rồi, chẳng qua dự án đang làm có phần login nho nhỏ + không mã hóa password nên mới nảy sinh vấn đề này 🙂

  3. Sao lại đưa luôn thẳng vào câu SQL thế? Không sợ SQL-Injection à?
    Cách “hay hơn” là:
    1- SELECT userId FROM tableName WHERE loginName=escapeString($loginName)
    2- Có được ID rồi thì lấy user data theo ID
    3- Xong if ( $user->authenticate($password) ) { … }

    Tuy đi qua nhiều bước, nhưng sẽ rất là nhanh và tiện về nhiều mặt.
    1- sẽ rất là nhanh vì ID là PK (và loginName chắc bạn cũng index trên column nó rồi chứ!)
    2- Tuy “dư” thêm câu query 1 nhưng bù lại câu query 2 lại nhanh hơn 1 chút vì ID là PK và thường là number 🙂
    3- Bạn toàn quyền xử lýk iểu mã hóa password trong code

    Chưa kể nếu bạn setup cache, thì cache có thể ‘plug’ vào ở bất cứ bước nào 1, 2, 3 (giống như cache L1, L2, L3 trong CPU ấy nhỉ 🙂 ).

  4. Cám ơn những ý kiến của anh Thành :p

    2 biến $username & $password đã được escape trước khi cho vào trong chuỗi anh ạ.

    Thường thì khi “bề trên” có yêu cầu thì em mới làm những bước giống như anh bảo. VD như trong trường hợp thông báo chính xác với người dùng họ sai cái gì, username hay password…Còn với những case không cần cụ thể & thông báo chung chung như: “Tên truy cập hoặc mật khẩu không chính xác” thì em cứ quẳng nguyên cả lũ vào 1 câu query cho nhanh (mình nhanh) 😀

Leave a Reply

Your email address will not be published. Required fields are marked *