web-dev-qa-db-ja.com

セキュアCookieとhttps / httpの混合サイト使用

多くのサイトがhttpsをサポートしているように見えますが、セキュアCookieは使用していません。サイトでセキュアCookieを使用するようにしますが、代わりにhttpを使用して一部のコンテンツにアクセスできるようにします。

これを行う賢明な方法は、実際のセッション用の安全なCookieと、ユーザーがログインしているかどうかを示すフラグである非安全なCookieを持つことです(ヘッダーに異なるものを表示するなど)ログインリンクの代わりにログアウトリンク)。このCookieには「実際の」セッション情報は含まれず、サイトのhttp部分でログアウトしているユーザーと比較して、ログインしているユーザーに対してサイトがわずかに異なるページを表示できるようにするためです。

サイト全体をhttpsにすることは別のオプションですが、これはプレーンなhttpよりもかなり遅いように見えるため、理想的ではありません。

サイトでこの種のセットアップを使用せず、安全なCookieを使用しないのはなぜですか?クッキーの盗難の可能性は、最近では安全なクッキーを必要としているようです。同じことを達成するためのより良い方法はありますか?

51
David Gardner

あなたが提案する解決策は、許可されていない人々が「ログインしているように」サイトの非セキュア(http)部分を見ることができることを気にしない限り、それが機能するようです。サイトのhttp部分には機密情報が含まれておらず、ログインしているユーザーとログインしていないユーザーの唯一の違いはヘッダーに無害なものがあることです。

頻繁に使用されない理由は、次のいずれかです。

  • このシナリオは、あまり一般的ではないかもしれません。通常、サイトの一部を安全にするために十分な注意を払う場合は、ログインセッションをその安全な部分だけに制限するか、サイト全体で常にHTTPS(Paypalなど)を使用するようにします。
  • 安全で、これ以上の機能を備えた既存のソリューションが存在します。たとえば、HTTPSログインフォームで誰かにログインし、HTTPに戻すときにセッションを維持します。 OpenIDはその一例です。また、flickrまたはgmailも考えてください。サインインページは常にHTTPSですが、セッションが開始されると、セッションを安全に維持しながらHTTPに移行します。

更新(2014年8月)

2009年にこれを書き直して以来、ログイン画面に安全な接続を確立し、ログイン後にHTTPに戻すという習慣はほとんどなくなりました。

HTTPSをサイド全体で使用するオーバーヘッドは、もはや大したことではありません。 Googleが開発した新しいSPDYプロトコル(現在はHTTP/2に進化)は、クロスブラウザおよび主要なWebサーバーでサポートされ、HTTPSの速度を向上させます。

最後に、コメントの書き込み、写真のアップロードなど、認証にとって重要ではないアクションであっても、プライバシーはこれまで以上に重要であると考えられています。

Googleは最近、HTTPSのみのサイトが検索エンジンのランキングで利益を得るようになると言っています。

31
thomasrutter

セキュリティの観点から、セキュリティで保護されていない接続を介して送信されたコンテンツを決して信頼しないでください。そのため、そのCookieの盗難または悪用のコストがほぼゼロの場合にのみ、暗号化されていない接続を介して送信されたCookieを使用しても安全です。

それを念頭に置いて、ほとんどのサイトは、データがチャネル間で「漏洩」しないように設計されています。結局のところ、暗号化側からのデータは通常特権であるため、通常のチャネルでは許可されませんが、非暗号化チャンネルからのデータは潜在的になりすまし、信頼されるべきではありません。

これらの一般化に当てはまらないデータがある場合は、お好きなように自由に使用してください。

11
tylerl

HTTPを介したセッションCookieの転送は、しばらくの間私を悩ませてきました。あなたが説明したテクニックは、ログインしたユーザーがログインしたかのようにHTTPページを閲覧できるようにする一方で、Cookieを保護する唯一の正しい方法だと思います。しかし、これが実装されることはめったにありません。

サイトがこの種のセットアップを使用せず、安全なクッキーを使用しないのはなぜですか?

採用されなかった主な理由は、 リスク管理

  • 盗聴によるセッショントークンの盗難は、たとえばクロスサイトスクリプティング(脆弱性があると仮定)。ネットワーク(ユーザーのLANまたはISPなど)にアクセスする必要があります。したがって、リスクベースの優先順位付けによると、開発者はXSSの問題に最初に取り組む必要があります。これは、XSSがはるかに大きな攻撃対象領域を提供するためです(攻撃の確率がはるかに高くなります)。
  • CSRFとUIの修正(別名クリックジャッキング)についても同じことが言えます。
  • ハッキングされたセッションのビジネスへの影響が大きい場合(たとえば、後でWebショップで使用するためにクレジットカードを保存する場合)、サイト全体をHTTPSに制限する方がよい場合があります。

もう1つの理由は、使いやすさの懸念です。提案されたスキームでは、1人のユーザーの2つの同時セッションを効果的に管理しています。これは、ログイン中のフラグが安全でないセッションに保存されている唯一の状態である限り、簡単です。両方のセッション内から言語や国などの設定も変更できる場合は、(実装または使用するために)面倒になる可能性があります。

同じことを達成するためのより良い方法はありますか?

から The Web Application Hacker's Handbook

HTTP Cookieを使用してトークンを送信している場合、これらのトークンにsecureのフラグを付けて、ユーザーのブラウザーがトークンをHTTPで送信しないようにする必要があります。可能であれば、ヘルプページや画像などの静的コンテンツを含むアプリケーションのすべてのページにHTTPSを使用する必要があります。

真剣に、サイト全体がHTTPSを使用するようにします。数年前には、主にCDNがHTTPSサポートを提供していないため、これは実現不可能でした。ただし、今日の主な問題は、開発コストと運用コストのバランスをとることです。

9
Pankrat

推奨されるプラクティスは、サイト全体にSSLを強制することです。ただし、HTTPとHTTPSを選択して選択できると便利な場合があります。

@Dsavid Gardnerと同様のシナリオに遭遇しました。私の会社は、サードパーティベンダーを使用してサイトのストア部分を管理し、そのストアはサブドメイン " https://store.mysite.com 」。 15年分のビデオコンテンツがあり、現在のビデオ管理ベンダーは、ビデオがSSLに埋め込まれると中断します。 (私はそれがHTTPドメインからリソースを引き込んでいると推測していますが、それは別の日に別の問題です)

確かに、SSLを購入し、2つのサードパーティベンダーのデバッグプロセスを経て、データベース全体で検索および置換(または.htaccessファイルハックですが、私は脱線します)を行ってHTTPリソースを修正できます。ヘッダーにメッセージ「Welcome 'YourName'」を含めることができるようにするためのリンクですが、それは単にやり過ぎのようです。

これは、すでに設定されている安全なCookieに基づいてサイト全体の安全でないCookieを設定する簡単なJavascriptソリューションです。

まず、 いくつかのjavascript cookie関数を取得しました 。先に進み、このコードをサイトの安全な部分に配置します。

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)===' ') { 
            c = c.substring(1,c.length);
        }
        if (c.indexOf(nameEQ) === 0) {
            return c.substring(nameEQ.length,c.length);
        }
    }
    return null;
 }
 function setCookie(cname, cvalue, exdays) {
    var d = new Date();
    d.setTime(d.getTime() + (exdays*24*60*60*1000));
    var expires = "expires="+d.toUTCString();

    /* Note, the W3 documents where I got this code didn't include the
    option to set the domain. I added this and it allows the cookie 
    to be shared across sub-domains. Be sure not to add "www" */
    document.cookie = cname + "=" + cvalue + "; " + expires + "; domain=.yourdomain.com";
 }
 /*Now we check our cookies on our secure server to find out if the user is
 logged in or not. In my case, the First Name is stored as a cookie. */
 var firstNameCookie = readCookie("the-secure-cookie-name");
 //
 if(!firstNameCookie){
    /* If the cookie doesn't exist, then the person isn't logged in. Add 
    conditional logic here if you'd like (such as deleting any current 
    logged in cookies from the HTTP portion of the site) */
 }
 else {
    /* otherwise, we have a successful login. By grabbing the cookie via 
    this javascript resting on the secure server, we haven't compromised our 
    security. However, if we set a cookie with javascript right now, it 
    won't be a secure cookie by default and we'll have access to it with 
    HTTP on the subdomain */
    setCookie("HTTPfirstName", firstNameCookie, 1.5);
 }

 */The clients first name is now accessible across subdomains in the cookie
  entitled "HTTPfirstName" */

この場合、HTTPサーバーに漏えいしたのはクライアントの名だけです。ただし、さらにセキュリティが必要な場合は、特定のCookie(つまり「firstNameCookie」)にHTTPリクエストのみがアクセスできるようにサーバー設定を設定し、保護の層を追加できます ここでそれを行う方法を学ぶことができます

確かに、これは最も理想的なソリューションではありません。将来的には、サイト全体にSSLを実装する予定ですが、その間にSSLを置き換える簡単なjavascript関数を用意することは間違いなくあります。

1
Lucas