6

私はhttps://github.com/lemmingzshadow/php-websocket/を使用しています

一部のドメインを許可できlocalhostます。ローカル サーバーを指すドメインを許可しました。しかし、自分のコンピューターにサーバーを持っている他の誰かが、自分の localhost サーバーのスクリプトを使用して (私のドメインを介して) 私の websocket に接続できるのではないかと思います。

関連するコードは次のとおりです。

-> server/server.php

$server->setAllowedOrigin('localhost');
$server->setAllowedOrigin('mydomain.com');

-> サーバー/lib/WebSocket/Connection.php

// check origin:
if($this->server->getCheckOrigin() === true)
{
    $origin = (isset($headers['Sec-WebSocket-Origin'])) ? $headers['Sec-WebSocket-Origin'] : false;
    $origin = (isset($headers['Origin'])) ? $headers['Origin'] : $origin;
    if($origin === false)
    {
        $this->log('No origin provided.');
        $this->sendHttpResponse(401);
        stream_socket_shutdown($this->socket, STREAM_SHUT_RDWR);
        $this->server->removeClientOnError($this);
        return false;
    }

    if(empty($origin))
    {
        $this->log('Empty origin provided.');
        $this->sendHttpResponse(401);
        stream_socket_shutdown($this->socket, STREAM_SHUT_RDWR);
        $this->server->removeClientOnError($this);
        return false;
    }

    if($this->server->checkOrigin($origin) === false)
    {
        $this->log('Invalid origin provided.');
        $this->sendHttpResponse(401);
        stream_socket_shutdown($this->socket, STREAM_SHUT_RDWR);
        $this->server->removeClientOnError($this);
        return false;
    }
}

-> サーバー/lib/WebSocket/Server.php

public function checkOrigin($domain)
{
    $domain = str_replace('http://', '', $domain);
    $domain = str_replace('https://', '', $domain);
    $domain = str_replace('www.', '', $domain);
    $domain = str_replace('/', '', $domain);

    return isset($this->_allowedOrigins[$domain]);
}

public function setAllowedOrigin($domain)
{
    $domain = str_replace('http://', '', $domain);
    $domain = str_replace('www.', '', $domain);
    $domain = (strpos($domain, '/') !== false) ? substr($domain, 0, strpos($domain, '/')) : $domain;
    if(empty($domain))
    {
        return false;
    }
    $this->_allowedOrigins[$domain] = true;     
    return true;
}

編集:

たぶん、私は十分に明確ではありませんでした。誰でも Websocket に接続できるようにしたいのですが、それは自分のドメイン (またはローカルホスト) にいる場合に限られます。たとえば、AJAX の同じオリジン ポリシーのようなものです。

私の心配は、ローカルホストを許可すると、他のコンピューターの他のすべてのローカルホストも許可される可能性があることです。

4

3 に答える 3

1

確認したい場合は、分析してIPチェックを追加する必要があります$_SERVER["REMOTE_ADDR"]。チェックされているオリジンは、簡単に偽造できるクライアントから提供されたテキスト値です。

if (!in_array($_SERVER["REMOTE_ADDR"], array("127.0.0.1", "ip.of.dom.ain")) exit;

IPアドレスをハードコーディングしたくない場合、または頻繁に変更される場合は、gethostbynameを使用して、このようにドメインのIPアドレスを取得できます。これにより、DNSでドメインを照会する必要がある場合に各要求に遅延が追加され、DNSがダウンしたときにタイムアウトが発生することに注意してください。(もちろん、次のコードは最適化できます)

$allowed_origins = array('localhost', 'mydomain.com');
$allowed_ips = array();
foreach ($allowed_origins as $domain) {
    $server->setAllowedOrigin($domain);
    $allowed_ips[] = gethostbyname($domain);
}
if (!in_array($_SERVER["REMOTE_ADDR"], $allowed_ips)) exit; 

おそらくこれを行う適切な方法は、Webサーバーを介してリソースを保護し、許可するIPアドレスからの要求のみを受け入れるようにすることです(Apacheでの拒否またはnginxでの拒否を参照)。

于 2012-12-30T14:49:22.427 に答える
1

自分の localhost だけを許可したいときにすべての localhost からの接続を許可することに不安がありましたが、別の質問カナカが次のように述べていることがわかりました。

明確にするために、妥協のない適切に動作するブラウザーで実行されている Javascript は、ページが読み込まれた元のサイトの値を保持する Sec-WebSocket-Origin の値に影響を与えることはできません (サーバーが特定の発信元ポイントのみを許可できるようにします)。ただし、Node.js で WebSocket クライアントとして Javascript を実行している場合は、origin の値を任意の値に設定できます。CORS セキュリティは、サーバーではなく、ブラウザー ユーザーの安全のためのものです。サーバーを保護するには、他のメカニズムが必要です。

次に、私のオリジン チェック コードはまったく安全ではありません。誰かが自分のローカルホストを使用して私の WebSocket に接続するための十分な知識を持っている場合、Origin ヘッダーを変更できる可能性が高いため、すべてのローカルホストをすべて許可するかどうかは問題ではありません。

于 2013-01-01T23:46:45.340 に答える