зеркало из https://github.com/mozilla/pjs.git
Bug 323924, Call CheckLoadURIWithPrincipal before issuing pings and on redirects. r/sr=jst
This commit is contained in:
Родитель
66c19f7801
Коммит
cdf5bf4c06
|
@ -122,6 +122,7 @@
|
||||||
#include "nsIPrefService.h"
|
#include "nsIPrefService.h"
|
||||||
#include "nsITimer.h"
|
#include "nsITimer.h"
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
|
#include "nsContentPolicyUtils.h"
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
/**
|
/**
|
||||||
|
@ -192,6 +193,48 @@ PingsEnabled(PRInt32 *maxPerLink, PRBool *requireSameHost)
|
||||||
return allow;
|
return allow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRBool
|
||||||
|
CheckPingURI(nsIURI* uri, nsIContent* content)
|
||||||
|
{
|
||||||
|
if (!uri)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
// Check with nsIScriptSecurityManager
|
||||||
|
nsCOMPtr<nsIScriptSecurityManager> ssmgr =
|
||||||
|
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
|
||||||
|
NS_ENSURE_TRUE(ssmgr, PR_FALSE);
|
||||||
|
|
||||||
|
nsresult rv =
|
||||||
|
ssmgr->CheckLoadURIWithPrincipal(content->NodePrincipal(), uri,
|
||||||
|
nsIScriptSecurityManager::STANDARD);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore non-HTTP(S)
|
||||||
|
PRBool match;
|
||||||
|
if ((NS_FAILED(uri->SchemeIs("http", &match)) || !match) &&
|
||||||
|
(NS_FAILED(uri->SchemeIs("https", &match)) || !match)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check with contentpolicy
|
||||||
|
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
|
||||||
|
nsIURI* docURI = nsnull;
|
||||||
|
nsIDocument* doc = content->GetOwnerDoc();
|
||||||
|
if (doc) {
|
||||||
|
docURI = doc->GetDocumentURI();
|
||||||
|
}
|
||||||
|
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_OTHER,
|
||||||
|
uri,
|
||||||
|
docURI,
|
||||||
|
content,
|
||||||
|
EmptyCString(), // mime hint
|
||||||
|
nsnull, //extra
|
||||||
|
&shouldLoad);
|
||||||
|
return NS_SUCCEEDED(rv) && NS_CP_ACCEPTED(shouldLoad);
|
||||||
|
}
|
||||||
|
|
||||||
typedef void (* ForEachPingCallback)(void *closure, nsIContent *content,
|
typedef void (* ForEachPingCallback)(void *closure, nsIContent *content,
|
||||||
nsIURI *uri, nsIIOService *ios);
|
nsIURI *uri, nsIIOService *ios);
|
||||||
|
|
||||||
|
@ -229,12 +272,6 @@ ForEachPing(nsIContent *content, ForEachPingCallback callback, void *closure)
|
||||||
if (!doc)
|
if (!doc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptSecurityManager> ssmgr =
|
|
||||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
|
|
||||||
if (!ssmgr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// value contains relative URIs split on spaces (U+0020)
|
// value contains relative URIs split on spaces (U+0020)
|
||||||
const PRUnichar *start = value.BeginReading();
|
const PRUnichar *start = value.BeginReading();
|
||||||
const PRUnichar *end = value.EndReading();
|
const PRUnichar *end = value.EndReading();
|
||||||
|
@ -250,17 +287,10 @@ ForEachPing(nsIContent *content, ForEachPingCallback callback, void *closure)
|
||||||
ios->NewURI(NS_ConvertUTF16toUTF8(Substring(start, iter)),
|
ios->NewURI(NS_ConvertUTF16toUTF8(Substring(start, iter)),
|
||||||
doc->GetDocumentCharacterSet().get(),
|
doc->GetDocumentCharacterSet().get(),
|
||||||
baseURI, getter_AddRefs(uri));
|
baseURI, getter_AddRefs(uri));
|
||||||
if (uri && NS_SUCCEEDED(ssmgr->CheckLoadURIWithPrincipal(
|
if (CheckPingURI(uri, content)) {
|
||||||
content->NodePrincipal(), uri,
|
|
||||||
nsIScriptSecurityManager::STANDARD))) {
|
|
||||||
// Ignore non-HTTP(S) pings:
|
|
||||||
PRBool match;
|
|
||||||
if ((NS_SUCCEEDED(uri->SchemeIs("http", &match)) && match) ||
|
|
||||||
(NS_SUCCEEDED(uri->SchemeIs("https", &match)) && match)) {
|
|
||||||
callback(closure, content, uri, ios);
|
callback(closure, content, uri, ios);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
start = iter = iter + 1;
|
start = iter = iter + 1;
|
||||||
if (iter >= end)
|
if (iter >= end)
|
||||||
break;
|
break;
|
||||||
|
@ -302,12 +332,14 @@ public:
|
||||||
NS_DECL_NSIINTERFACEREQUESTOR
|
NS_DECL_NSIINTERFACEREQUESTOR
|
||||||
NS_DECL_NSICHANNELEVENTSINK
|
NS_DECL_NSICHANNELEVENTSINK
|
||||||
|
|
||||||
nsPingListener(PRBool requireSameHost)
|
nsPingListener(PRBool requireSameHost, nsIContent* content)
|
||||||
: mRequireSameHost(requireSameHost)
|
: mRequireSameHost(requireSameHost),
|
||||||
|
mContent(content)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PRBool mRequireSameHost;
|
PRBool mRequireSameHost;
|
||||||
|
nsCOMPtr<nsIContent> mContent;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS4(nsPingListener, nsIStreamListener, nsIRequestObserver,
|
NS_IMPL_ISUPPORTS4(nsPingListener, nsIStreamListener, nsIRequestObserver,
|
||||||
|
@ -351,12 +383,17 @@ NS_IMETHODIMP
|
||||||
nsPingListener::OnChannelRedirect(nsIChannel *oldChan, nsIChannel *newChan,
|
nsPingListener::OnChannelRedirect(nsIChannel *oldChan, nsIChannel *newChan,
|
||||||
PRUint32 flags)
|
PRUint32 flags)
|
||||||
{
|
{
|
||||||
|
nsCOMPtr<nsIURI> newURI;
|
||||||
|
newChan->GetURI(getter_AddRefs(newURI));
|
||||||
|
|
||||||
|
if (!CheckPingURI(newURI, mContent))
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
|
||||||
if (!mRequireSameHost)
|
if (!mRequireSameHost)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> oldURI, newURI;
|
nsCOMPtr<nsIURI> oldURI;
|
||||||
oldChan->GetURI(getter_AddRefs(oldURI));
|
oldChan->GetURI(getter_AddRefs(oldURI));
|
||||||
newChan->GetURI(getter_AddRefs(newURI));
|
|
||||||
NS_ENSURE_STATE(oldURI && newURI);
|
NS_ENSURE_STATE(oldURI && newURI);
|
||||||
|
|
||||||
if (!IsSameHost(oldURI, newURI))
|
if (!IsSameHost(oldURI, newURI))
|
||||||
|
@ -450,7 +487,7 @@ SendPing(void *closure, nsIContent *content, nsIURI *uri, nsIIOService *ios)
|
||||||
// opening the channel, then it is not necessary to hold a reference to the
|
// opening the channel, then it is not necessary to hold a reference to the
|
||||||
// channel. The networking subsystem will take care of that for us.
|
// channel. The networking subsystem will take care of that for us.
|
||||||
nsCOMPtr<nsIStreamListener> listener =
|
nsCOMPtr<nsIStreamListener> listener =
|
||||||
new nsPingListener(info->requireSameHost);
|
new nsPingListener(info->requireSameHost, content);
|
||||||
if (!listener)
|
if (!listener)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче