[XForms] Add content policy checks to security checks. Bug 325814, r=bz+smaug

This commit is contained in:
allan%beaufour.dk 2006-05-31 09:00:24 +00:00
parent 7a6afdd808
commit 37d10acd06
6 changed files with 108 additions and 38 deletions

View File

@ -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!");

View File

@ -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!");

View File

@ -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() };

View File

@ -917,8 +917,8 @@ nsXFormsSubmissionElement::CheckSameOrigin(nsIDocument *aBaseDocument,
else
mode = nsXFormsUtils::kXFormsActionSend;
allowSubmission = nsXFormsUtils::CheckSameOrigin(aBaseDocument, aTestURI,
mode);
allowSubmission =
nsXFormsUtils::CheckConnectionAllowed(mElement, aTestURI, mode);
}
}

View File

@ -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)
{

View File

@ -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