Bug 692067: Make WebSockets trigger content policies. r=smaug,dveditz

This commit is contained in:
Kyle Huey 2011-12-07 18:19:43 -05:00
parent 79b4aba51f
commit 95e592ecec
6 changed files with 35 additions and 4 deletions

View File

@ -139,6 +139,7 @@ NS_CP_ContentTypeName(PRUint32 contentType)
CASE_RETURN( TYPE_DTD );
CASE_RETURN( TYPE_FONT );
CASE_RETURN( TYPE_MEDIA );
CASE_RETURN( TYPE_WEBSOCKET );
default:
return "<Unknown Type>";
}

View File

@ -137,6 +137,11 @@ interface nsIContentPolicy : nsISupports
*/
const unsigned long TYPE_MEDIA = 15;
/**
* Indicates a WebSocket load.
*/
const unsigned long TYPE_WEBSOCKET = 16;
/* Please update nsContentBlocker when adding new content types. */
//////////////////////////////////////////////////////////////////////

View File

@ -102,6 +102,7 @@ function ContentSecurityPolicy() {
csp._MAPPINGS[cp.TYPE_MEDIA] = cspr_sd.MEDIA_SRC;
csp._MAPPINGS[cp.TYPE_FONT] = cspr_sd.FONT_SRC;
csp._MAPPINGS[cp.TYPE_XMLHTTPREQUEST] = cspr_sd.XHR_SRC;
csp._MAPPINGS[cp.TYPE_WEBSOCKET] = cspr_sd.XHR_SRC;
/* These must go through the catch-all */

View File

@ -68,9 +68,12 @@ nsNoDataProtocolContentPolicy::ShouldLoad(PRUint32 aContentType,
// Don't block for TYPE_OBJECT since such URIs are sometimes loaded by the
// plugin, so they don't necessarily open external apps
// TYPE_WEBSOCKET loads can only go to ws:// or wss://, so we don't need to
// concern ourselves with them.
if (aContentType != TYPE_DOCUMENT &&
aContentType != TYPE_SUBDOCUMENT &&
aContentType != TYPE_OBJECT) {
aContentType != TYPE_OBJECT &&
aContentType != TYPE_WEBSOCKET) {
// The following are just quick-escapes for the most common cases
// where we would allow the content to be loaded anyway.

View File

@ -76,6 +76,8 @@
#include "mozilla/Preferences.h"
#include "nsDOMLists.h"
#include "xpcpublic.h"
#include "nsContentPolicyUtils.h"
#include "nsContentErrors.h"
using namespace mozilla;
@ -1276,6 +1278,9 @@ nsWebSocket::Init(nsIPrincipal* aPrincipal,
rv = ParseURL(PromiseFlatString(aURL));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> originDoc =
nsContentUtils::GetDocumentFromScriptContext(mScriptContext);
// Don't allow https:// to open ws://
if (!mSecure &&
!Preferences::GetBool("network.websocket.allowInsecureFromHTTPS",
@ -1283,8 +1288,6 @@ nsWebSocket::Init(nsIPrincipal* aPrincipal,
// Confirmed we are opening plain ws:// and want to prevent this from a
// secure context (e.g. https). Check the security context of the document
// associated with this script, which is the same as associated with mOwner.
nsCOMPtr<nsIDocument> originDoc =
nsContentUtils::GetDocumentFromScriptContext(mScriptContext);
if (originDoc && originDoc->GetSecurityInfo())
return NS_ERROR_DOM_SECURITY_ERR;
}
@ -1302,6 +1305,23 @@ nsWebSocket::Init(nsIPrincipal* aPrincipal,
AppendUTF16toUTF8(protocolArray[index], mRequestedProtocolList);
}
// Check content policy.
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_WEBSOCKET,
mURI,
mPrincipal,
originDoc,
EmptyCString(),
nsnull,
&shouldLoad,
nsContentUtils::GetContentPolicy(),
nsContentUtils::GetSecurityManager());
NS_ENSURE_SUCCESS(rv, rv);
if (NS_CP_REJECTED(shouldLoad)) {
// Disallowed by content policy.
return NS_ERROR_CONTENT_BLOCKED;
}
// the constructor should throw a SYNTAX_ERROR only if it fails to parse the
// url parameter, so we don't care about the EstablishConnection result.
EstablishConnection();

View File

@ -68,7 +68,8 @@ static const char *kTypeString[] = {"other",
"objectsubrequest",
"dtd",
"font",
"media"};
"media",
"websocket"};
#define NUMBER_OF_TYPES NS_ARRAY_LENGTH(kTypeString)
PRUint8 nsContentBlocker::mBehaviorPref[NUMBER_OF_TYPES];