views:

391

answers:

1

My app (under development) uses Safari 4.0.3 and JavaScript to present its front end to the user. The backend is PHP and SQLite. This is under OS X 10.5.8.

The app will from time to time receive chunks of HTML to present to the user. Each chunk is the body of an email received, and as such one has no control over the quality of the HTML received. What I do it use innerHTML to shove the chunk into an iFrame and let Safari render it.

To do that I do this:

window.frames["mainwindow"].window.frames["Frame1"].document.body.innerHTML = myvar;

where myvar contains the received HTML. Now, for the most part this works as desired, and the HTML is rendered as expected. The exception appears to be when the tag for the chunk looks like:

<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" ...

and so on for more than 2800 chars. The effect is as if my JavaScript statement above had not been executed - I can see that using Safari's Error Console in the Develop menu to look into the iFrame. If I extract the HTML from the SQLite backend db and save it as a .html file, then Safari will render that with no trouble.

Any comments on why this might be happening, or on such use of innerHTML, or pointers to discussion of same, would be appreciated.

+1  A: 

innerHTML is not the same as writing a complete document. Even if you write to outerHTML as suggested by Gumbo, there are things outside the root element that can confuse it, such as doctypes. To write a whole document at once, you have to use old-school cross-frame document.write:

var d= window.frames["mainwindow"].window.frames["Frame1"].document;
d.open();
d.write(htmldoc);
d.close();

Each chunk is the body of an email received, and as such one has no control over the quality of the HTML received.

OK, you may have a security problem then.

If you let an untrusted source like an e-mail inject HTML into your security context (and an iframe you're writing to is in your security context), it can run JavaScript of its own, including scripts that reach up and control your entire enclosing application and anything else on the same hostname. Unless your application is so trivial you don't care about that, this is really bad news.

If you need to allow untrusted HTML, the way many webmail services do it is to have it served on a different hostname (eg. a subdomain) that does not have access to any other part of the application. To do this, your iframe src would have to point to the different hostname; you couldn't script between the two security contexts.

bobince
Funnily enough I had arrived at document.write after reading Gumbo's reply and before seeing yours. I also as mentioned in my comment to his reply found I needed to do a bit more data validation, which I've now added. I use NUL, SOH, and STX as data delimiters in my AJAX streams, and one of these was present in that html header.Your comments about security are well taken - thanks. At present I'm writing this largely for my own amusement and to keep doing some technical work since retirement. However I can see I might need to restructure it if I wanted it to have a wider use.Thanks again.
clothears