[*Thực hành] Thử nghiệm SQL Injection

Bảo mật

Mục tiêu

Luyện tập thử nghiệm SQL Injection và chống SQL Injection.

Mô tả

Trong phần này, chúng ta sẽ phát triển một ứng dụng hiện thị danh sách khách hàng. Với hai cách viết câu truy vấn:

  • Có nguy cơ xảy ra lỗi SQL Injection
  • Chặn lỗi SQL Injection

Hướng dẫn

Bước 1: Tạo ứng dụng Laravel có tên “injection”

Vào thư mục chúng ta muốn lưu trữ mã nguồn của dự án rồi gõ lệnh:

composer  create-project laravel/laravel injection --prefer-dist

Đời đến khi lệnh chạy kết thúc

Screen%20Shot%202019 11 08%20at%2010.10.09

Bước 2: vào trong thư mục code và mở toàn bộ tên trong thư mục bằng trình soạn thảo yêu thích

cd injection/

Bước 3: Tạo CSDL cho ứng dụng Injection

Tạo một database có tên "injection"

Bước 4: Cài đặt cấu hình kết nối CSDL

Sửa file cấu hình “.env” theo các tham số sau

# Tên kết nối CSDL mặc định
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306

# CSDL mặc định
DB_DATABASE=injection

# Tài khoản
DB_USERNAME=root

# mật khẩu
DB_PASSWORD=

Các tham số này sẽ đường sử dụng ở trong file “config/database.php”. Vì thế các bạn hoàn toàn có thể thay thế các thông tin kết nối trực tiếp tại file “config/database.php”.

Bước 5: Tạo file migration

php artisan make:migration create_customer_table

Bước 6: Tạo các trường thông tin lưu trữ trong bảng “customer”

Sửa nội dung file “database/migrations/2018_09_24_172406_create_customer_table.php” như sau:

public function up(){
  Schema::create('customer', function (Blueprint $table) {
      $table->increments('id');
      $table->string('name');
      $table->date('dob');
      $table->string('email');
      $table->timestamps();
  });
}

Bước 7: Thực thi migration

php artisan migrate
Screen%20Shot%202019 11 08%20at%2010.14.08

Bước 8: Tạo Seeding

php artisan make:seeder CustomerTableSeeder

Thay đổi nội dung file seeding như sau:

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class CustomerTableSeeder extends Seeder
{
  /**
   * Run the database seeds.
   *
   * @return void
   */
  public function run()
  {
      $dataArray = [];
      for ($i = 0; $i < 20; $i++) {
          array_push($dataArray, [
              'name' => str_random(10),
              'dob' => date("Y-m-d", mt_rand(1, time())),
              'email' => str_random(10) . '@gmail.com',
              'created_at' => date('Y-m-d H:i:s'),
              'updated_at' => date('Y-m-d H:i:s')
          ]);
      }
      DB::table('customer')->insert($dataArray);
  }
}

Và sửa nội dung file “database/seeds/DatabaseSeeder.php”:

public function run(){
  $this->call(CustomerTableSeeder::class);
}

Bước 9: Thực thi seeding, tạo dữ liệu mẫu

php artisan db:seed
Screen%20Shot%202019 11 08%20at%2010.27.16

Trong 1 số trường hợp có thể “CustomerTableSeeder” không được khởi chạy, khi đó bạn chạy lệnh:

composer dump-autoload
Screen%20Shot%202019 11 08%20at%2010.15.19

Và chạy lại lệnh khởi chạy seeding

Bước 10: Chạy ứng dụng và truy cập URL greeting để xem kết quả.

Gõ lệnh: php artisan serve

Screen%20Shot%202019 11 08%20at%2010.16.18

Truy cập “http://127.0.0.1:8000”, chúng ta sẽ thấy trang laravel greeting.

Screen%20Shot%202019 11 08%20at%2010.17.30

Bước 11: Thay đổi nội dung file “routes/web.php”

Route::get('/', function (\Illuminate\Http\Request $request) {
  if (!empty($request->value)) {
      $customers = DB::select(DB::raw('SELECT * FROM customer WHERE id = ' . $request->value));
  }
  dump('SELECT * FROM customer WHERE id = ' . $request->value);
  dd($customers);
  return view('welcome');
});

Bước 12: Truy cập đường dẫn sau “http://127.0.0.1:8000/?value=1

Screen%20Shot%202019 11 08%20at%2010.19.06

Kiểm tra chúng ta thấy sâu lệnh SQL được thực hiện sẽ là lấy dữ liệu ở bảng “customer” với id =1

Vậy bậy giờ chúng ta truy cập đường dẫn “http://127.0.0.1:8000/?value=1%20or%201=1

Screen%20Shot%202019 11 08%20at%2010.22.16

Chúng ta thấy rất rõ ràng lỗi SQL Injection đã bị khai thác và trả về toàn bộ dữ liệu của bảng “customer”

Bước 13: Sửa nội dung file “routes/web.php”

Route::get('/', function (\Illuminate\Http\Request $request) {
  if (!empty($request->value)) {
      $customers = DB::table('customer')->where('id', $request->value)->get();
  }
  dump('SELECT * FROM customer WHERE id = ' . $request->value);
  dd($customers);
  return view('welcome');
});

Bước 14: Truy cập đường dẫn sau “http://127.0.0.1:8000/?value=1

Screen%20Shot%202019 11 08%20at%2010.23.28

Kiểm tra chúng ta thấy sâu lệnh SQL được thực hiện sẽ là lấy dữ liệu ở bảng “customer” với id =1 không khác biệt so với trước đó.

Vậy bậy giờ chúng ta truy cập đường dẫn “http://127.0.0.1:8000/?value=1%20or%201=1

Screen%20Shot%202019 11 08%20at%2010.24.21

Chúng ta thấy lỗi SQL Injection đã đã bị chặn và dữ liệu ở bảng “customer” được bảo vệ, điều kiện truy vấn được xác thực chuẩn xác mà không gặp vấn đề gì.

Tổng kết

Qua bài tập trên chúng ta đã luyện tập:

  • Thử nghiệm tình huống SQL Injection
  • Xử lý lỗi SQL Injection

Mã nguồn: https://github.com/Sonnh290791/injection.git

Leave a Reply

Your email address will not be published.