ホームページ バックエンド開発 PHPチュートリアル PHP データベースのセキュリティ - SQL インジェクションと予防策

PHP データベースのセキュリティ - SQL インジェクションと予防策

Nov 22, 2016 am 10:45 AM
php PHPデータベース

多くの Web 開発者は、SQL クエリが改ざんされる可能性があることを認識していないため、SQL クエリを信頼できるコマンドとして扱います。彼らは、SQL クエリがアクセス制御をバイパスし、それによって認証と権限のチェックをバイパスできることをほとんど知りませんでした。さらに、SQL クエリを介してホスト オペレーティング システム レベルのコマンドを実行することもできます。

ダイレクト SQL コマンド インジェクションは、攻撃者が既存の SQL ステートメントを作成または変更して、隠しデータを取得したり、キー値を上書きしたり、データベース ホスト オペレーティング システム コマンドを実行したりするためによく使用される手法です。これは、アプリケーションがユーザー入力を受け取り、それを静的パラメーターと組み合わせて SQL クエリにすることによって実現されます。いくつかの実例を以下に示します。

入力されたデータの検証が不足しており、接続する新しいユーザーを作成する権限を持つスーパーユーザーまたは他のデータベース アカウントを使用しているため、攻撃者はデータベースに新しいスーパーユーザーを作成する可能性があります。

例 #1 データのページング表示を実装するコードは、スーパーユーザー (PostgreSQL システム) の作成にも使用できます。

<?php
    $offset = $argv[0]; // 注意,没有输入验证!
    $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
    $result = pg_query($conn, $query);
?>
ログイン後にコピー

一般ユーザーは、$offset がビニングされている「前のページ」と「次のページ」のリンクをクリックします。元のコードでは、$offset が数値であるとのみ考えられます。ただし、誰かが次のステートメントを urlencode() して URL に追加しようとすると:

0;
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
    select &#39;crack&#39;, usesysid, &#39;t&#39;,&#39;t&#39;,&#39;crack&#39;
    from pg_shadow where usename=&#39;postgres&#39;;
--
ログイン後にコピー

、スーパー ユーザーを作成できます。 0; は、エラーが発生しないように、元のクエリを完成させるための正しいオフセットを提供するだけであることに注意してください。

注:

-- は SQL のコメント マークであり、通常、SQL インタープリターに次のステートメントを無視するように指示するために使用されます。

パスワードを取得する考えられる方法は、検索結果を表示するページをターゲットにすることです。攻撃者が行う必要があるのは、どの変数が SQL ステートメントに送信され、それらの変数が誤って処理されたかを特定することだけです。このような変数は通常、WHERE、ORDER BY、LIMIT、OFFSET などの SELECT クエリの条件文で使用されます。データベースが UNION 構造をサポートしている場合、攻撃者は完全な SQL クエリを元のステートメントに追加して、任意のデータ テーブルからパスワードを取得する可能性もあります。したがって、パスワードフィールドを暗号化することが重要です。

例 #2 記事といくつかのパスワードを表示する (任意のデータベース システム)

<?php
    $query = "SELECT id, name, inserted, size FROM products
        WHERE size = &#39;$size&#39;
        ORDER BY $order LIMIT $limit, $offset;";
    $result = odbc_exec($conn, $query);
?>
ログイン後にコピー

元のクエリに別の SELECT クエリを追加してパスワードを取得できます:

&#39;
union select &#39;1&#39;, concat(uname||&#39;-&#39;||passwd) as name, &#39;1971-01-01&#39;, &#39;0&#39; from usertable;
--
ログイン後にコピー

上記のステートメントの場合 (' と -- を使用) $query内の任意の変数に追加されると面倒になります。 SQL の

UPDATE にも脆弱性があります。このクエリは、上の例のように、別の完全なリクエストに挿入または追加することもできます。しかし、攻撃者は、テーブル内の一部のデータを変更できるように、SET 句をターゲットにすることを好みます。この場合、クエリを正常に変更するには、データベースの構造を知っている必要があります。フォーム上の変数名に基づいてフィールドを推測したり、総当たりでクラックしたりすることができます。ユーザー名とパスワードを保存するフィールドに名前を付ける方法は多くありません。

例 #3 パスワードのリセットから追加の権限の取得まで (任意のデータベース システム)

<?php
    $query = "UPDATE usertable SET pwd=&#39;$pwd&#39; WHERE uid=&#39;$uid&#39;;";
?>
ログイン後にコピー

しかし、悪意のあるユーザーは ' または '%admin%' のような uid を $uid への変数の値として送信します。管理者パスワードを入力するか、$pwd の値を "hehehe', admin='yes', trusted=100" (その後にスペースがあります) に送信して、さらに多くの権限を取得します。これを行うと、クエリは実際には次のようになります:

<?php
    // $uid == &#39; or uid like&#39;%admin%&#39;; --
    $query = "UPDATE usertable SET pwd=&#39;...&#39; WHERE uid=&#39;&#39; or uid like &#39;%admin%&#39;; --";
    // $pwd == "hehehe&#39;, admin=&#39;yes&#39;, trusted=100 "
    $query = "UPDATE usertable SET pwd=&#39;hehehe&#39;, admin=&#39;yes&#39;, trusted=100 WHERE
        ...;";
?>
ログイン後にコピー

次の恐ろしい例は、いくつかのデータベースでシステム コマンドを実行する方法を示します。

例 #4 データベースが配置されているホストのオペレーティング システム (MSSQL Server) を攻撃します

<?php
    $query  = "SELECT * FROM products WHERE id LIKE &#39;%$prod%&#39;";
    $result = mssql_query($query);
?>
ログイン後にコピー

攻撃が送信した場合、%' exec master..xp_cmdshell 'net user test testpass /ADD' -- の値として変数 $prod の場合、$query は

<?php
    $query = "SELECT * FROM products WHERE id LIKE &#39;%a%&#39;
        exec master..xp_cmdshell &#39;net user test testpass /ADD&#39;--";
    $result = mssql_query($query);
?>
ログイン後にコピー

になります。MSSQL サーバーは、システムにユーザーを追加するためのコマンドをその後に含むこの SQL ステートメントを実行します。このプログラムが sa として実行されており、MSSQLSERVER サービスに十分な権限がある場合、攻撃者はホストにアクセスするためのシステム アカウントを取得できます。

注:

上記の例は特定のデータベース システムに関するものですが、他のデータベース システムに対して同様の攻撃を実行できないという意味ではありません。さまざまな方法を使用すると、さまざまなデータベースが影響を受ける可能性があります。

予防措置

上記の攻撃を実行するには、攻撃者はデータベース構造に関する情報を知る必要があると言って自分を慰める人もいるかもしれません。はい、そうです。しかし、攻撃者がこの情報を取得しないとは誰も保証できません。取得したデータベースは漏洩の危険にさらされます。フォーラム プログラムなどのオープン ソース ソフトウェア パッケージを使用してデータベースにアクセスしている場合、攻撃者が関連コードを入手するのは簡単です。コードの設計が不適切な場合、リスクはさらに大きくなります。

这些攻击总是建立在发掘安全意识不强的代码上的。所以,永远不要信任外界输入的数据,特别是来自于客户端的,包括选择框、表单隐藏域和 cookie。就如上面的第一个例子那样,就算是正常的查询也有可能造成灾难。

永远不要使用超级用户或所有者帐号去连接数据库。要用权限被严格限制的帐号。

检查输入的数据是否具有所期望的数据格式。PHP 有很多可以用于检查输入的函数,从简单的变量函数和字符类型函数(比如 is_numeric(), ctype_digit())到复杂的Perl 兼容正则表达式函数都可以完成这个工作。

如果程序等待输入一个数字,可以考虑使用 is_numeric() 来检查,或者直接使用 settype() 来转换它的类型,也可以用 sprintf() 把它格式化为数字。

Example #5 一个实现分页更安全的方法

<?php
    settype($offset, &#39;integer&#39;);
    $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
    // 请注意格式字符串中的 %d,如果用 %s 就毫无意义了
    $query = sprintf("SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d;",
        $offset);
?>
ログイン後にコピー

使用数据库特定的敏感字符转义函数(比如 mysql_escape_string() 和 sql_escape_string())把用户提交上来的非数字数据进行转义。如果数据库没有专门的敏感字符转义功能的话 addslashes() 和 str_replace() 可以代替完成这个工作。看看第一个例子,此例显示仅在查询的静态部分加上引号是不够的,查询很容易被攻破。

要不择手段避免显示出任何有关数据库的信心,尤其是数据库结构。

也可以选择使用数据库的存储过程和预定义指针等特性来抽象数库访问,使用户不能直接访问数据表和视图。但这个办法又有别的影响。

除此之外,在允许的情况下,使用代码或数据库系统保存查询日志也是一个好办法。显然,日志并不能防止任何攻击,但利用它可以跟踪到哪个程序曾经被尝试攻击过。日志本身没用,要查阅其中包含的信息才行。毕竟,更多的信息总比没有要好。


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

今まで知らなかったことを後悔している 7 つの PHP 関数 今まで知らなかったことを後悔している 7 つの PHP 関数 Nov 13, 2024 am 09:42 AM

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

母音を文字列にカウントするPHPプログラム 母音を文字列にカウントするPHPプログラム Feb 07, 2025 pm 12:12 PM

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

PHPでHTML/XMLを解析および処理するにはどうすればよいですか? PHPでHTML/XMLを解析および処理するにはどうすればよいですか? Feb 07, 2025 am 11:57 AM

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

PHPでの後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? Apr 03, 2025 am 12:03 AM

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。

See all articles