SQL Injection là gì? Cách Phòng Ch?ng T?n C?ng SQL Injection.
Hình 1. SQL Injection là gì? Cách Phòng Ch?ng T?n C?ng SQL Injection.

SQL Injection là gì? Cách Phòng Ch?ng T?n C?ng SQL Injection.

SQL Injection là m?t lo?i l? h?ng b?o m?t web x?y ra khi m?t k? t?n c?ng có th? chèn ho?c "tiêm" các l?nh SQL ??c h?i vào m?t truy v?n SQL h?p l?. ?i?u này có th? cho phép k? t?n c?ng th?c hi?n các hành ??ng kh?ng mong mu?n trên c? s? d? li?u c?a ?ng d?ng, ch?ng h?n nh? truy c?p d? li?u nh?y c?m, thay ??i ho?c xóa d? li?u, và th?m chí th?c hi?n các l?nh qu?n tr?.


Ví d? 1 v? SQL Injection

Gi? s? b?n có m?t ?ng d?ng web v?i m?t form ??ng nh?p ??n gi?n. Ng??i dùng nh?p tên ng??i dùng và m?t kh?u, và ?ng d?ng th?c hi?n truy v?n SQL sau ?? xác th?c ng??i dùng:

$username = $_POST['username'];
$password = $_POST['password'];

$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
$result = mysqli_query($conn, $sql);        

N?u ng??i dùng nh?p ' OR '1'='1?vào tr??ng tên ng??i dùng và b?t k? th? gì vào tr??ng m?t kh?u, truy v?n SQL s? tr? thành:

SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '';        

Ph?n ' OR '1'='1' lu?n lu?n ?úng, vì v?y truy v?n s? tr? v? t?t c? các hàng trong b?ng users, cho phép k? t?n c?ng ??ng nh?p mà kh?ng c?n bi?t m?t kh?u th?c s?.


Ví d? 2 v? SQL Injection

M?t cau query nh? sau:

$name = "Nguyen The Tung'; DELETE FROM SINHVIEN; -- ";
mysql_query("SELECT * FROM CUSTOMERS WHERE name='{$name}' ");        

Phan tích l?nh SQL ???c ta:

Khi giá tr? c?a $name là "Nguyen The Tung'; DELETE FROM SINHVIEN; -- ", truy v?n SQL s? tr? thành:

SELECT * FROM CUSTOMERS WHERE name='Tung'; DELETE FROM SINHVIEN; -- ';        

?o?n m? trên s? ???c phan tích nh? sau:

  1. SELECT * FROM CUSTOMERS WHERE name='Nguyen The Tung': Tìm t?t c? các hàng trong b?ng CUSTOMERS có c?t name là 'Nguyen The Tung'.
  2. DELETE FROM SINHVIEN: Xóa t?t c? các hàng trong b?ng SINHVIEN.
  3. -- ': B? qua ph?n còn l?i c?a cau l?nh SQL.


Cách ng?n ng?a


Cách ng?n ng?a SQL Injection ? ví d? 1:

  1. S? d?ng Prepared Statements (Cau l?nh chu?n b? s?n)

Prepared Statements tách bi?t d? li?u ??u vào c?a ng??i dùng kh?i m? SQL, giúp ng?n ng?a SQL Injection.

Ly do Prepared Statements ng?n ng?a SQL Injection

  • Tách bi?t m? SQL và d? li?u ??u vào: Khi b?n s? d?ng Prepared Statements, b?n ?ang tách bi?t ph?n c?u trúc c?a cau l?nh SQL kh?i d? li?u ??u vào. ?i?u này có ngh?a là các d? li?u ??u vào s? kh?ng bao gi? ???c coi là m?t ph?n c?a m? SQL.
  • X? ly d? li?u ??u vào an toàn: PDO s? t? ??ng thoát (escape) các ky t? ??c bi?t trong d? li?u ??u vào. ?i?u này ng?n ch?n vi?c chèn các ?o?n m? ??c h?i vào cau l?nh SQL.
  • C? ??nh c?u trúc cau l?nh SQL: Cau l?nh SQL ???c xác ??nh tr??c (prepared) và kh?ng thay ??i d?a trên d? li?u ??u vào. Do ?ó, kh?ng có cách nào ?? d? li?u ??u vào thay ??i m?c ?ích c?a cau l?nh SQL ban ??u.

Ví d? v?i MySQLi:

$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
$result = $stmt->get_result();        

Ví d? v?i PDO:

$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username AND password = :password");
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$stmt->execute();
$result = $stmt->fetch();        

  1. S? d?ng ORM (Object-Relational Mapping)

S? d?ng ORM nh? Eloquent (Laravel) ho?c Doctrine (Symfony) ?? t? ??ng hóa vi?c t?o các truy v?n an toàn.

Ví d? v?i Eloquent (Laravel):

$user = User::where('username', $username)->where('password', $password)->first();        

3. Escaping ??u vào ng??i dùng

S? d?ng các hàm thoát ky t? (escaping functions) ?? x? ly d? li?u ??u vào c?a ng??i dùng.

Ví d? v?i MySQLi:

$username = mysqli_real_escape_string($conn, $_POST['username']);
$password = mysqli_real_escape_string($conn, $_POST['password']);        

Ví d? v?i PDO:

PDO t? ??ng thoát ky t? khi s? d?ng prepared statements.

  1. S? d?ng các th? vi?n b?o m?t

S? d?ng các th? vi?n ho?c framework ?? ???c ch?ng minh là an toàn ?? x? ly các truy v?n SQL.

B?ng cách s? d?ng các bi?n pháp trên, b?n có th? gi?m thi?u nguy c? SQL Injection và b?o v? c? s? d? li?u c?a mình kh?i các t?n c?ng .


Cách ng?n ng?a SQL Injection ? ví d? 2:

?? ng?n ng?a SQL Injection, b?n nên s? d?ng Prepared Statements ho?c các th? vi?n cung c?p các hàm an toàn ?? th?c thi các truy v?n SQL. D??i ?ay là cách làm ?i?u ?ó.

S? d?ng MySQLi v?i Prepared Statements

// K?t n?i ??n c? s? d? li?u
$conn = new mysqli($servername, $username, $password, $dbname);

// Ki?m tra k?t n?i
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// Chu?n b? cau l?nh
$stmt = $conn->prepare("SELECT * FROM CUSTOMERS WHERE name = ?");
$stmt->bind_param("s", $name);

// Th?c thi cau l?nh
$stmt->execute();

// L?y k?t qu?
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    echo $row['name'];
}

// ?óng cau l?nh và k?t n?i
$stmt->close();
$conn->close();        

S? d?ng PDO v?i Prepared Statements

// K?t n?i ??n c? s? d? li?u
try {
    $pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Chu?n b? cau l?nh
    $stmt = $pdo->prepare("SELECT * FROM CUSTOMERS WHERE name = :name");
    $stmt->bindParam(':name', $name);

    // Th?c thi cau l?nh
    $stmt->execute();

    // L?y k?t qu?
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        echo $row['name'];
    }
} catch(PDOException $e) {
    echo "Connection failed: " . $e->getMessage();
}

// ?óng k?t n?i
$pdo = null;        

Vi?c s? d?ng Prepared Statements giúp ng?n ch?n SQL Injection b?ng cách ??m b?o r?ng d? li?u ??u vào c?a ng??i dùng ???c x? ly ?úng cách và kh?ng th? th?c thi nh? m?t ph?n c?a cau l?nh SQL. ?i?u này giúp b?o v? ?ng d?ng c?a b?n kh?i các cu?c t?n c?ng tiêm nhi?m SQL và b?o v? c? s? d? li?u c?a b?n kh?i b? truy c?p ho?c thay ??i trái phép.


Trung Hi?u ?inh

Data Engineering | Database Optimization | Data/Risk Analyst in Finance | Expert in MicrosoftExcel

10 个月

bài vi?t tam huy?t quá, c?m ?n anh r?t nhi?u vì ?? chia s?

赞
回复

要查看或添加评论,请登录

Nguy?n Th? Tùng的更多文章

  • Invisible MySQL columns in Laravel

    Invisible MySQL columns in Laravel

    Laravel là m?t framework PHP m?nh m? giúp ??n gi?n hóa nhi?u tác v? phát tri?n web ph? bi?n, bao g?m c? vi?c làm vi?c…

    3 条评论
  • Các options quan tr?ng c?a InnoDB Buffer Pool trong MySQL

    Các options quan tr?ng c?a InnoDB Buffer Pool trong MySQL

    InnoDB Buffer Pool là m?t ph?n quan tr?ng c?a h? th?ng MySQL, ch?u trách nhi?m cho vi?c l?u tr? d? li?u và ch? m?c ???c…

  • C?p nh?t index nh? th? nào

    C?p nh?t index nh? th? nào

    C?p nh?t index trong c? s? d? li?u là quá trình th?c hi?n khi d? li?u trong b?ng ???c thay ??i, và b?n c?n c?p nh?t…

  • T?i sao khi ?ánh index l?i t?n nhi?u RAM và chi?n l??c s? d?ng index hi?u qu?.

    T?i sao khi ?ánh index l?i t?n nhi?u RAM và chi?n l??c s? d?ng index hi?u qu?.

    Vi?c ?ánh index trong MySQL là m?t k? thu?t quan tr?ng ?? c?i thi?n hi?u su?t truy v?n, nh?ng nó c?ng ?i kèm v?i m?t s?…

    1 条评论
  • Index trong SQL là gì và khi nào nên ?ánh index?

    Index trong SQL là gì và khi nào nên ?ánh index?

    Vi?c t?o và qu?n ly các ch? s? (index) trong c? s? d? li?u là m?t khía c?nh quan tr?ng c?a vi?c t?i ?u hóa hi?u su?t…

  • Partitioning Trong MySQL K?t H?p V?i Laravel

    Partitioning Trong MySQL K?t H?p V?i Laravel

    Partitioning trong MySQL là m?t k? thu?t h?u ích ?? qu?n ly và t?i ?u hóa c? s? d? li?u l?n. Trong Laravel, b?n có th?…

  • Optimizing MySQL for Peak Performance

    Optimizing MySQL for Peak Performance

    In today's data-driven world, the performance of your MySQL database can significantly impact your application's…

    2 条评论