19

データベースに送信される文字列に、ユーザーが不正/特殊文字を使用する可能性のあるフォームに取り組んでいます。文字列内のこれらの文字をエスケープ/否定したいので、htmlspecialchars()を使用しています。しかし、より良い/より速い方法はありますか?

4

6 に答える 6

30

データベースに「違法な」文字はありません。一部の文字を格納できないデータベースはナンセンスです。文字列を区切るために使用される引用符などのサービス文字がいくつかあります。これらの文字は、削除するのではなく、エスケープする必要があります。

データベースにクエリを送信するには、次の2つのオプションがあります。

  1. 通常の方法でクエリを作成し、SQLコンソールで実行できるSQLクエリとまったく同じように表示します。そのためには、 「mysql_real_escape_stringを使用する」だけでなく、一連のルール全体
    を理解する必要があります。 次のようなルール:

    • 文字列は引用符で囲み、エスケープする必要があります。エスケープの唯一の意味はそれです:それは単にエスケープ区切り文字です!(および他のいくつかの文字-文字列終了文字およびエスケープ文字自体)。引用符で囲まれていない場合、mysql_real_escape_stringはまったく役に立ちません。
    • 数値は、その型に明示的にキャストする必要があります。データ番号は文字列と同じように脅威にさらされる可能性がありますが、LIMIT句のパラメータなど、エスケープできず、キャストのみが可能な番号もあります。
  2. クエリとデータを別々に送信します。
    これは、単に「バインディングを使用する」に短縮できるため、最も好ましい方法です。すべての文字列、数値、およびLIMITパラメータをバインドできます-まったく心配する必要はありません。
    この方法を使用すると、プレースホルダーを使用したクエリがそのままデータベースに送信され、バインドされたデータが別々のパケットで送信されるため、干渉することはありません。これは、コードデータの分離に似ています。プログラム(クエリ自体)をデータとは別に送信します。

だが!

上記のすべては、クエリのデータ部分のみを対象としています。
ただし、演​​算子や識別子を追加して、クエリをさらに動的にする必要がある場合もあります。
この場合、すべての動的パラメーターをスクリプトにハードコーディングし、そのセットから選択する必要があります。
たとえば、動的な順序付けを行うには、次のようにします。

$orders  = array("name","price","qty"); //field names
$key     = array_search($_GET['sort'],$orders)); // see if we have such a name
$orderby = $orders[$key]; //if not, first one will be set automatically. smart enuf :)
$query   = "SELECT * FROM `table` ORDER BY $orderby"; //value is safe

または動的検索:

$w     = array();
$where = '';

if (!empty($_GET['rooms']))     $w[]="rooms='".mesc($_GET['rooms'])."'";
if (!empty($_GET['space']))     $w[]="space='".mesc($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mesc($_GET['max_price'])."'";

if (count($w)) $where="WHERE ".implode(' AND ',$w);
$query="select * from table $where";

この例では、フィールド名ではなく、ユーザーが入力したデータのみをクエリに追加しています。これらのデータはすべてスクリプトにハードコードされています。バインディングの場合、アルゴリズムは非常に似ています。

等々。

于 2010-06-08T06:15:55.473 に答える
13

このデータをデータベースに送信する場合は、データベースのエスケープ関数を確認してください。

つまり、MySQL にはmysql_real_escape_stringがあります。

これらのエスケープ関数は、悪意のある可能性のある文字を処理し、そこに入力したのと同じ方法でデータを取得します.

準備済みステートメントを使用してデータを処理することもできます。

$dbPreparedStatement = $db->prepare('INSERT INTO table (htmlcontent) VALUES (?)');
$dbPreparedStatement->execute(array($yourHtmlData));

またはもう少し自己説明:

$dbPreparedStatement = $db->prepare('INSERT INTO table (htmlcontent) VALUES (:htmlcontent)');
$dbPreparedStatement->execute(array(':htmlcontent' => $yourHtmlData));

異なるタイプのデータを保存する場合は、 を使用bindParamして各タイプを定義します。つまり、整数は次のように定義できます$db->bindParam(':userId', $userId, PDO::PARAM_INT);。例:

$dbPreparedStatement = $db->prepare('INSERT INTO table (postId, htmlcontent) VALUES (:postid, :htmlcontent)');
$dbPreparedStatement->bindParam(':postid', $userId, PDO::PARAM_INT);
$dbPreparedStatement->bindParam(':htmlcontent', $yourHtmlData, PDO::PARAM_STR);
$dbPreparedStatement->execute();

$dbPHP データ オブジェクト (PDO) はどこにありますか。使用していない場合は、 PHP Data Objectsで詳細を学ぶことができます。

于 2010-06-07T20:53:23.977 に答える
2

まず第一に、データベースに挿入する前ではなく、表示するときにサニタイズする必要があります。SQL インジェクションは別の話ですが、おそらくトピック外です。

次に、ユーザーが HTML を投稿できるようにする必要がまったくない場合は、それで十分ですhtmlspecialchars。HTML のすべての特殊文字を処理します。

于 2010-06-07T20:50:22.963 に答える
1

データベースに送信される文字列に、ユーザーが不正/特殊文字を使用する可能性のあるフォームに取り組んでいます。

ユーザーは、実際にはそれをはるかに超えることができます。

文字列内のこれらの文字をエスケープ/否定したいので、htmlspecialchars() を使用しています。ただし、より良い/より高速な方法があるかどうかを知りたいです。

HTML ピューリファイヤーを使用:

HTML Purifier は、PHP で書かれた標準準拠の HTML フィルター ライブラリです。HTML Purifier は、完全に監査された安全で寛大なホワイトリストを使用して、すべての悪意のあるコード (XSS として知られている) を削除するだけではありません。

そして自分で決めてください:)

于 2010-06-07T20:48:53.080 に答える
0

これは、自分で取り組みたい問題ではありません。HTML Purifierなど、これを行うためのライブラリがあります。

于 2010-06-07T20:49:48.507 に答える
0

これらの不正な文字が何であるかは述べていませんが、データベース API の提供されたメカニズムを使用してデータをエスケープする必要があります。たとえば、MySQL を使用している場合は、PDO パラメーター化された SQL ステートメントを使用します。

于 2010-06-07T20:51:58.737 に答える