Attachment #786299: Fix for Bug 886262: Ensure sandbox flags and, where necessary, null principal are set for child objects. for bug #886262

View | Details | Raw Unified | Return to bug 886262
Collapse All | Expand All

(-)a/content/base/src/nsFrameLoader.cpp (-17 / +21 lines)
Line     Link Here 
 Lines 457-489   nsFrameLoader::ReallyStartLoadingInterna Link Here 
457
  // Just to be safe, recheck uri.
457
  // Just to be safe, recheck uri.
458
  rv = CheckURILoad(mURIToLoad);
458
  rv = CheckURILoad(mURIToLoad);
459
  NS_ENSURE_SUCCESS(rv, rv);
459
  NS_ENSURE_SUCCESS(rv, rv);
460
460
461
  nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
461
  nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
462
  mDocShell->CreateLoadInfo(getter_AddRefs(loadInfo));
462
  mDocShell->CreateLoadInfo(getter_AddRefs(loadInfo));
463
  NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
463
  NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
464
464
465
  // Does this frame have a parent which is already sandboxed or is this
466
  // an <iframe> with a sandbox attribute?
467
  uint32_t sandboxFlags = 0;
468
  uint32_t parentSandboxFlags = mOwnerContent->OwnerDoc()->GetSandboxFlags();
469
470
  HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent);
471
472
  if (iframe) {
473
    sandboxFlags = iframe->GetSandboxFlags();
474
  }
475
476
  if (sandboxFlags || parentSandboxFlags) {
477
    // The child can only add restrictions, never remove them.
478
    sandboxFlags |= parentSandboxFlags;
479
    mDocShell->SetSandboxFlags(sandboxFlags);
480
  }
481
482
  // If this frame is sandboxed with respect to origin we will set it up with
465
  // If this frame is sandboxed with respect to origin we will set it up with
483
  // a null principal later in nsDocShell::DoURILoad.
466
  // a null principal later in nsDocShell::DoURILoad.
484
  // We do it there to correctly sandbox content that was loaded into
467
  // We do it there to correctly sandbox content that was loaded into
485
  // the frame via other methods than the src attribute.
468
  // the frame via other methods than the src attribute.
486
  // We'll use our principal, not that of the document loaded inside us.  This
469
  // We'll use our principal, not that of the document loaded inside us.  This
487
  // is very important; needed to prevent XSS attacks on documents loaded in
470
  // is very important; needed to prevent XSS attacks on documents loaded in
488
  // subframes!
471
  // subframes!
489
  loadInfo->SetOwner(mOwnerContent->NodePrincipal());
472
  loadInfo->SetOwner(mOwnerContent->NodePrincipal());
 Lines 1564-1579   nsFrameLoader::MaybeCreateDocShell() Link Here 
1564
    doc->GetContainer();
1547
    doc->GetContainer();
1565
  nsCOMPtr<nsIWebNavigation> parentAsWebNav = do_QueryInterface(container);
1548
  nsCOMPtr<nsIWebNavigation> parentAsWebNav = do_QueryInterface(container);
1566
  NS_ENSURE_STATE(parentAsWebNav);
1549
  NS_ENSURE_STATE(parentAsWebNav);
1567
1550
1568
  // Create the docshell...
1551
  // Create the docshell...
1569
  mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
1552
  mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
1570
  NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
1553
  NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
1571
1554
1555
  // Apply sandbox flags even if our owner is not an iframe, as this copies
1556
  // flags from our owning content's owning document.
1557
  uint32_t sandboxFlags = 0;
1558
  HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent);
1559
  if (iframe) {
1560
    sandboxFlags = iframe->GetSandboxFlags();
1561
  }
1562
  ApplySandboxFlags(sandboxFlags);
1563
1572
  if (!mNetworkCreated) {
1564
  if (!mNetworkCreated) {
1573
    if (mDocShell) {
1565
    if (mDocShell) {
1574
      mDocShell->SetCreatedDynamically(true);
1566
      mDocShell->SetCreatedDynamically(true);
1575
    }
1567
    }
1576
  }
1568
  }
1577
1569
1578
  // Get the frame name and tell the docshell about it.
1570
  // Get the frame name and tell the docshell about it.
1579
  NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
1571
  NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
 Lines 2463-2478   nsFrameLoader::SetDetachedSubdocView(nsV Link Here 
2463
2455
2464
nsView*
2456
nsView*
2465
nsFrameLoader::GetDetachedSubdocView(nsIDocument** aContainerDoc) const
2457
nsFrameLoader::GetDetachedSubdocView(nsIDocument** aContainerDoc) const
2466
{
2458
{
2467
  NS_IF_ADDREF(*aContainerDoc = mContainerDocWhileDetached);
2459
  NS_IF_ADDREF(*aContainerDoc = mContainerDocWhileDetached);
2468
  return mDetachedSubdocViews;
2460
  return mDetachedSubdocViews;
2469
}
2461
}
2470
2462
2463
void
2464
nsFrameLoader::ApplySandboxFlags(uint32_t sandboxFlags)
2465
{
2466
  if (mDocShell) {
2467
    uint32_t parentSandboxFlags = mOwnerContent->OwnerDoc()->GetSandboxFlags();
2468
2469
    // The child can only add restrictions, never remove them.
2470
    sandboxFlags |= parentSandboxFlags;
2471
    mDocShell->SetSandboxFlags(sandboxFlags);
2472
  }
2473
}
2474
2471
/* virtual */ void
2475
/* virtual */ void
2472
nsFrameLoader::AttributeChanged(nsIDocument* aDocument,
2476
nsFrameLoader::AttributeChanged(nsIDocument* aDocument,
2473
                                mozilla::dom::Element* aElement,
2477
                                mozilla::dom::Element* aElement,
2474
                                int32_t      aNameSpaceID,
2478
                                int32_t      aNameSpaceID,
2475
                                nsIAtom*     aAttribute,
2479
                                nsIAtom*     aAttribute,
2476
                                int32_t      aModType)
2480
                                int32_t      aModType)
2477
{
2481
{
2478
  MOZ_ASSERT(mObservingOwnerContent);
2482
  MOZ_ASSERT(mObservingOwnerContent);
(-)a/content/base/src/nsFrameLoader.h (+7 lines)
Line     Link Here 
 Lines 298-313   public: Link Here 
298
                             nsIDocument* aContainerDoc);
298
                             nsIDocument* aContainerDoc);
299
299
300
  /**
300
  /**
301
   * Retrieves the detached view and the document containing the view,
301
   * Retrieves the detached view and the document containing the view,
302
   * as set by SetDetachedSubdocView().
302
   * as set by SetDetachedSubdocView().
303
   */
303
   */
304
  nsView* GetDetachedSubdocView(nsIDocument** aContainerDoc) const;
304
  nsView* GetDetachedSubdocView(nsIDocument** aContainerDoc) const;
305
305
306
  /**
307
   * Applies a new set of sandbox flags. These are merged with the sandbox
308
   * flags from our owning content's owning document with a logical OR, this
309
   * ensures that we can only add restrictions and never remove them.
310
   */
311
  void ApplySandboxFlags(uint32_t sandboxFlags);
312
306
private:
313
private:
307
314
308
  void SetOwnerContent(mozilla::dom::Element* aContent);
315
  void SetOwnerContent(mozilla::dom::Element* aContent);
309
316
310
  bool ShouldUseRemoteProcess();
317
  bool ShouldUseRemoteProcess();
311
318
312
  /**
319
  /**
313
   * Is this a frameloader for a bona fide <iframe mozbrowser> or
320
   * Is this a frameloader for a bona fide <iframe mozbrowser> or
(-)a/content/base/src/nsObjectLoadingContent.cpp (-3 / +15 lines)
Line     Link Here 
 Lines 55-70    Link Here 
55
#include "nsGkAtoms.h"
55
#include "nsGkAtoms.h"
56
#include "nsThreadUtils.h"
56
#include "nsThreadUtils.h"
57
#include "nsNetUtil.h"
57
#include "nsNetUtil.h"
58
#include "nsMimeTypes.h"
58
#include "nsMimeTypes.h"
59
#include "nsStyleUtil.h"
59
#include "nsStyleUtil.h"
60
#include "nsGUIEvent.h"
60
#include "nsGUIEvent.h"
61
#include "nsUnicharUtils.h"
61
#include "nsUnicharUtils.h"
62
#include "mozilla/Preferences.h"
62
#include "mozilla/Preferences.h"
63
#include "nsSandboxFlags.h"
63
64
64
// Concrete classes
65
// Concrete classes
65
#include "nsFrameLoader.h"
66
#include "nsFrameLoader.h"
66
67
67
#include "nsObjectLoadingContent.h"
68
#include "nsObjectLoadingContent.h"
68
#include "mozAutoDocUpdate.h"
69
#include "mozAutoDocUpdate.h"
69
#include "nsIContentSecurityPolicy.h"
70
#include "nsIContentSecurityPolicy.h"
70
#include "nsIChannelPolicy.h"
71
#include "nsIChannelPolicy.h"
 Lines 2281-2299   nsObjectLoadingContent::OpenChannel() Link Here 
2281
  NS_ENSURE_SUCCESS(rv, rv);
2282
  NS_ENSURE_SUCCESS(rv, rv);
2282
2283
2283
  // Referrer
2284
  // Referrer
2284
  nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
2285
  nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
2285
  if (httpChan) {
2286
  if (httpChan) {
2286
    httpChan->SetReferrer(doc->GetDocumentURI());
2287
    httpChan->SetReferrer(doc->GetDocumentURI());
2287
  }
2288
  }
2288
2289
2289
  // Set up the channel's principal and such, like nsDocShell::DoURILoad does
2290
  // Set up the channel's principal and such, like nsDocShell::DoURILoad does.
2290
  nsContentUtils::SetUpChannelOwner(thisContent->NodePrincipal(),
2291
  // If the content being loaded should be sandboxed with respect to origin we
2291
                                    chan, mURI, true);
2292
  // create a new null principal here. nsContentUtils::SetUpChannelOwner is
2293
  // used with a flag to force it to be set as the channel owner.
2294
  nsCOMPtr<nsIPrincipal> ownerPrincipal;
2295
  uint32_t sandboxFlags = doc->GetSandboxFlags();
2296
  if (sandboxFlags & SANDBOXED_ORIGIN) {
2297
    ownerPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1");
2298
  } else {
2299
    // Not sandboxed - we allow the content to assume its natural owner.
2300
    ownerPrincipal = thisContent->NodePrincipal();
2301
  }
2302
  nsContentUtils::SetUpChannelOwner(ownerPrincipal, chan, mURI, true,
2303
                                    sandboxFlags & SANDBOXED_ORIGIN);
2292
2304
2293
  nsCOMPtr<nsIScriptChannel> scriptChannel = do_QueryInterface(chan);
2305
  nsCOMPtr<nsIScriptChannel> scriptChannel = do_QueryInterface(chan);
2294
  if (scriptChannel) {
2306
  if (scriptChannel) {
2295
    // Allow execution against our context if the principals match
2307
    // Allow execution against our context if the principals match
2296
    scriptChannel->SetExecutionPolicy(nsIScriptChannel::EXECUTE_NORMAL);
2308
    scriptChannel->SetExecutionPolicy(nsIScriptChannel::EXECUTE_NORMAL);
2297
  }
2309
  }
2298
2310
2299
  // AsyncOpen can fail if a file does not exist.
2311
  // AsyncOpen can fail if a file does not exist.
(-)a/content/html/content/src/HTMLIFrameElement.cpp (-16 / +11 lines)
Line     Link Here 
 Lines 217-249   HTMLIFrameElement::SetAttr(int32_t aName Link Here 
217
}
217
}
218
218
219
nsresult
219
nsresult
220
HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
220
HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
221
                                const nsAttrValue* aValue,
221
                                const nsAttrValue* aValue,
222
                                bool aNotify)
222
                                bool aNotify)
223
{
223
{
224
  if (aName == nsGkAtoms::sandbox && aNameSpaceID == kNameSpaceID_None) {
224
  if (aName == nsGkAtoms::sandbox && aNameSpaceID == kNameSpaceID_None) {
225
    // Parse the new value of the sandbox attribute, and if we have a docshell
225
    // If we have an nsFrameLoader, parse the new value of the sandbox
226
    // set its sandbox flags appropriately.
226
    // attribute and apply the new sandbox flags.
227
    if (mFrameLoader) {
227
    if (mFrameLoader) {
228
      nsCOMPtr<nsIDocShell> docshell = mFrameLoader->GetExistingDocShell();
228
      // If a nullptr aValue is passed in, we want to clear the sandbox flags
229
229
      // which we will do by setting them to 0.
230
      if (docshell) {
230
      uint32_t newFlags = 0;
231
        uint32_t newFlags = 0;
231
      if (aValue) {
232
        // If a nullptr aValue is passed in, we want to clear the sandbox flags
232
        nsAutoString strValue;
233
        // which we will do by setting them to 0.
233
        aValue->ToString(strValue);
234
        if (aValue) {
234
        newFlags = nsContentUtils::ParseSandboxAttributeToFlags(strValue);
235
          nsAutoString strValue;
235
      }   
236
          aValue->ToString(strValue);
236
      mFrameLoader->ApplySandboxFlags(newFlags);
237
          newFlags = nsContentUtils::ParseSandboxAttributeToFlags(
238
            strValue);
239
        }   
240
        docshell->SetSandboxFlags(newFlags);
241
      }
242
    }
237
    }
243
  }
238
  }
244
  return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
239
  return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
245
                                            aNotify);
240
                                            aNotify);
246
}
241
}
247
242
248
nsresult
243
nsresult
249
HTMLIFrameElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
244
HTMLIFrameElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,

Return to bug 886262