OWASP(Open Web Application Security Project)는 현재 웹 애플리케이션에 대한 위협을 기록하는 프로젝트입니다. 저는 해당 사이트를 팔로우해 왔으며 2010년, 2013년, 2017년 보고서에서 SQL 또는 기타 유형의 주입 위협이 목록 상단에 있다는 점에서 몇 가지 유사점을 발견했습니다.
이건 심각한 문제입니다.
파산을 초래할 수 있으므로 이 문제는 사활을 걸고 발생하는 문제이므로 회사에서는 이러한 문제를 해결하는 데 집중해야 합니다.
주입이란 무엇인가요?
소위 주입은 데이터가 필터링되지 않고 신뢰할 수 없는 콘텐츠가 시스템 인터프리터에 직접 기록된다는 의미입니다. 더 나쁜 것은 공격자가 시스템에 대한 모든 액세스 권한을 얻을 수 있다는 것입니다. 권한.
예:
아래 악성 쿼리 문을 보면 악의적인 동작이 포함된 SQL 문을 $name 변수에 넣은 다음 사용자가 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; -- '
짐작한 대로 위 문은 데이터베이스에서 전체 사용자 데이터 테이블을 삭제합니다.
Yoda가 말했듯이:
너무 위험해요, 예, 너무 위험해요.
PHP 애플리케이션에 대한 악의적인 주입을 방지하는 방법은 무엇입니까?
우선, 실제로 데이터베이스에 아무것도 삽입되지 않습니다. 이 오류는 쿼리 문의 형식이 잘못되었기 때문에 발생합니다. SQL 문의 형식을 올바르게 지정하거나 쿼리 문과 데이터를 별도로 직접 처리하기만 하면 해결 방법은 간단합니다.
어떻게 하나요? 매개변수화된 쿼리를 사용하여 데이터 형식을 지정하고 쿼리 문을 데이터와 분리합니다.
매개변수화된 쿼리를 사용하면 프로그램이 주입 위험으로부터 벗어날 수 있습니다.
예제는 다음과 같습니다.
$statement = $db->prepare('SELECT * FROM table WHERE id = ? and name = ? ');\ $statement->execute([1, "Mark"]);
그 외에도 프로젝트에서 ORM(Object Relational Mapping)이나 쿼리 빌더를 사용하는 안전한 방법이 있습니다.
제가 추천하고 싶은 것은 유명한 PHP 프레임워크인 Laravel에서도 사용되는 Eloquent입니다. 다음으로, 주입 위험을 효과적으로 방지하기 위해 데이터 형식을 지정하는 데 도움이 되는 설치 및 사용 방법을 알려 드리겠습니다.
Eloquent 설치
준비
PHP와 Composer가 설치되어 있는지 확인하세요.
공식적으로 시작되었습니다
프로젝트 초기에 ORM을 설치하는 것이 가장 좋습니다.
게시물 테이블과 사용자 테이블을 포함하는 블로그 애플리케이션을 구축한다고 가정해 보겠습니다.
초기 구성
가장 먼저 할 일은 프로그램에 대한 작곡가.json 파일을 만드는 것입니다. 터미널에서 Composer init를 실행하고 터미널의 프롬프트를 따를 수 있습니다.
종속성을 정의하라는 메시지가 나타나면 Illuminate/database 를 작성하세요. 최종 출력은 위 이미지와 동일해야 합니다. 이제 작곡가 설치를 실행하여 프로젝트에 해당 종속성을 설치할 수 있습니다.
또는 이미 작곡가.json 파일이 있는 경우 터미널에 작곡가 필요 조명/데이터베이스를 직접 입력하여 해당 종속 항목을 설치할 수 있습니다.
이제 애플리케이션의 루트 디렉터리에 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 파일을 소개해야 합니다. 이러한 방식으로 공급업체 디렉터리의 모든 패키지를 로드할 수 있습니다.
그런 다음 IlluminateDatabaseCapsuleManager를 Capsule로 사용하는 방법을 소개하고 eloquent를 사용할 수 있도록 별칭을 지정합니다.
다음으로, 위와 같이 bootEloquent()를 사용하여 Capsule 객체를 생성하고 데이터베이스 연결을 초기화합니다.
이제 가장 먼저 해야 할 일은 test라는 데이터베이스를 만드는 것입니다. 로컬에서 올바른 사용자 이름과 비밀번호를 입력했는지 확인하세요.
마이그레이션/데이터 마이그레이션
Eloquent를 사용하면 가장 큰 이점 중 하나는 마이그레이션을 사용할 수 있습니다.
마이그레이션이 무엇인지 이해하지 못하신다면 아래 설명을 읽어보세요.
마이그레이션은 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(); });
migrations.php 파일에서 위 코드는 Capsule 클래스를 통해 두 개의 데이터 테이블을 생성합니다. 하나는 사용자 테이블이고 다른 하나는 게시물 테이블이며 각각 필드 이름을 정의합니다.
이 파일을 실행하세요. 흰색 화면이 나타나면 마이그레이션이 성공적으로 실행되고 있다는 의미입니다. 이제 데이터베이스를 열어 이 두 테이블이 생성되었는지 확인할 수 있습니다.
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!