PHP 項目中單獨使用 Laravel Eloquent 查詢語句來避免 SQL 注入

file

OWASP (Open Web Application Security Project) 是一個記錄當前 web 應用所受威脅狀況的項目。我一直都在關注他們的網站,從 2010,2013 和 2017 年的報告中我發現了一些類似之處,SQL 或其餘類型的注入威脅都是高居榜首。php

這是個心腹大患。mysql

它會致使你破產,所以這個事情關乎存亡,你單位應該着力處理此類問題避免它的出現。laravel

什麼是注入?

所謂注入,就是數據沒有通過過濾,將沒法信任的內容直接寫入了系統解釋器,這種行爲會致使對站點產生SQL注入,更糟糕的是,攻擊者可能會得到對系統的所有權限。web

舉個例子:

看下面的惡意查詢語句,它會將含有惡意行爲的SQL語句放在$name變量裏,而後容許用戶經過POST的方式傳遞給PHP腳本,從而達到最終使用傳入的惡意代碼進行攻擊的目的。sql

*//將惡意代碼, DROP TABLE寫入name變量*
`name = "Mark';DROP TABLE users; -- ";
query = "SELECT * FROM users WHERE name='name'";`數據庫

通過PHP腳本解析,這會最終生成這樣的SQL語句: SELECT * FROM users WHERE name='Mark';DROP TABLE users; -- 'json

正如你猜的那樣,上述語句會將整個users數據表從數據庫裏刪除掉。安全

正如尤達說的:bash

這太危險了,是的,太危險了。composer

如何防止對 PHP 應用的惡意注入?

首先,其實並無真的往數據庫裏注入什麼東西,這種錯誤只是因爲沒有正確地將查詢語句格式化。解決的方法很簡單,只要正確地格式化 SQL 語句,或者是直接把查詢語句和數據分開處理。

怎麼作呢?用參數化查詢對數據格式化,並使查詢語句與數據分離。

使用參數化查詢,能夠確保程序遠離注入風險。

例子以下:

$statement = $db->prepare('SELECT * FROM table WHERE id = ? and name = ? ');\ $statement->execute([1, "Mark"]);

除此以外,還有一種安全的作法,就是在項目中使用 ORM ( 對象關係映射)或者是查詢構造器。

我要推薦的是著名的 PHP 框架 Laravel 也在用的 Eloquent。接下來,我會教你如何安裝和使用,它能夠幫助咱們作好數據格式化的工做,從而有效避免注入危害。

更多關於 Eloquent 知識能夠參考 laravel docs.

安裝 Eloquent

準備工做

請確保你已經安裝了 PHP 和 Composer

正式開始

最好在項目開始之初就安裝 ORM。

假設咱們想建一個博客應用,包含一個 posts 表和一個 users 表。

初始化配置

首先要作的是爲程序建立 composer.json 文件。 你能夠在終端上運行 composer init  並按照終端上的提示進行操做。

eloquent composer setup screenshot

當他要求您來定義依賴關係的時候, 寫入 illuminate/database . 最後的輸出應該和上面的圖片中顯示的同樣。如今你就能夠在項中經過運行  composer install  來安裝相應的依賴了。

或者,若是你已經有了 composer.json 這個文件, 你能夠直接在終端輸入  composer require illuminate/database 來安裝相應的依賴。

如今咱們須要在應用程序的根目錄中建立  start.php 文件並把下面的代碼粘貼到文件中。我會在下面解釋他們的做用。

require "vendor/autoload.php";
//If you want the errors to be shown  *是否顯示錯誤
error_reporting(E_ALL);
ini_set('display_errors', '1');
use Illuminate\Database\Capsule\Manager as Capsule;

 $capsule = new Capsule;

 $capsule->addConnection([
    "driver" => "mysql",
    "host" =>"127.0.0.1",
    "database" => "test",
    "username" => "root",
    "password" => "root"
 ]);
//Make this Capsule instance available globally. *要讓 capsule 能在全局使用
 $capsule->setAsGlobal();
// Setup the Eloquent ORM.
 $capsule->bootEloquent();
複製代碼

在第一行咱們須要引入 vendor/autoload.php 文件。這樣咱們才能加載到 vendor 目錄下的全部包。

而後咱們引入 use Illuminate\Database\Capsule\Manager as Capsule 並起別名 ,這樣子咱們就能使用 eloquent 了。

接下來, 咱們建立一個 Capsule 對象並初始化咱們的數據庫鏈接, 如上  bootEloquent() 。

如今, 很明顯咱們要作的第一件事就是建立名爲 test 的數據庫,請確保你在本身本地輸入的是正確的用戶名和密碼.

Migrations / 數據遷移

使用 Eloquent 的一個最大的好處就是可使用 migrations。

若是你不瞭解什麼是 migrations,能夠看下面的解釋:

migration 是一種能夠經過 PHP 代碼建立數據表的方式。

migrations.php 文件中建立 migration:

require "start.php";
use Illuminate\Database\Capsule\Manager as Capsule;
Capsule::schema()->create('users', function ($table) {
   $table->increments('id');
   $table->string('name');
   $table->string('email')->unique();
   $table->string('password');
   $table->timestamps();
});
Capsule::schema()->create('posts', function ($table) {
   $table->increments('id');
   $table->string('title');
   $table->text('body');
   $table->integer('created_by')->unsigned();
   $table->timestamps();
});
複製代碼

上面這段代碼,經過 Capsule 類建立了兩個數據表,一個是 users 表,另外一個是 posts 表,而且分別爲他們定義了字段名。

運行這個文件,若是你看到白屏,就說明 migrations 運行成功了,如今就能夠打開數據庫看看是否生成了這兩個表。

php myadmin models example

Models

如今,惟一要作的就是建立對應數據表的 Model 類。

用了 Eloquent,你就能夠在 Model 類裏操做相應的數據表,執行查詢語句了。

建立一個 Models 文件夾,而後在其中分別建立 User.phpPost.php 文件:

namespace Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
   /**
    * 對應的數據表
    *
    * @var string
    */
    protected $table = "users";
   /**
    * 容許插入的字段
    *
    * @var array
    */
    protected $fillable = [
        'name', 'email', 'password'
    ];
   /**
    * 須要被隱藏的字段
    *
    * @var array
    */
    protected $hidden = [
        'password', 'remember_token',
    ];
   /*
    * 給 User 類添加方法
    *
    */
    public function posts()
    {
        return $this->hasMany(Post::class, 'created_by');
    }
}
複製代碼

And

namespace Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
   /**
    * 對應的數據表
    *
    * @var string
    */
    protected $table = "posts";
  /**
   * 容許插入的字段
   *
   * @var array
   */
   protected $fillable = [
       'title', 'body', 'created_by'
   ];
 }
複製代碼

composer.json 文件中加入以下代碼,以確保上面建立的類文件可以被自動加載。

"autoload": {
    "classmap": [
        "Models" // Folder where all your models are
     ]
}
複製代碼

而後執行 composer dump-autoload

經過 Eloquent 操做數據庫

基本大功告成了。 測一下吧,在根目錄建立 index.php 文件,添加以下代碼:

require "start.php";
use Models\User;
use Models\Post;
User::create(
 [
  'name' => 'Mark Mike',
  'email' => 'temp-email-1@mark.com',
  'password' => '1234'
 ]
);
Post::create(
 [
  'title' => 'New Blog Post',
  'body' => 'New Blog Content',
  'created_by' => 1
 ]
);
print_r(User::all());
print_r(Post::all());
print_r(User::find(1)->posts);
複製代碼

如你所見,用 Eloquent 操做數據庫就是這麼簡單。除此以外,Eloquent 還提供了不少方法供你使用,並且很安全。

結語:

Eloquent 就像是給你的 SQL 查詢加了一道安全層,它能夠過濾掉咱們在執行 SQL 查詢時所犯的錯誤。若是你想用它,可是又不想安裝 Laravel 框架,那麼我想你已經從這篇文章中學到了該如何去作。這個優雅的 SQL 助手,將幫助你寫出更乾淨且更安全的代碼。

文章轉自:learnku.com/php/t/25962
更多文章:learnku.com/php/c/trans…

相關文章
相關標籤/搜索