OWASP (Open Web Application Security Project) は、Web アプリケーションに対する現在の脅威を記録するプロジェクトです。私は彼らのサイトをフォローしていますが、2010 年、2013 年、2017 年のレポートにはいくつかの類似点があり、SQL またはその他の種類のインジェクション脅威がリストの最上位にあります。
これは深刻な問題です。
これは倒産の原因となるため、この問題は生死に関わる問題であり、組織はこの種の問題の発生を避けるためにこの種の問題への対処に重点を置く必要があります。
注射とは何ですか?
いわゆるインジェクションとは、データがフィルタリングされず、信頼できないコンテンツがシステム インタープリタに直接書き込まれることを意味します。この動作は、サイトへの SQL インジェクションにつながります。さらに悪いことに、攻撃者は、システムに対する完全な権限を取得します。
例:
次の悪意のあるクエリ ステートメントを見てください。これは、悪意のある動作を含む SQL ステートメントを $name 変数に配置し、ユーザーがpass POST メソッドは、受信した悪意のあるコードを使用して攻撃を実行するという最終的な目的を達成するために、PHP スクリプトに渡されます。
// 将恶意代码,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; -- '
ご想像のとおり、上記のステートメントはデータベースからユーザー データ テーブル全体を削除します。
ヨーダが言ったように:
これは危険すぎる、そう、危険すぎる。
PHP アプリケーションへの悪意のあるインジェクションを防ぐにはどうすればよいですか?
まず第一に、実際にはデータベースには何も挿入されません。このエラーは単にクエリ ステートメントの形式が間違っていることが原因です。 SQL ステートメントを正しくフォーマットするか、クエリ ステートメントとデータを別々に直接処理する限り、解決策は簡単です。 ######どうやってするの?パラメーター化されたクエリを使用してデータをフォーマットし、クエリ ステートメントをデータから分離します。
パラメータ化されたクエリを使用すると、プログラムがインジェクションのリスクを確実に回避できます。
例は次のとおりです:
$statement = $db->prepare('SELECT * FROM table WHERE id = ? and name = ? ');\ $statement->execute([1, "Mark"]);
さらに、プロジェクトで ORM (オブジェクト リレーショナル マッピング) またはクエリ ビルダーを使用する安全な方法があります。
私がおすすめしたいのは、有名なPHPフレームワークLaravelでも使われているEloquentです。次に、注射の危険を効果的に回避するためにデータをフォーマットするのに役立つ、そのインストール方法と使用方法を説明します。
Eloquent のインストール準備
PHP と
Composer正式な開始プロジェクトの開始時に ORM をインストールするのが最善です。
posts テーブルと users テーブルを含むブログ アプリケーションを構築するとします。
初期化構成最初に行うことは、プログラム用のcomposer.jsonファイルを作成することです。ターミナルでcomposer initを実行し、ターミナルのプロンプトに従うことができます。
#依存関係を定義するように求められたら、「luminate/database」と書きます。最終的な出力は上の画像のようになります。これで、composer install を実行して、プロジェクトに対応する依存関係をインストールできるようになります。
または、composer.json ファイルがすでにある場合は、ターミナルに直接「composer require inspired/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 ファイルを導入する必要があります。この方法で、ベンダー ディレクトリ内のすべてのパッケージをロードできます。
次に、Illuminate\Database\Capsule\Manager を Capsule として使用し、eloquent を使用できるようにエイリアスを付けます。
次に、上記の bootEloquent() と同様に、Capsule オブジェクトを作成し、データベース接続を初期化します。
さて、明らかに最初に行う必要があるのは、test という名前のデータベースを作成することです。ローカルで正しいユーザー名とパスワードを入力していることを確認してください。
移行 / データ移行Eloquent を使用する最大の利点の 1 つは、移行を使用できることです。
移行とは何かわからない場合は、以下の説明を読んでください:
移行は、PHP コードを通じてデータ テーブルを作成する方法です。
migrations.php ファイルに移行を作成します:
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 クラスを通じて 2 つのデータ テーブルを作成します。1 つは users テーブル、もう 1 つは post テーブルで、それぞれフィールドです。それらには名前が定義されています。
このファイルを実行します。白い画面が表示された場合は、移行が正常に実行されたことを意味します。これで、データベースを開いて、これら 2 つのテーブルが生成されたかどうかを確認できます。
Modelsあとは、データ テーブルに対応する Model クラスを作成するだけです。
用了 Eloquent,你就可以在 Model 类里操作相应的数据表,执行查询语句了。
创建一个 Models 文件夹,然后在其中分别创建 User.php 和 Post.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 助手,将帮助你写出更干净且更安全的代码。
更多PHP相关知识,请访问PHP中文网!
以上がSQL インジェクションを回避するには、PHP プロジェクトで Laravel Eloquent クエリを単独で使用します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。