2009-06-15 2 views
1

MySQLの注入試行を停止するPHP関数を作成しようとしています。私がやっているのは、str_replace()を使ってシンボルを削除し、HTML文字コードで置き換えることです。私の問題は、すべてのコードに&#が含まれていることです。私はそれらの記号をそのコードに置き換えることも望みます。どのように私のようなものにコード を変更せずにこれを行うことができます:PHP記号を文字コードで置き換えてSQLインジェクションを停止する機能

ここ
&#38&#59;&338&#59;#35&#59;32&#59; 

私の関数である。

function replaceSymbols($text) 
{ 
    $text = str_replace('#', '&#35', $text); 
    $text = str_replace('&', '&' $text); 
    $text = str_replace(';', '&#59', $text); 

    $text = str_replace(' ', ' ' $text); 
    $text = str_replace('!', '!' $text); 
    $text = str_replace('"', '"' $text); 
    $text = str_replace('$', '$' $text); 
    $text = str_replace('%', '%' $text); 
    $text = str_replace( "'" '&#39', $text); 
    $text = str_replace('(', '(' $text); 
    $text = str_replace(')', ')' $text); 
    $text = str_replace('*', '*' $text); 
    $text = str_replace('+', '&#43', $text); 
    $text = str_replace(',', ',' $text); 
    $text = str_replace('-', '-' $text); 
    $text = str_replace('.', '.' $text); 
    $text = str_replace('/', '&#47', $text); 
    $text = str_replace(':', ':' $text); 
    $text = str_replace('<', '&#60;' $text); 
    $text = str_replace('=', '&#61;' $text); 
    $text = str_replace('>', '&#62;' $text); 
    $text = str_replace('?', '&#63', $text); 
    $text = str_replace('[', '&#91', $text); 
    $text = str_replace('\\', '&#92;' $text); 
    $text = str_replace(']', '&#93;' $text); 
    $text = str_replace('^', '&#94;' $text); 
    $text = str_replace('_', '&#95', $text); 
    $text = str_replace('`', '&#96', $text); 
    $text = str_replace('{', '&#123;' $text); 
    $text = str_replace('|', '&#124;' $text); 
    $text = str_replace('}', '&#125', $text); 
    $text = str_replace('~', '&#126', $text); 

    return $text; 

} 
+0

これらの文字のほとんどは、SQLインジェクションのリスクを増加させません。 mysql_real_escape_string()関数は、処理が必要なすべての文字を処理します。そしてその関数は、あなたの関数が持たない文字セットをどう扱うかを知っています。 –

答えて

11

はあなたがmysql_real_escape_string見てきましたが?

は、するmysql_query()でそれを を置いても安全なようにアカウント に 接続の現在の文字セットを取って、 エスケープ文字列の特殊文字をエスケープします。

+2

あなた自身のことを考え始めると、「自己、これは共通の問題です...」と答えます。答えは通常「ライブラリ関数を使用してください!」です。だから彼らはそこにいるのです。そうでないと確信するまで、ライブラリ関数がより良い、より速く、より安全で安価であることを前提とすべきです。 –

2

その他は、非常にうまく動作するmysql_real_escape_string()を述べています。本当にエンティティに変換する場合はhtmlentities()をご覧ください。それはまだあなたが望むすべての文字を変換していない場合は、あなたもそうのようなstrtr()を使用することができます。

プレースホルダを使用していないのはなぜ
$entities = array(
    '#' => '&#35;', 
    '&' => '&#38;', 
    .... 
); 

$converted = strtr($input, $trans); 
0

?あなたが何かを忘れてしまったり、突然何らかの他の形式(HTML文字エンティティが動作しなくなった場所)で出力したいなどの理由で、何らかのエスケープスキームは動作しません。

ドライバーに依存するだけでなく、より高速なネットワーク転送(文字列の代わりにネイティブint、floatなどとして転送される数値)やプリコンパイル済みステートメントの使用によるネットワーク速度の向上など、プレースホルダーから追加の利点が得られます。

UPDATE明らかに、mysql_インターフェイスはプレースホルダをサポートしていません。これは基本的に、あらゆる種類の配備に安全でないか、適切でないことを意味し、別のドライバを探します。

+0

FWIW、クエリパラメータのプレースホルダ、および一般的なプリペアドステートメントは、最も一般的なMySQL API for PHPではサポートされていません。 –

+1

??うわー、それはひどいです。知っておいてよかった。好奇心のために、どうしてPDOを使っているのはなぜですか? – Trey

1

このような基本的な問題を解決しようとしないでください。既に解決済みです。ただし、基本的なことを学びたいが、本番環境では使用しないでください。クエリをエスケープするは、mysql_real_escape_stringを使用するか、またはパラメータ化されたクエリを使用してを解決し、動作します。自家製のソリューションには、しばしば微妙なバグや専門性があるため、役に立たなくなります。私は今、記事を見つけることができませんが、コーディングホラーのjeff atwood(またはそれはjoelですか?)は、自分のstrip_tags関数を実行しようとした友人について書きました...失敗しました。最近、暗号化についても同じことが言えます。ホームブリュはほとんど常に失敗します。

あなたの方法:
は...あなたの方法は、一方向関数(ハッシュ化に無関係ではないが^^)であるエスケープ古典文字列は、完全に可逆的であるため、当面の作業のために非常に適していません。

0

mysql_real_escape_string()のように、他の人が投稿した解決策に従うことを強くお勧めします。つまり、あなたの機能は鍵となる方法で欠陥があります。あなたが何かを確保している場合、デフォルトのポリシーはで、デフォルトでは拒否されます。つまり、任意の入力または要求が攻撃であると想定し、入力を調べて、何かが確定した場合は、ではなく、の攻撃を許可します。関数の文脈では、入力が既知の許容可能な文字のセットに含まれているかどうかを確認し、他のすべてをエスケープすることを意味します。擬似コード:

function replaceSymbols(text): 
    result = "" 
    for each character c in text: 
     if isalpha(c) or isdigit(c): 
      append c to result 
     else 
      append escape(c) to result 
    return result 
関連する問題