Open Bug 1041602 Opened 10 years ago Updated 2 years ago

SecurityError when adding, writing to, removing iframes rapidly

Categories

(Core :: General, defect)

30 Branch
x86_64
Windows 8.1
defect

Tracking

()

People

(Reporter: gmauer, Unassigned)

References

Details

(Keywords: steps-wanted, testcase)

Attachments

(3 files)

Attached file firefox iframe error.js (deleted) —
User Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36

Steps to reproduce:

TLDR; This is the most reduced test case I can come up with: http://jsfiddle.net/LG4x2/ (open the dev console, sorry for the mess - its compiled coffeescript)

On both chrome and IE the test runs twice. and dev console logs

    iframe text is foo, expected foo
    iframe text is bar, expected bar.

On firefox it runs once due to (what I inferred elsewhere) a SecurityError.

Here's the actual use case - I have an application which allows people to build up "slideshows" by writing javascript+html code. I obviously do not want to let their code run unrestrained directly in the parent page, so I sandbox it in an iframe - think jsfiddle/jsbin. I achieve this with a widget that basically creates an iframe, does some templating and writes the html to the document.

This works, but I have some jasmine tests to verify that it's working. And here I run into issues because after the first test runs I get the aforementioned SecurityError causing subsequent tests to fail.

Specifically the error seems to be coming from the `$slide.remove()` line on the second invocation, if that is removed the test runs. Interestingly, putting it into any sort of `setTimeout` seems to fix the issue.


Actual results:

Security error on second invocation of `iframeElement.remove()`


Expected results:

No error. Everything is fine. My tests shoudl work
(In reply to George Mauer from comment #0)

> Specifically the error seems to be coming from the `$slide.remove()` line on
> the second invocation, if that is removed the test runs. Interestingly,
> putting it into any sort of `setTimeout` seems to fix the issue.

I'm confused. Putting the $slide.remove() code in a try...catch doesn't show any errors. Adding a console.log statement after it and removing the try...catch shows the second console.log as well.

Where do you get the securityerror?
Component: Untriaged → General
Flags: needinfo?(gmauer)
Product: Firefox → Core
The SecurityError only shows up when I actually run this with jasmine http://jsfiddle.net/togakangaroo/pSsf5/

Not exactly sure why that is but the end result is the same - code that should run does not.
Flags: needinfo?(gmauer)
So what I see in that testcase is two document.open() calls.

The first one is fine.

The second one comes with this stack:

#0    0x114992c58   http://fiddle.jshell.net/togakangaroo/pSsf5/show/:38 (0x143374060 @ 35)
#1    0x114992b90   http://code.jquery.com/jquery-2.1.0.js:3260 (0x1437f7da8 @ 353)
#2    0x114992af8   http://fiddle.jshell.net/togakangaroo/pSsf5/show/:35 (0x143371da8 @ 17)
#3    0x114992a60   http://fiddle.jshell.net/togakangaroo/pSsf5/show/:68 (0x14336f830 @ 18)
#4    0x1149929a0   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:290 (0x143371c18 @ 129)
#5    0x1149928f0   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1520 (0x14336e9c0 @ 35)
#6            0x0   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1496 (0x14336e830 @ 115)
#7    0x114992850   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1485 (0x14336e768 @ 15)
#8    0x1149927b8   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:518 (0x14336e5d8 @ 66)
#9            0x0   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:306 (0x14336f2b8 @ 320)
#10    0x114992628   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1708 (0x14336ece0 @ 15)
#11    0x114992578   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1520 (0x14336e9c0 @ 35)
#12            0x0   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1496 (0x14336e830 @ 115)
#13    0x1149924e0   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1517 (0x1433ce768 @ 24)
#14    0x114992440   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:333 (0x1433fa448 @ 73)
#15    0x1149923b0   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:506 (0x1433fa380 @ 62)
#16            0x0   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1505 (0x14336e830 @ 208)
#17    0x114992318   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1517 (0x1433ce768 @ 24)
#18    0x114992298   http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:287 (0x1433ce5d8 @ 16)
#19    0x1149921f0   http://code.jquery.com/jquery-2.1.0.js:3047 (0x14335f448 @ 115)
#20    0x114992150   http://code.jquery.com/jquery-2.1.0.js:3159 (0x14335f380 @ 148)
#21    0x1149920b8   http://code.jquery.com/jquery-2.1.0.js:3249 (0x1433ce510 @ 54)
#22    0x114992020   http://fiddle.jshell.net/togakangaroo/pSsf5/show/:8 (0x1433ce448 @ 17)

and ends up throwing.

It throws because the JSContext it's running on is associated with a torn-down window: it has no docshell and no document (because its iframe has been removed from the DOM).  So it fails security checks.

In particular, this is coming off a setTimeout on an inner whose outer has been torn down.

Bobby, can we replace this GetDocumentFromContext with an entry settings object check or something?  Seems like that would do what we want here, and since the inner window that's out settings global _does_ still have a pointer to the document it would work.

The other weirdness is that this outer gets torn down in the middle of script executing on it.  I wonder whether we can delay that like we delay window.close calls?
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: needinfo?(bobbyholley)
Attached file Subframe for testcase (deleted) —
Attached file Testcase (deleted) —
(In reply to Boris Zbarsky [:bz] from comment #3)
> So what I see in that testcase is two document.open() calls.
> 
> The first one is fine.
> 
> The second one comes with this stack:
> 
> #0    0x114992c58   http://fiddle.jshell.net/togakangaroo/pSsf5/show/:38
> (0x143374060 @ 35)
> #1    0x114992b90   http://code.jquery.com/jquery-2.1.0.js:3260 (0x1437f7da8
> @ 353)
> #2    0x114992af8   http://fiddle.jshell.net/togakangaroo/pSsf5/show/:35
> (0x143371da8 @ 17)
> #3    0x114992a60   http://fiddle.jshell.net/togakangaroo/pSsf5/show/:68
> (0x14336f830 @ 18)
> #4    0x1149929a0  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:290
> (0x143371c18 @ 129)
> #5    0x1149928f0  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1520
> (0x14336e9c0 @ 35)
> #6            0x0  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1496
> (0x14336e830 @ 115)
> #7    0x114992850  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1485
> (0x14336e768 @ 15)
> #8    0x1149927b8  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:518
> (0x14336e5d8 @ 66)
> #9            0x0  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:306
> (0x14336f2b8 @ 320)
> #10    0x114992628  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1708
> (0x14336ece0 @ 15)
> #11    0x114992578  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1520
> (0x14336e9c0 @ 35)
> #12            0x0  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1496
> (0x14336e830 @ 115)
> #13    0x1149924e0  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1517
> (0x1433ce768 @ 24)
> #14    0x114992440  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:333
> (0x1433fa448 @ 73)
> #15    0x1149923b0  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:506
> (0x1433fa380 @ 62)
> #16            0x0  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1505
> (0x14336e830 @ 208)
> #17    0x114992318  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:1517
> (0x1433ce768 @ 24)
> #18    0x114992298  
> http://cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js:287
> (0x1433ce5d8 @ 16)
> #19    0x1149921f0   http://code.jquery.com/jquery-2.1.0.js:3047
> (0x14335f448 @ 115)
> #20    0x114992150   http://code.jquery.com/jquery-2.1.0.js:3159
> (0x14335f380 @ 148)
> #21    0x1149920b8   http://code.jquery.com/jquery-2.1.0.js:3249
> (0x1433ce510 @ 54)
> #22    0x114992020   http://fiddle.jshell.net/togakangaroo/pSsf5/show/:8
> (0x1433ce448 @ 17)
> 
> and ends up throwing.
> 
> It throws because the JSContext it's running on is associated with a
> torn-down window: it has no docshell and no document (because its iframe has
> been removed from the DOM).  So it fails security checks.
> 
> In particular, this is coming off a setTimeout on an inner whose outer has
> been torn down.
> 
> Bobby, can we replace this GetDocumentFromContext with an entry settings
> object check or something?  Seems like that would do what we want here, and
> since the inner window that's out settings global _does_ still have a
> pointer to the document it would work.

Yes, but we need that the entry settings stack to be complete before we can use it. That would be bug 951991, a Q3 DOM goal.

> The other weirdness is that this outer gets torn down in the middle of
> script executing on it.  I wonder whether we can delay that like we delay
> window.close calls?

Here there be dragons.
Depends on: 951991
Flags: needinfo?(bobbyholley)
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: