Bug 116406

Summary: frame inside frame recursion at blog of SAP manager makes Konqueror use insane amounts of memory and cpu time
Product: [Applications] konqueror Reporter: Martin Steigerwald <Martin>
Component: khtmlAssignee: Konqueror Developers <konq-bugs>
Status: RESOLVED WORKSFORME    
Severity: normal CC: frank78ac, hnzekto
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Debian testing   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Martin Steigerwald 2005-11-15 10:41:36 UTC
Version:            (using KDE KDE 3.4.2)
Installed from:    Debian testing/unstable Packages
OS:                Linux

Hello,

although Shai Agassi says "I Love opensouce - really!" at least his blog bombs out Konqueror badly:

https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/1700

as mentioned in:
http://www.heise.de/newsticker/meldung/66168

Its a frame opening inside a frame opening inside a frame kind of bug that makes Konqueror eat gradually increasing amount of memory and cpu time up to a point where I had to use Ctrl-Alt-Esc on the Konqueror window to stop that denial of service attack:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
16098 martin    18   0  919m 226m 8608 R  0.7 60.2  13:27.33 konqueror

I stopped it before memory got exhausted completely:

martin@deepdance:~ -> free
             total       used       free     shared    buffers     cached
Mem:        385452     380472       4980          0        308      22752
-/+ buffers/cache:     357412      28040
Swap:       979924     856176     123748

Step to reproduce:

- point konqueror to this URL:
https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/1700

In early stage the frame inside frame recursion can be stopped by pressing the button to stop the transfer.

Konqueror should limit the amount of frames inside frames to a sensible amount to avoid this kind of denial of service attack - not many more that are visible on a 21 inch TFT display or so I think. Well I wouldn't be surprised if you have such taken such a precaution already, but it doesn't seem to work here.

Mozilla Firefox 1.07 as well as Opera 8.5 however do not show the frame inside frame inside frame behavior and just show one frame.

Regards,
Martin Steigerwald
Comment 1 Martin Steigerwald 2005-11-15 10:45:27 UTC
For the figure about memory consumption: I opened this blog another time to see if that behavior is reproducable. Before I did this it seemed, that the frame inside frame recursion had come to an end, Konqueror did not eat more memory - so it may well be that an internal frame inside frame limit in Konqueror has already been reached.

Still I consider the amount of resources just for one opening of the blog already quite insane and as Mozilla Firefox and Opera do not show that behavior, there might well be a fixable bug hidden in Konqueror.
Comment 2 Philip Rodrigues 2006-09-07 21:53:22 UTC
At least the konqueror rendering is wrong (well, different to FF at least) - firefox doesn't open frames within frames on that page, while konqueror does. I didn't leave it long enough to see if it got to OOM.
Comment 3 Tommi Tervo 2006-12-19 15:49:56 UTC
*** Bug 139011 has been marked as a duplicate of this bug. ***
Comment 4 Gregor B. Rosenauer 2007-04-27 19:30:21 UTC
same problem here, try this one on the same site:
https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/2824

Konqueror renders frame after frame, nesting each one in the other, making the result an interesting work of art but resulting in a totally weird and unreadable UI clutter...,-)

Opens fine in Firefox 2.0.0.3.
Comment 5 Frank Reininghaus 2008-04-20 01:30:14 UTC
I saved this page with Firefox using "Save page as/... Webpage, complete" to see what's going on. This <iframe>-recursion seems to be due to more than one problem (both in Konqueror and in the page itself; all I write here applies to Konqueror 3.5.8 and SVN trunk revision 798811).

The short version is:

1. Protection against recursive inclusion of <iframe>s fails if JavaScript (document.location.replace) is involved (Firefox stops after 10 recursions in this case).

2. The SAP webpage uses document.location.replace for the file in the <iframe>, not for the parent which was probably intended.

3. A regular expression check of parent.location.href fails in the file in the <iframe> in Konqueror, but apparently not in Firefox.

Here is the long version:

It seems that Konqueror actually has some protection against the inclusion of an HTML page in itself using <iframe> as can be seen in this example (save as recursive-iframe.html):

<html><head><title>konqi test</title></head>
<body>
<p>This is the top of a new HTML file.<p>
<p>An iframe starts below this line:</p>
<hr />
<iframe src="recursive-iframe.html" width="95%" height="95%">
</iframe>
</body>
</html>

The page is included just once, then the recursion stops (Firefox stops the recursion even earlier and doesn't include the file at all).

One of the problems in Konqueror is that this protection does not work if the <iframe> includes another HTML file which then replaces itself by the first HTML file using JavaScript (document.location.replace ()). To see this, save this file as recursive-iframe-2a.html:

<html><head><title>konqi test</title></head>
<body>
<p>This is the top of a new HTML file.<p>
<p>An iframe starts below this line:</p>
<hr />
<iframe src="recursive-iframe-2b.html" width="99%" height="99%"></iframe>
</body>
</html>

and this as recursive-iframe-2b.html:

<html><head><title>konqi test</title>
<script type="text/javascript" language="javascript">
  document.location.replace('recursive-iframe-2a.html') 
</script>
</head>
<body>
<p></p>
</body>
</html>

You get an infinite <iframe> recursion in Konqueror (Firefox stops after 10 recursions). This is essentially what happens when that SAP page is opened in Konqueror.

The situation in the SAP page is similar:

The HTML file contains an <iframe> (just like the example recursive-iframe-2a.html), and the included file contains in its <head> the following JavaScript code:

<script type="text/javascript" language="javascript">
try {
var pattern = /^https:\/\/(www(\d{3})?|wwwn|admin|webservice)\.sdn\.sap\.com/;
if (!pattern.test(parent.location.href)) {
  document.location.replace('https://www.sdn.sap.com/irj/sdn/weblogs?blog='
  + escape(document.location.pathname)
  + escape(document.location.search));
}	
} catch (e) { }
</script>

This is apparently a check that should make sure that the page is opened from the SAP webserver and not from some local copy. The mistake in the page is that it then uses 'document.location.replace ()' (instead of replacing the location of the parent) in case of failure, i.e., it replaces the contents of the <iframe> with the first HTML file which contains the <iframe>. This leads to the recursion, but only in Konqueror!

The strange thing is that the regular expression check (!pattern.test(parent.location.href)) fails in Konqueror (but apparently not in Firefox). It's not easy to analyse this with a local copy of the page because parent.location.href yields something different then. I can just say that parent.location.href yields the right offline URL if I use the local copy and that the regular expression check works OK if I replace 'parent.location.href' with the actual URL 

https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/1700

My first guess would be that parent.location.href is for some reason not equal to this URL, but the easy check 

document.write ("parent.location.href = " + parent.location.href);

requires write access to the file on the web server.
Comment 6 Maksim Orlovich 2008-04-20 03:19:14 UTC
Wow, thanks for the phenomenal analysis. I am collecting a whole bunch of issues in this area ATM, and this is an angle I didn't think of... Thankfully testing the last bullet is much easier with a source build..
Comment 7 Martin Steigerwald 2012-03-06 08:10:14 UTC
I am closing this, cause I can´t reproduce this with Konqueror from KDE SC 4.7.4 anymore, neither with webkit nor khtml. The page I mentioned just displays fine. Since I don´t see a fix targeted at this in the comments, I am closing this as "WORKSFORME".

Feel free to reopen when there is still an issue left or adapt resolution to something else as you see fit.

(First comment of mine with new Bugzilla;)