6

多数の AJAX 呼び出しに対してセキュリティ チェックを実行し、記録されているのと同じ IP が要求されているかどうかを確認します。

次の一連のクラス関数を使用して IP を確立しました (IP はロード バランサー経由で取得できるため、長い方法論になります。

    private function IPMask_Match ($network, $ip) {
      $ip_arr = explode('/', $network);
      if (count($ip_arr) < 2) {
        $ip_arr = array($ip_arr[0], null);
      }
      $network_long = ip2long($ip_arr[0]);
      $x = ip2long($ip_arr[1]);
      $mask =  long2ip($x) == $ip_arr[1] ? $x : 0xffffffff << (32 - $ip_arr[1]);
      $ip_long = ip2long($ip);
      return ($ip_long & $mask) == ($network_long & $mask);
    }


    private function IPCheck_RFC1918 ($IP) {
      $PrivateIP = false;
      if (!$PrivateIP) {
        $PrivateIP = $this->IPMask_Match('127.0.0.0/8', $IP);
      }
      if (!$PrivateIP) {
        $PrivateIP = $this->IPMask_Match('10.0.0.0/8', $IP);
      }
      if (!$PrivateIP) {
        $PrivateIP = $this->IPMask_Match('172.16.0.0/12', $IP);
      }
      if (!$PrivateIP) {
        $PrivateIP = $this->IPMask_Match('192.168.0.0/16', $IP);
      }
      return $PrivateIP;
    }


    public function getIP () {
      $UsesProxy = (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) || !empty($_SERVER['HTTP_CLIENT_IP'])) ? true : false;
      if ($UsesProxy && !empty($_SERVER['HTTP_CLIENT_IP'])) {
        $UserIP = $_SERVER['HTTP_CLIENT_IP'];
      }
      elseif ($UsesProxy && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $UserIP = $_SERVER['HTTP_X_FORWARDED_FOR'];
        if (strstr($UserIP, ',')) {
          $UserIPArray = explode(',', $UserIP);
          foreach ($UserIPArray as $IPtoCheck) {
            if (!$this->IPCheck_RFC1918($IPtoCheck)) {
              $UserIP = $IPtoCheck;
              break;
            }
          }
          if ($UserIP == $_SERVER['HTTP_X_FORWARDED_FOR']) {
            $UserIP = $_SERVER['REMOTE_ADDR'];
          }
        }
      }
      else{
        $UserIP = $_SERVER['REMOTE_ADDR'];
      }
      return $UserIP;
    }

問題は、プロキシ経由で操作しているユーザーに問題が発生していることです。誰かがそれがなぜなのかを示すことができますか? 基本的な無料のプロキシをオンラインで使用してエミュレートしましたが、可変 IP などを取得しているようには見えません。そのため、2 つの IP が一致しないと言う理由がわかりません。

4

5 に答える 5

2

残念ながら、問題はほぼ確実にプロキシではありません。ほぼ確実に、静的なパブリックIPルーターであり、サブネットを介してトラフィックをルーティングします。

また、サブネットは巨大になる可能性があります(たとえば、大学で)。

そして、それが本物のプロキシ(最近ではまれです-10歳の技術)によるものであったとしても、プロキシが転送を志願したとしても、それはほぼ確実に192.168。のようなサブネットIPであるため、何の意味もありません。とにかくxx..これは基本的にパブリックIPアドレス(別名スイッチボード)の内部拡張です。

指を交差させてphpipv6を試すことができますPHPでIPv6アドレスを操作するか、さらに賢くてMacアドレスを試すことができますPHPで接続されたクライアントのMACとIPアドレスを取得するにはどうすればよいですか?しかし、どちらも失敗する運命にあります。私の直感は、だまそうとすることです。最善の方法は、基本的にセッションストアにネットワーク共有を使用し、負荷分散されたPHPサーバーがすべてにアクセスし、同じDNSプレフィックスを介してすべてを実行できるようにすることです。または、セッションの集まりを行うためにサードパーティのDNSを設定することもできます。

答えは、広告代理店のような「クッキー」で追跡しない限り、それを行うことはできないということです。

于 2012-10-29T21:16:13.847 に答える
2

最初にプロキシとは何かを説明するので、両者は同じページにいます。

プロキシとは

プロキシは通常、ユーザーの代わりにインターネットにアクセスする単一のコンピューターであり、プロキシは結果をユーザーに送り返します。問題は、その 1 台のコンピューターを使用している他の何百人または何千人もの人々がいる可能性がある場合に発生します。それらはすべて同じ IP アドレスを持っていますが、通常、ヘッダーはユーザーがプロキシ経由であることを示しています。

私が想定しているあなたのスクリプトは(適切に見ずに)、IPとヘッダーが混同されています。

別のソリューション

もっと良い方法があります。セッションを使用し、セッションにキーを保存して、ajax ページにアクセスする前に、最初にメイン サイトにアクセスしたことを確認します。例:

index.php

session_start();
$_SESSION['ajax_ok'] = true;

ajax/username_check.php

session_start();
if (empty($_SESSION['ajax_ok'])) {
    die("You can not access this page...");
}

これにより、最初にメインサイトにアクセスする必要があり、クライアントはほとんどのブラウザーがサポートするセッションもサポートする必要があります。これは、ボットなどが ajax スクリプトを悪用するのを防ぐのに役立ちます。

上記のコードのマングルを使用するよりも、信頼性が高く簡単なソリューション ><

セッションを使用できない場合はどうなりますか?

使用している特定のコンプでセッションを使用できない場合は、別のコンピューターをセットアップするか、(php が提供するコールバックを使用して) セッション ハンドラーを書き直すか、ファイル システムを使用する代わりにセッション用のデータベースのようなものを使用することができます。 ? セッションでも使用できる、Web サイトで使用する何かが必要です。ロード バランサ ファイル ベースのセッションがある場合などは、通常、いずれにせよ機能しないため、セッションを変更して上記のような別のものを使用することをお勧めします。

于 2012-10-25T20:33:39.143 に答える
1

友人がこれを特定しました。基本的に一部のプロキシは、X_FORWARDED_FOR をコンマ区切りの値またはコンマ区切りとスペースで返すことができます。

修正するには:-

後:

foreach ($UserIPArray as $IPtoCheck) {

次の行を追加します。

$IPtoCheck = trim($IPtoCheck);

並べ替えました。

于 2012-10-26T13:09:23.637 に答える
0

あなたのソリューションがセキュリティのために何かを行うかどうかについて話し合いたいと思います.

$_SERVER['REMOTE_ADDR'] は偽造できません。これは、アクセスする IP アドレスが使用されるため、Web サーバーによって設定されます。応答はすべてこのアドレスに送られます。

$_SERVER['HTTP_FORWARDED_FOR'] と $_SERVER['HTTP_CLIENT_IP'] は、Web サーバーに送信される HTTP ヘッダーであるため、簡単に偽造できます。これらのヘッダーを省略するように構成されている場合、プロキシと通信していることもわかりません。クライアントがこれらのヘッダーを挿入することを決定した場合、プロキシと話しているわけではないことを知っていますか。

IP アドレス FORGED に基づくフィルタリングは実際には役に立ちませんが、これは達成したいものに大きく依存します。これは、詳細に入るまで不明のままです。

あたりを見回すと、PHP の Suhosin パッチと拡張機能に出くわします。これは、セッションと Cookie のコンテンツを暗号化する機能です。暗号化キーは、いくつかの静的キーを使用して構築されますが、HTTP ユーザー エージェントや要求元の IP アドレスの一部などを追加します。注: 実際に要求を行うために使用される IP、つまり、使用されている場合はプロキシです。信頼できる情報のみ。

ユーザーが複数の要求に対して IP アドレスを変更するプロキシ クラスターを使用しないことがわかっている場合を除き、完全な IP アドレスを使用することはあまり良い考えではないと主張することができます。そのため、通常は IP の一部のみが使用されるか、まったく使用されません。

ただし、HTTP ユーザー エージェントは、固有の情報の優れたソースです。はい、偽造できますが、それはまったく問題ではありません。なぜなら、同じソースからのリクエストのみを許可したい場合、ユーザー エージェント文字列は時間の経過とともに変化しないと仮定するのが有効であるためです。他のユーザーの束。したがって、送信されたすべての HTTP ヘッダーを見るだけで、ブラウザーのほぼ一意のフィンガープリントを生成できることを示す統計があります。これは、すべてのユーザーが、accept-content ヘッダーなど、何かを変更するさまざまな拡張機能をインストールするためです。

動作するコードを提供することも、この回答のいずれかが当てはまるかどうかをあなたの質問から判断することもできませんが、特に偽造できる場合は、IP 情報を使用しないことをお勧めします。これは、すべてのクライアントが同じインターフェイス上であっても複数のアクティブなアドレスを持ち、それらはすべてランダムに生成され、後で再び発生する可能性が非常に低い IPv6 について考えると、さらに有効です。(もちろん、これは決して IPv6 でホストするつもりがない場合には当てはまりませんが、ある時点でユーザーがいなくなるでしょう。)

于 2012-10-31T20:36:22.127 に答える
0

問題は、プロキシ経由で操作しているユーザーに問題が発生していることです。誰かがそれがなぜなのかを示すことができますか? 基本的な無料のプロキシをオンラインで使用してエミュレートしましたが、可変 IP などを取得していないようです。そのため、2 つの IP が一致しないと言う理由がわかりません。

解析コードHTTP_X_FORWARDED_FORはカンマで爆発しますが、セパレータは「カンマスペース」である可能性があります。その場合、RFC 1918 チェックは失敗します。一部のプロキシはスペースを追加しませんが、標準ではスペースを使用します。

http://en.wikipedia.org/wiki/X-Forwarded-For

フィールドの一般的な形式は次のとおりです。

X-Forwarded-For: client, proxy1, proxy2

ここで、値はコンマとスペースで区切られた IP アドレスのリストで、一番左が元のクライアントであり、要求を通過した後続の各プロキシは、要求を受信した IP アドレスを追加します。この例では、要求は proxy1、proxy2、および proxy3 を通過しました (proxy3 は要求のリモート アドレスとして表示されます)。

したがって、explode区切り記号を ", " に変更するか、preg_split",\s*" を区切り記号として使用し、両方のケースをカバーする必要があります。

次に、問題は、AJAX で呼び出しを行っているページを AJAX 呼び出し自体に認証することです。

Cookie ベースのセッションを使用したくない場合 (これが最善の方法です)、nonceを使用してこれを試すことができます。つまり、ページを生成するときに、一意の ID を発行して HTML コードに挿入すると、AJAX コードが ID を復元して AJAX サーブレットに戻します。後者は、ここで詳しく説明されているように Access-Control-Request に追加するか、単にリクエストにデータを追加することができます。

于 2012-10-30T23:33:48.727 に答える