mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
[XForms] Add content policy checks to security checks. Bug 325814, r=bz+smaug
This commit is contained in:
parent
7a6afdd808
commit
37d10acd06
@ -41,7 +41,6 @@
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOM3Node.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsXFormsAtoms.h"
|
||||
#include "nsString.h"
|
||||
@ -179,14 +178,8 @@ nsXFormsInstanceElement::OnChannelRedirect(nsIChannel *OldChannel,
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
nsresult rv = aNewChannel->GetURI(getter_AddRefs(newURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ENSURE_STATE(mElement);
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mElement->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
|
||||
NS_ENSURE_STATE(doc);
|
||||
|
||||
if (!nsXFormsUtils::CheckSameOrigin(doc, newURI)) {
|
||||
if (!nsXFormsUtils::CheckConnectionAllowed(mElement, newURI)) {
|
||||
const PRUnichar *strings[] = { NS_LITERAL_STRING("instance").get() };
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("externalLinkLoadOrigin"),
|
||||
strings, 1, mElement, mElement);
|
||||
@ -568,7 +561,7 @@ nsXFormsInstanceElement::LoadExternalInstance(const nsAString &aSrc)
|
||||
NS_NewURI(getter_AddRefs(uri), aSrc,
|
||||
doc->GetDocumentCharacterSet().get(), doc->GetDocumentURI());
|
||||
if (uri) {
|
||||
if (nsXFormsUtils::CheckSameOrigin(doc, uri)) {
|
||||
if (nsXFormsUtils::CheckConnectionAllowed(mElement, uri)) {
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
loadGroup = doc->GetDocumentLoadGroup();
|
||||
NS_WARN_IF_FALSE(loadGroup, "No load group!");
|
||||
|
@ -216,7 +216,7 @@ nsXFormsLabelElement::LoadExternalLabel(const nsAString& aSrc)
|
||||
NS_NewURI(getter_AddRefs(uri), aSrc, doc->GetDocumentCharacterSet().get(),
|
||||
doc->GetDocumentURI());
|
||||
if (uri) {
|
||||
if (nsXFormsUtils::CheckSameOrigin(doc, uri)) {
|
||||
if (nsXFormsUtils::CheckConnectionAllowed(mElement, uri)) {
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
loadGroup = doc->GetDocumentLoadGroup();
|
||||
NS_WARN_IF_FALSE(loadGroup, "No load group!");
|
||||
|
@ -932,7 +932,7 @@ nsXFormsMessageElement::TestExternalFile()
|
||||
doc->GetDocumentURI());
|
||||
NS_ENSURE_STATE(uri);
|
||||
|
||||
if (!nsXFormsUtils::CheckSameOrigin(doc, uri)) {
|
||||
if (!nsXFormsUtils::CheckConnectionAllowed(mElement, uri)) {
|
||||
nsAutoString tagName;
|
||||
mElement->GetLocalName(tagName);
|
||||
const PRUnichar *strings[] = { tagName.get() };
|
||||
@ -1017,13 +1017,7 @@ nsXFormsMessageElement::OnChannelRedirect(nsIChannel *OldChannel,
|
||||
nsresult rv = aNewChannel->GetURI(getter_AddRefs(newURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ENSURE_STATE(mElement);
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mElement->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
|
||||
NS_ENSURE_STATE(doc);
|
||||
|
||||
if (!nsXFormsUtils::CheckSameOrigin(doc, newURI)) {
|
||||
if (!nsXFormsUtils::CheckConnectionAllowed(mElement, newURI)) {
|
||||
nsAutoString tagName;
|
||||
mElement->GetLocalName(tagName);
|
||||
const PRUnichar *strings[] = { tagName.get() };
|
||||
|
@ -917,8 +917,8 @@ nsXFormsSubmissionElement::CheckSameOrigin(nsIDocument *aBaseDocument,
|
||||
else
|
||||
mode = nsXFormsUtils::kXFormsActionSend;
|
||||
|
||||
allowSubmission = nsXFormsUtils::CheckSameOrigin(aBaseDocument, aTestURI,
|
||||
mode);
|
||||
allowSubmission =
|
||||
nsXFormsUtils::CheckConnectionAllowed(mElement, aTestURI, mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,9 @@
|
||||
#include "nsIAttribute.h"
|
||||
#include "nsXFormsAtoms.h"
|
||||
#include "nsIXFormsRepeatElement.h"
|
||||
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsIXFormsContextControl.h"
|
||||
#include "nsIDOMDocumentEvent.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
@ -1301,22 +1303,49 @@ nsXFormsUtils::FindParentContext(nsIDOMElement *aElement,
|
||||
}
|
||||
|
||||
/* static */ PRBool
|
||||
nsXFormsUtils::CheckSameOrigin(nsIDocument *aBaseDocument, nsIURI *aTestURI,
|
||||
nsXFormsUtils::CheckConnectionAllowed(nsIDOMElement *aElement,
|
||||
nsIURI *aTestURI,
|
||||
ConnectionType aType)
|
||||
{
|
||||
if (!aElement || !aTestURI)
|
||||
return PR_FALSE;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
aElement->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
|
||||
if (!doc)
|
||||
return PR_FALSE;
|
||||
|
||||
// Start by checking UniversalBrowserRead, which overrides everything.
|
||||
nsIPrincipal *basePrincipal = doc->NodePrincipal();
|
||||
PRBool res;
|
||||
rv = basePrincipal->IsCapabilityEnabled("UniversalBrowserRead", nsnull, &res);
|
||||
if (NS_SUCCEEDED(rv) && res)
|
||||
return PR_TRUE;
|
||||
|
||||
// Check same origin
|
||||
res = CheckSameOrigin(doc, aTestURI, aType);
|
||||
if (!res || aType == kXFormsActionSend)
|
||||
return res;
|
||||
|
||||
// Check content policy
|
||||
return CheckContentPolicy(aElement, doc, aTestURI);
|
||||
}
|
||||
|
||||
/* static */ PRBool
|
||||
nsXFormsUtils::CheckSameOrigin(nsIDocument *aBaseDocument,
|
||||
nsIURI *aTestURI,
|
||||
ConnectionType aType)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// get the base document's principal
|
||||
nsIPrincipal *basePrincipal = aBaseDocument->NodePrincipal();
|
||||
|
||||
// check for the UniversalBrowserRead capability.
|
||||
PRBool crossSiteAccessEnabled;
|
||||
rv = basePrincipal->IsCapabilityEnabled("UniversalBrowserRead", nsnull,
|
||||
&crossSiteAccessEnabled);
|
||||
if (NS_SUCCEEDED(rv) && crossSiteAccessEnabled)
|
||||
return PR_TRUE;
|
||||
NS_ASSERTION(aBaseDocument && aTestURI, "Got null parameters?!");
|
||||
|
||||
// check the security manager and do a same original check on the principal
|
||||
nsIPrincipal* basePrincipal = aBaseDocument->NodePrincipal();
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
|
||||
if (secMan) {
|
||||
@ -1356,6 +1385,29 @@ nsXFormsUtils::CheckSameOrigin(nsIDocument *aBaseDocument, nsIURI *aTestURI,
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* static */ PRBool
|
||||
nsXFormsUtils::CheckContentPolicy(nsIDOMElement *aElement,
|
||||
nsIDocument *aDoc,
|
||||
nsIURI *aURI)
|
||||
{
|
||||
NS_ASSERTION(aElement && aDoc && aURI, "Got null parameters?!");
|
||||
|
||||
nsIURI *docURI = aDoc->GetDocumentURI();
|
||||
NS_ENSURE_TRUE(docURI, PR_FALSE);
|
||||
|
||||
PRInt16 decision = nsIContentPolicy::ACCEPT;
|
||||
nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_OTHER,
|
||||
aURI,
|
||||
docURI,
|
||||
aElement, // context
|
||||
EmptyCString(), // mime guess
|
||||
nsnull, // extra
|
||||
&decision);
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
|
||||
return NS_CP_ACCEPTED(decision);
|
||||
}
|
||||
|
||||
/*static*/ PRBool
|
||||
nsXFormsUtils::IsXFormsElement(nsIDOMNode* aNode, const nsAString& aName)
|
||||
{
|
||||
|
@ -372,7 +372,7 @@ public:
|
||||
PRInt32 *aContextPosition,
|
||||
PRInt32 *aContextSize);
|
||||
|
||||
/** Connection type used by CheckSameOrigin */
|
||||
/** Connection type used by CheckConnectionAllowed */
|
||||
enum ConnectionType {
|
||||
/** Send data, such as doing submission */
|
||||
kXFormsActionSend = 1,
|
||||
@ -385,17 +385,16 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether aTestURI has the same origin as aBaseDocument or the user
|
||||
* has allowed the connection type using the permission manager
|
||||
* Check whether a connecion to aTestURI from aElement is allowed.
|
||||
*
|
||||
* @param aBaseDocument The document the XForms lives in
|
||||
* @param aElement The element trying to access the resource
|
||||
* @param aTestURI The uri we are trying to connect to
|
||||
* @param aType The type of connection (see ConnectionType)
|
||||
* @return Whether connection is allowed
|
||||
*/
|
||||
static NS_HIDDEN_(PRBool) CheckSameOrigin(nsIDocument *aBaseDocument,
|
||||
nsIURI *aTestURI,
|
||||
ConnectionType aType = kXFormsActionLoad);
|
||||
static NS_HIDDEN_(PRBool) CheckConnectionAllowed(nsIDOMElement *aElement,
|
||||
nsIURI *aTestURI,
|
||||
ConnectionType aType = kXFormsActionLoad);
|
||||
|
||||
/**
|
||||
* @return true if aNode is element, its namespace URI is
|
||||
@ -549,6 +548,38 @@ public:
|
||||
*/
|
||||
static NS_HIDDEN_(nsresult) GetWindowFromDocument(nsIDOMDocument *aDoc,
|
||||
nsIDOMWindowInternal **aWindow);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Do same origin checks on aBaseDocument and aTestURI. Hosts can be
|
||||
* whitelisted through the XForms permissions.
|
||||
*
|
||||
* @note The function assumes that the caller does not pass null arguments
|
||||
*
|
||||
* @param aBaseDocument The document the XForms lives in
|
||||
* @param aTestURI The uri we are trying to connect to
|
||||
* @param aType The type of connection (see ConnectionType)
|
||||
* @return Whether connection is allowed
|
||||
*
|
||||
*/
|
||||
static NS_HIDDEN_(PRBool) CheckSameOrigin(nsIDocument *aBaseDocument,
|
||||
nsIURI *aTestURI,
|
||||
ConnectionType aType = kXFormsActionLoad);
|
||||
|
||||
/**
|
||||
* Check content policy for loading the specificed aTestURI.
|
||||
*
|
||||
* @note The function assumes that the caller does not pass null arguments
|
||||
*
|
||||
* @param aElement The element trying to load the content
|
||||
* @param aBaseDocument The document the XForms lives in
|
||||
* @param aTestURI The uri we are trying to load
|
||||
* @return Whether loading is allowed.
|
||||
*/
|
||||
static NS_HIDDEN_(PRBool) CheckContentPolicy(nsIDOMElement *aElement,
|
||||
nsIDocument *aDoc,
|
||||
nsIURI *aURI);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user