PHP プログラマ、特に初心者は、インターネットの危険性について常にほとんど知識がありません。ハッカーがどのように侵入し、侵入し、脆弱性をアップロードし、SQL インジェクションやクロススクリプト攻撃を行うのかがわかりません。もっと。最も基本的な予防策として、外部からの送信に注意を払い、ファイアウォールに対処するための最初のセキュリティ メカニズムを作成する必要があります。
ルール 1: 外部データや入力を決して信頼しない
Web アプリケーションのセキュリティについて最初に認識しなければならないのは、外部データを信頼すべきではないということです。外部データには、プログラマが PHP コードに直接入力しないデータが含まれます。他のソースからのデータ (GET 変数、フォーム POST、データベース、構成ファイル、セッション変数、Cookie など) は、セキュリティを確保するための手順が講じられるまで信頼できません。
たとえば、次のデータ要素は PHP で設定されているため安全であると考えられます。
リスト 1. 安全で完璧なコード
コードをコピーします コードは次のとおりです:
$myUsername = 'tmyer'
$arrayarrayUsers = array('tmyer', 'tom', 'tommy ');
define("GREETING", 'Hello there' . $myUsername);
ただし、次のデータ要素には欠陥があります。
リスト 2. 安全でない欠陥のあるコード
コードをコピーする コードは次のとおりです。
$myUsername = $_POST['username'] //tainted! myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); なぜ最初の変数 $myUsername には欠陥があるのか? フォーム POST から直接取得されるためです。ユーザーはこの入力フィールドに任意の文字列を入力できます。これには、ファイルを駆除したり、以前にアップロードしたファイルを実行したりする悪意のあるコマンドも含まれます。 「A ~ Z の文字のみを受け入れるクライアント側 (JavaScript) フォーム検証スクリプトを使用すれば、この危険を回避できないのですか?」と疑問に思われるかもしれません。はい、これは常に有益なステップですが、後で説明するように、誰でも任意のフォームを自分のマシンにダウンロードして変更し、必要なものを再送信できます。
解決策は簡単です。$_POST['username'] でサニタイズコードを実行する必要があります。これを行わないと、(配列や定数などで) $myUsername を使用するたびに、これらのオブジェクトが汚染される可能性があります。ユーザー入力をサニタイズする簡単な方法は、正規表現を使用して処理することです。この例では、文字のみが受け入れられることが想定されています。文字列を特定の文字数に制限したり、すべての文字を小文字にすることを要求したりすることも良いアイデアかもしれません。
リスト 3. ユーザー入力を安全にする
コードをコピーします
コードは次のとおりです。
$myUsername = cleanInput($_POST['username']) //clean! = array ($myUsername, 'tom', 'tommy'); //clean! define("GREETING", 'hello there' . $myUsername); //clean! strto lower( $input); $clean = preg_replace(“/[^a-z]/”, “”, $clean); $clean = substr($clean,0,12); return $clean; >
ルール 2: セキュリティの実装を困難にする PHP 設定を無効にする
ユーザーの入力を信頼できないのと同じように、マシン上での PHP の構成方法も信頼すべきではないことも知っておく必要があります。たとえば、register_globals が無効になっていることを確認してください。 register_globals が有効な場合、$variable を使用して GET または POST 文字列を同じ名前に置き換えるなどの不注意な行為が可能になります。この設定を無効にすると、PHP は正しい名前空間の正しい変数を参照するように強制します。フォーム POST から変数を使用するには、$_POST['variable'] を引用符で囲む必要があります。こうすることで、この特定の変数を Cookie、セッション、または GET 変数と間違えることがなくなります。
ルール 3: 理解できない場合、保護することはできません
一部の開発者は、奇妙な構文を使用したり、ステートメントを非常にコンパクトに編成して、短くても曖昧なコードを形成します。このアプローチは効率的かもしれませんが、コードが何をしているのかを理解していないと、コードを保護する方法を決定できません。たとえば、以下の 2 つのコードのうち、どちらが好きですか? = (isset($_POST ['ユーザー名']) ? $_POST['ユーザー名']:”);
//難読化されていないコード
$input = ”; isset($_POST['ユーザー名']){ $input = $_POST ['ユーザー名'];
}else{
$input = ”;
2 番目のより明確なコード スニペットでは、$input に欠陥があり、安全に処理する前にクリーンアップする必要があることが簡単にわかります。
ルール 4: 「多層防御」は新しい魔法です このチュートリアルでは、フォームを処理する PHP コードで必要な措置を講じながら、オンライン フォームを保護する方法を例を使用して説明します。同様に、PHP 正規表現を使用して GET 変数が完全に数値であることを確認する場合でも、SQL クエリでエスケープされたユーザー入力が使用されることを確認する手順を実行できます。多層防御は良いアイデアであるだけでなく、深刻な問題に巻き込まれないようにします。基本的なルールについて説明したので、最初の脅威である SQL インジェクション攻撃を見てみましょう。
◆SQL インジェクション攻撃を防ぐ
SQL インジェクション攻撃では、ユーザーはフォームまたは GET クエリ文字列を操作して、データベース クエリに情報を追加します。たとえば、単純なログイン データベースがあるとします。このデータベースの各レコードには、ユーザー名フィールドとパスワード フィールドがあります。ユーザーがログインできるようにするログイン フォームを作成します。
コードをコピーします コードは次のとおりです:
/title>
コードは次のとおりです:
$ ok = 0; $username = $_POST['user']; $pw = $_POST['pw']; $sql = “username=' のユーザーから count(*) を選択します。”ユーザー名 ."' およびパスワード = '"。$pw."' 制限 1"; ctr == 1){ //アプリケーションに入っても大丈夫です! }
if ($okay){
$_SESSION['loginokay'] = true; Index .php");
}else{
header("login.php");
}
?>
このコードは問題ありませんね? 世界中の数百 (場合によっては数千) の PHP /MySQL サイトは、このようなコードを使用します。何が問題なのでしょうか? そうですね、「ユーザー入力は信頼できない」ということを思い出してください。ここではユーザーからの情報はエスケープされないため、アプリケーションは脆弱なままになります。具体的には、あらゆる種類の SQL インジェクション攻撃が発生する可能性があります。たとえば、ユーザーがユーザー名として foo を入力し、パスワードとして ' または '1'='1 を入力すると、実際には次の文字列が PHP に渡され、クエリが MySQL に渡されます。以下のように:
$sql = “select count(*) as ctr from users where username=
'foo' かつpassword=” or '1'='1' limit 1''?> ;
このクエリは常に 1 のカウントを返すため、ハッカーはパスワード文字列の末尾に悪意のある SQL を挿入することでこの問題を解決できます。これは、組み込みの mysql_real_escape_string() 関数がラッパーとして機能します。この関数は、文字列内の文字をエスケープし、アポストロフィなどの特殊文字を渡すことを不可能にし、それを MySQL で操作できるようにします。コード
コードは次のとおりです:
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = "ユーザーから count(*) を選択しますここで、ユーザー名 = '".mysql_real_
_string($username)."' およびパスワード ='".mysql_real_escape_string($pw)."'
制限 1";
$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){
if ($data->ctr == 1){ //
$okay = 1 を入力しても問題ありません! {
$_SESSION['loginokay'] = true;
header("index.php");
else{
?> mysql_real_escape_string() を使用します。ユーザー入力のラッパーとして、ユーザー入力への悪意のある SQL インジェクションを回避できます。ユーザーが SQL インジェクションを介して不正なパスワードを渡そうとすると、次のクエリがデータベースに渡されます:
コードをコピー
コードは次のとおりです:
select count(*) as ctr from users whereユーザー名 = 'foo' およびパスワード =
'' または '1'='1'' 制限 1''
http://www.bkjia.com/PHPjc/322437.html
www.bkjia.com
true
http://www.bkjia.com/PHPjc/322437.html
技術記事
PHP プログラマー、特に初心者は、インターネットの危険性についてあまりにも知識が乏しいため、外部からの侵入に対して無力であることがよくあります...。