Bug 886262 - Ensure sandbox flags and, where necessary, null principal are set for child objects. r=bz

This commit is contained in:
Bob Owen 2013-08-06 11:01:23 +01:00
parent a30f8920ea
commit d12e2d913c
4 changed files with 54 additions and 36 deletions

View File

@ -462,23 +462,6 @@ nsFrameLoader::ReallyStartLoadingInternal()
mDocShell->CreateLoadInfo(getter_AddRefs(loadInfo));
NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
// Does this frame have a parent which is already sandboxed or is this
// an <iframe> with a sandbox attribute?
uint32_t sandboxFlags = 0;
uint32_t parentSandboxFlags = mOwnerContent->OwnerDoc()->GetSandboxFlags();
HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent);
if (iframe) {
sandboxFlags = iframe->GetSandboxFlags();
}
if (sandboxFlags || parentSandboxFlags) {
// The child can only add restrictions, never remove them.
sandboxFlags |= parentSandboxFlags;
mDocShell->SetSandboxFlags(sandboxFlags);
}
// If this frame is sandboxed with respect to origin we will set it up with
// a null principal later in nsDocShell::DoURILoad.
// We do it there to correctly sandbox content that was loaded into
@ -1569,6 +1552,15 @@ nsFrameLoader::MaybeCreateDocShell()
mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
// Apply sandbox flags even if our owner is not an iframe, as this copies
// flags from our owning content's owning document.
uint32_t sandboxFlags = 0;
HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent);
if (iframe) {
sandboxFlags = iframe->GetSandboxFlags();
}
ApplySandboxFlags(sandboxFlags);
if (!mNetworkCreated) {
if (mDocShell) {
mDocShell->SetCreatedDynamically(true);
@ -2471,6 +2463,18 @@ nsFrameLoader::GetDetachedSubdocView(nsIDocument** aContainerDoc) const
return mDetachedSubdocViews;
}
void
nsFrameLoader::ApplySandboxFlags(uint32_t sandboxFlags)
{
if (mDocShell) {
uint32_t parentSandboxFlags = mOwnerContent->OwnerDoc()->GetSandboxFlags();
// The child can only add restrictions, never remove them.
sandboxFlags |= parentSandboxFlags;
mDocShell->SetSandboxFlags(sandboxFlags);
}
}
/* virtual */ void
nsFrameLoader::AttributeChanged(nsIDocument* aDocument,
mozilla::dom::Element* aElement,

View File

@ -303,6 +303,13 @@ public:
*/
nsView* GetDetachedSubdocView(nsIDocument** aContainerDoc) const;
/**
* Applies a new set of sandbox flags. These are merged with the sandbox
* flags from our owning content's owning document with a logical OR, this
* ensures that we can only add restrictions and never remove them.
*/
void ApplySandboxFlags(uint32_t sandboxFlags);
private:
void SetOwnerContent(mozilla::dom::Element* aContent);

View File

@ -60,6 +60,7 @@
#include "nsGUIEvent.h"
#include "nsUnicharUtils.h"
#include "mozilla/Preferences.h"
#include "nsSandboxFlags.h"
// Concrete classes
#include "nsFrameLoader.h"
@ -2289,9 +2290,20 @@ nsObjectLoadingContent::OpenChannel()
httpChan->SetReferrer(doc->GetDocumentURI());
}
// Set up the channel's principal and such, like nsDocShell::DoURILoad does
nsContentUtils::SetUpChannelOwner(thisContent->NodePrincipal(),
chan, mURI, true);
// Set up the channel's principal and such, like nsDocShell::DoURILoad does.
// If the content being loaded should be sandboxed with respect to origin we
// create a new null principal here. nsContentUtils::SetUpChannelOwner is
// used with a flag to force it to be set as the channel owner.
nsCOMPtr<nsIPrincipal> ownerPrincipal;
uint32_t sandboxFlags = doc->GetSandboxFlags();
if (sandboxFlags & SANDBOXED_ORIGIN) {
ownerPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1");
} else {
// Not sandboxed - we allow the content to assume its natural owner.
ownerPrincipal = thisContent->NodePrincipal();
}
nsContentUtils::SetUpChannelOwner(ownerPrincipal, chan, mURI, true,
sandboxFlags & SANDBOXED_ORIGIN);
nsCOMPtr<nsIScriptChannel> scriptChannel = do_QueryInterface(chan);
if (scriptChannel) {

View File

@ -222,23 +222,18 @@ HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
bool aNotify)
{
if (aName == nsGkAtoms::sandbox && aNameSpaceID == kNameSpaceID_None) {
// Parse the new value of the sandbox attribute, and if we have a docshell
// set its sandbox flags appropriately.
// If we have an nsFrameLoader, parse the new value of the sandbox
// attribute and apply the new sandbox flags.
if (mFrameLoader) {
nsCOMPtr<nsIDocShell> docshell = mFrameLoader->GetExistingDocShell();
if (docshell) {
uint32_t newFlags = 0;
// If a nullptr aValue is passed in, we want to clear the sandbox flags
// which we will do by setting them to 0.
if (aValue) {
nsAutoString strValue;
aValue->ToString(strValue);
newFlags = nsContentUtils::ParseSandboxAttributeToFlags(
strValue);
}
docshell->SetSandboxFlags(newFlags);
}
// If a nullptr aValue is passed in, we want to clear the sandbox flags
// which we will do by setting them to 0.
uint32_t newFlags = 0;
if (aValue) {
nsAutoString strValue;
aValue->ToString(strValue);
newFlags = nsContentUtils::ParseSandboxAttributeToFlags(strValue);
}
mFrameLoader->ApplySandboxFlags(newFlags);
}
}
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,