4

私はこれを読みました:

注射に反対しないのに役立ちます。Beause エスケープは単なる文字列フォーマット機能であり、インジェクション防止機能ではありません。図に行きます。ただし、エスケープには準備済みステートメントと共通点があります。どちらも、悪名高い「ユーザー入力」に対してのみ使用している場合、データソースにもかかわらず、ANY クエリを構築するための厳密なルールとしてではなく、インジェクションを保証しません。データではなく識別子またはキーワードを挿入する必要がある場合。

次の投稿について: SQL エスケープを使用した動的 mysql クエリは、準備されたステートメントと同じくらい安全ですか?

だから私の質問は、それを使用することです:

$Var = "UserInput Data Possible SQL Injection";
$mysqli->real_escape_string($Var);

は SQL インジェクションに対する保護を提供しませんか?

$mysqli->query();使えるように使いたいfetch_array(MYSQLI_ASSOC);率直に言って、preparedステートメントを使用した後に結果を配列として取得する方法がわかりません。

したがって、データベース接続にこれがある場合:

$STD = new mysqli('localhost', 'root', 'xx', 'xx');
$STD->set_charset('utf8');

if ($STD->connect_error) {
    die("Standard Access Has Been Revoked. Please Contact Administration"); 
}elseif (!$STD){
die ("Other problem With Connecting To Database, Please Contact Administration");
}

の説明書に書いてある通りreal_escape_string

http://php.net/manual/en/mysqli.real-escape-string.php

上記のリスト:

注意 セキュリティ: デフォルトの文字セット mysqli_real_escape_string() に影響を与えるには、文字セットをサーバー レベルで設定するか、API 関数 mysqli_set_charset() を使用して設定する必要があります。詳細については、文字セットの概念セクションを参照してください。

リンク先: http://php.net/manual/en/mysqli.set-charset.php


私の全体的な質問は 3 つのオプションに分けることができます。1 つ目は、ステートメントの同等性を求めることですfetch_array()preparedこれにより、準備されたステートメントがデータを生として送信するため、SQL インジェクションを完全に防止できます。


この形式の最初の質問は次のとおりです。

私はクエリを次のように使用しています:

$GetCompletedQuery = $STD->query("SELECT Status FROM UserCompletion WHERE `UserID`=' ". $STD->real_escape_string($_SESSION['UID']) ."'");
$GetCompletedArray = $GetCompletedQuery->fetch_array(MYSQLI_ASSOC);

どちらが返されますか:

配列 ( [ステータス] => 1 )

ただし、準備済みステートメントを使用する場合:

$GetCompletedQuery = $STD->prepare("SELECT Status FROM UserCompletion WHERE `UserID`=?");
$GetCompletedQuery->bind_param('i', $_SESSION['UID']);
$GetCompletedQuery->execute();

$GetCompletedArray = $GetCompletedQuery->fetch_row;

print_r($GetCompletedArray);

どちらが返されますか:

致命的なエラー: 17 行目の /var/www/New/API/Constants.php の非オブジェクトに対するメンバー関数 fetch_row() の呼び出し

fetch_array()準備済みステートメントでは使用できないことがわかっているものを試してみると、同じことが表示されます。

それでは、準備されたステートメントを使用するためのオプションは何でしょうか?


2 番目の質問

通常のクエリを次のように使用する場合:

$GetCompletedQuery = $STD->query("SELECT Status FROM UserCompletion WHERE `UserID`=' ". $STD->real_escape_string($_SESSION['UID']) ."'");

これによりfetch_array(); 、SQL インジェクションからデータを適切に保護できますか?


3 番目の質問:

$_SESSION['UID'];これは次の方法で割り当てられているため、SQL インジェクションからエスケープ/保護する必要があります。

$InnerJoinQuery = $STD->query("
        SELECT Users.ID, Users.Username, Users.Password, UserInformation.LastName, UserInformation.Firstname, UserInformation.DOB
        FROM Users
        INNER JOIN UserInformation
        ON Users.ID = UserInformation.UserID WHERE Users.Username = '".$_SESSION['real_name']."'");
        $InnerJoinArray = $InnerJoinQuery->fetch_array(MYSQLI_ASSOC);

    $_SESSION['UID'] = $InnerJoinArray['ID'];
    $_SESSION['Password'] = $InnerJoinArray['Password'];
    $_SESSION['Firstname'] = $InnerJoinArray['Firstname'];
    $_SESSION['LastName'] = $InnerJoinArray['LastName'];
    $_SESSION['DOB'] = $InnerJoinArray['DOB'];

このスニペットは次のように説明しています。

ユーザーがユーザー名とパスワードを使用してログインすると、ファイルはデータベースから情報を取得$_SESSION['real_name']; し、結果を $_SESSION 配列に追加して、それぞれを異なるキーに追加します。

このチャンクに関する問題は、に$_SESSION['UID'];基づいてデータベースを介して割り当てられたときに、SQL インジェクションからエスケープ/保護する必要があるかどうかです。$_SESSION['real_name'];

この膨大なチャンクを読んでいただき、ありがとうございます。

4

1 に答える 1

6
  1. http://php.net/manual/en/mysqli-stmt.get-result.php
  2. はい、しかしそれは非常に悪い習慣です:
    • それはこの場合あなたを助けますが、この場合にのみそして他のもので欺くでしょう
    • 手動での脱出はばかげているので、ドライバーに任せてください。
  3. はい、SQLインジェクションのようなものはありませんが、不適切なフォーマットのみであるためです

使用$mysqli->real_escape_string($Var);してもSQLインジェクションに対する保護は提供されませんか?

私は考えを変えませんでした:確かに、そうではありません。
結果の値を引用符で囲む(そして、を使用mysqli_set_charset()して適切なエンコーディングを厳密に設定する)場合にのみ機能します。

ほら、SQLインジェクションはそれ自体に存在する本質的なものではありませんが、それはむしろ単なる結果です。不適切にフォーマットされたクエリの結果。
クエリを作成するときは、クエリのすべての部分を適切にフォーマットする必要があります。「注射」のためではなく、それのためです。文字列をクエリに挿入する場合は、文字列を引用符で囲む必要があります。そうしないと、構文エラーが発生します。クエリに文字列を挿入する場合、この文字列を区切るために使用されたこれらの引用符をエスケープする必要があります。そうしないと、構文エラーが発生します。等々。注射についての話を怖がらせるのではなく、あなたの関心事となるのは適切なフォーマットです。そして、すべての動的クエリパーツがそのタイプに従って適切にフォーマットされている限り、インジェクションは不可能です。

したがって、変数のソースまたはその値が問題になることはありません。しかし、それだけがクエリに含まれています。

  • 文字列は引用符で囲み、これらの引用符をエスケープする必要があります。
  • 数字はそのタイプにキャストする必要があります。
  • 識別子はバッククォートで囲む必要があり、これらのバッククォートを2倍にする必要があります

スクリプトにハードコーディングされたクエリの静的な部分を対象とする場合、このような厳密な標準は使用しません。たとえば、すべての識別子をバッククォートで囲んでいるわけではありません。
ただし、クエリの動的な部分を対象とする場合は、変数の内容を確実に知ることができないため、書式設定ルールの適用は厳密なルールにする必要があります。

ちなみに、文字列と数値をフォーマットする別の方法があります-プリペアドステートメント。本来あるべきほど便利ではありませんが、プレースホルダーを使用してクエリ内のデータを表すため、ばかげた手動フォーマットよりも使用することをお勧めします。

于 2013-01-14T04:20:07.587 に答える