web-dev-qa-db-ja.com

setRequestHeaderを使用してxmlhttprequestを作成しているときに、CookieとSet-Cookieヘッダーを設定できないのはなぜですか?

SetRequestHeaderを使用してcookieヘッダーを設定できないのはなぜかと思っていました。特定の理由がありますか、それともブラウザ自体によって追加されたため、これらのヘッダーは無効になっていますか?セキュリティ上の問題はありますか?

-編集

私はnode.jsに取り組んでおり、xmlhttprequestモジュールを使用しました。テストコードは次のとおりです。

var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.withCredentials = true;
xhr.setRequestHeader('Cookie', "key=value");
xhr.send(null);

ここでは、node.js' xmlhttprequestがcookie-headerを明示的に追加しないように(ブラウザーが行うように)cookie-headerを設定する必要があります。そうしようとすると、xmlhttprequestはエラー「Refused to set unsafe header」を返します。

パッチを見つけて、Cookieヘッダーを正常に送信できましたが。しかし、cookie-headerの設定が無効になっているのはなぜだろうと思っていましたか?私が読んだところはどこでも、データの整合性とセキュリティに必要であることがわかりましたが、この場合にどのセキュリティが侵害される可能性があるかはどこにも言及されていません。このデータ整合性の問題が、パッチを適用した場合、node.jsアプリケーションにも当てはまるかどうかを評価したいと思います。

31
jsist

working draft を経て見つけたはずだと確信しています

上記のヘッダーは、ユーザーエージェントによって制御され、トランスポートのこれらの側面を制御します。

まず、理解する必要があります。これらは、異なるブラウザ間の機能の相互運用性のガイドラインとして機能する標準です。ブラウザには必須ではないため、ブラウザはさまざまな理由でこの標準への準拠レベルが異なります。

第二に、技術的に言えば、ユーザーエージェントをエミュレートし、プログラムをブラウザーとして扱い、前述の標準に従ってこれらの値を非常にうまく設定できます。

最後に、ヘッダーの上書きを許可しない、またはContent-LengthCookieなどの特定のフィールドにヘッダーを設定する意図はsecure design approachである。 HTTP Request smuggling を阻止するか、少なくとも阻止しようとします。

23
Manish Singh

この動作を無効にできます:

var xhr = new XMLHttpRequest();
xhr.setDisableHeaderCheck(true);
xhr.open(...);
...
14
robertklep

よく知られているように、ブラウザでは、第三者がユーザーセッション(または他のデータ)を盗むのを防ぐために、Cookie(他のプロパティも含む)を慎重に管理する必要があります。これはブラウザーの問題であり、任意のJavascriptを実行するWebサイトにアクセスするという制御されない性質です。

もちろん、任意のコード実行のこのリスクは、あなたが計画した他のコードを実行する可能性のある記述したスクリプトのみを実行するため、node.jsのリスクは低いか、またはリスクがありません。

Driverdanの XMLHttpRequest.js のソースコードを見ると、次のことがわかります。

 // These headers are not user setable.   
 // The following are allowed but banned in the spec:   
 // * user-agent   
 var forbiddenRequestHeaders = [
    "accept-charset",
    "accept-encoding",
    "access-control-request-headers",
    "access-control-request-method",
    "connection",
    "content-length",
    "content-transfer-encoding",
    "cookie",
    "cookie2",
    "date",
    "expect",
    "Host",
    "keep-alive",
    "Origin",
    "referer",
    "te",
    "trailer",
    "transfer-encoding",
    "upgrade",
    "via"   ];

これは、node.jsに使用されるこのスクリプトに制限が特に適用される理由に関する特定の質問に答えます。コーダーは、おそらくnode.jsで必要なセキュリティ予防策ではないと感じているにも関わらず、仕様に(可能な限り厳密に)従いました。それでも、このデフォルトのセキュリティレベルは簡単に変更できます。

Robertklepが指摘したように、setDisableHeaderCheckメソッドを使用して、このデフォルトの予防策を無効にできます。そして、はい、この最後のポイントは、あなたの質問の中であなたが述べたので、あなたの質問の答えに答えるか、著しく貢献します:

I have found a patch and successfully able to send the cookie-header

そのパッチは必要ないことがわかりました。

がんばろう!

8
Todd

はい、データの整合性とセキュリティのために必要です。これを理解するには、HTTPリクエストメソッドでのCookieの役割を理解する必要があります。

Cookieは、ユーザー、ブラウザ、接続などを識別する上で重要であり、Webブラウザに保存されます。 JavaScriptでは、Cookieを操作できますが、ブラウザ上のすべてのCookieを操作することはできません。 HTTP cookies を参照してください。これらはブラウザによってのみ設定されるため、ユーザーは(JavaScriptを介して)誤用することはできません。

サポートされているブラウザーでは、HttpOnlyセッションCookieはHTTP(またはHTTPS)要求を送信するときにのみ使用されるため、他の非HTTP API(JavaScriptなど)からのアクセスが制限されます。

Xmlhttprequestを送信すると、HttpOnly Cookieが読み取られ、Cookieヘッダーを介してサーバーに送信されます。 xhr.setRequestHeader('Cookie', "key=value");を実行すると、サーバーに送信されたCookieを改ざんしようとしています。 setRequestHeaderは追加のkey=valueを追加し、送信されたCookieの整合性を損なう可能性があります。

これらは、ユーザー(セッション、メールアカウント、またはアカウント)を認証するためにサーバーによって使用されます。これにより、サーバーはクッキーの誤用を防ぎ、サーバーにアクセスできます。

4
user568109

ドキュメントには、これがデータの整合性を保護するために行われていることが記載されています。 http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method

上記のヘッダーは、ユーザーエージェントによって制御され、トランスポートのこれらの側面を制御します。これにより、データの整合性がある程度保証されます。 Sec-で始まるヘッダー名は、XMLHttpRequestに由来しないことが保証されている新しいヘッダーを作成できるように設定することはできません。

2

次の要点を使用して、この問題を解決できました。
https://Gist.github.com/killmenot/9976859

元のアイデアはここから取られます:
https://Gist.github.com/jfromaniello/4087861

私はいくつかの問題に直面しました:

  1. Source Gistは時代遅れであり、私にとってはうまくいきません。たとえば、「リクエスト」ライブラリAPIが変更されました。
  2. Socket.io-clientの「xmlhttprequest」ライブラリを使用して、socket.io-clientと同じレベルにインストールしないでください。
  3. 元の「socket.io-client」(0.9.16)は、「setDisableHeaderCheck」メソッドをサポートしない「xmlhttprequest」(1.4.2)を使用します(1.6.0はサポートします)。そこで、フォークを作成して使用します https://github.com/intspirit/socket.io-client/tree/0.9.16+201404081204

socket.io-client(1.0.0-pre)は、xmlhttprequestの正しいバージョンを使用するengine.io-clientを使用します。将来的には、フォークの代わりに1.0.0バージョンを使用し、「xhr-polling」トランスポートを指定し、XMLHttpRequestのモックを元のGistと同じように指定します。

1