0

ユーザーがMicrosoftSQLデータベースに格納されているCSSとHTMLの一部を変更できるようにするシンプルなインターフェイスを作成しています。このインターフェースはPHP5とADOdbを使用します。

何らかの理由で、このフォームは1つ以上の一重引用符を含む入力を拒否します。たとえば、次の文字列は許可されていません: "background-image:url('paper.gif');"

SQLインジェクション攻撃を防ぐために、ADOdbが一重引用符を積極的にフィルタリングしているのではないかと思います。PHPでユーザー入力をエスケープして、一重引用符を格納できるようにする方法はありますか?

すべての一重引用符を自動的に二重引用符に変換することを検討しましたが、それはユーザーのマークアップを壊す可能性があるようです。

おそらくあまり役​​に立ちませんが、私が使用しているテストの例を次に示します。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Cp1252">
<title>Edit website</title>
</head>
<body>
<h1>CSS Test</h1>

<?php
    include_once ('database.php');
    $table = "[User Site]";

    if (!isset($_REQUEST['dbname'])) {
        return false;
    } else {
        $dbname = $_REQUEST['dbname'];
        $db = Database::singleton($dbname);

        //Push any new CSS to the database
        if (isset($_POST['css'])) {
            $css = $_POST['css'];
            $sql = "UPDATE " . $table . 
                    " SET html='" . $html . "', css='" . $css . "' " .
                    " WHERE dbnameId='" . $dbname . "'";
            $db->Execute($sql);
        }

        //Fetch any CSS from the database
        $sql = "SELECT * FROM " . $table . " WHERE dbnameId='" . $dbname . "'";
        $data = recordToArray($db->Execute($sql));
        echo "<p>";
        $css = $data[0]['css'];
    }

    $rows = 20;
    $cols = 80;
?>
<!-- Show the user a form -->
<form action="test.php" method="post">
    CSS:<br>  <textarea rows="<?php echo $rows ?>" cols="<?php echo $cols ?>" name="css"><?php echo $css ?></textarea><p>
    <input type="hidden" name="dbname" value="<?php echo $dbname ?>" />
    <input type="submit" value="Update CSS" />
</form>
</p>
</body></html>
4

3 に答える 3

4

ADODBを使用していますが、これまでに存在したほとんどすべてのデータベース抽象化ライブラリの主要な機能であるプレースホルダー/プリペアドステートメントを使用していません。

物事が適切にエスケープされていないため、クエリは失敗します。プレースホルダーを使用すると、エスケープが自動的に追加されます。使用しているデータベースに適切なタイプのプレースホルダーを挿入するParamメソッドを確認してください。(MSSQLを使用しているようですが?、プレースホルダーとして使用しているかどうかはわかりません。)

それ以外の

$sql = "SELECT * FROM " . $table . " WHERE dbnameId='" . $dbname . "'";
$sth = $db->Execute($sql);

あなたは次のようなものが欲しいです:

$sql = "SELECT * FROM $table WHERE dbnameId = " . $db->Param('dbname');
$psh = $db->Prepare($sql);
$sth = $db->Execute($psh, array( $dbname ));

(これはテストされておらず、微妙に間違っている可能性があります。詳細については、リンクされたマニュアルページをお読みください。ADODBがひどいことを述べましたか?)

ADODBはひどいものであり、PHP4の時代に設計されたことを覚えておいてください。PDOなどのより現代的なものの使用を検討してください。

于 2010-07-22T21:55:26.710 に答える
2

SQLインジェクションを防ぐための積極的なフィルタリングではありません。ここにはSQLインジェクションの防止策はまったくありません。CSSの単一引用符は、クエリの単一引用符として解釈されているため、構文エラーが発生します。

私はこれまでADOdbを使用したことがありませんが、パラメーターバインディングをサポートしているようです。これにより、見栄えの良いクエリを作成し、期待どおりに機能させることができます(SQLインジェクションのリスクはありません)。

$db->Execute('UPDATE foo SET bar = ?, baz = ?', array("it's", "working"));

データベースがそれを見ると、上記は次と同等です:

$db->Execute("UPDATE foo SET bar = 'it\'s', baz = 'working'");

構文は正しく、エラーやインジェクションを回避できます。とにかく、作業する方がはるかに優れています:)

于 2010-07-22T21:57:20.450 に答える
1

解決策ははるかに簡単だと思います。ユーザー入力を直接挿入している'ため、SQLクエリを中断します。(これすでにSQLインジェクションです!)したがって、それらをエスケープする必要があります。しかし、ADOdbがこれにどの方法を提供するかはわかりません。それはのmysql_real_escape_stringためでmysql_あり、のPDO::quoteためPDOです。

さらに:使用せず、代わりに使用してください。さらに、使用しないでください、それは安全ではありません!代わりに使用してください。$_REQUEST$_POSTregister_globals$_POST

于 2010-07-22T21:55:00.143 に答える