On Fri, Aug 7, 2009 at 12:11 AM, Daniel Wagner-Hall<[email protected]> wrote: > > On Fri, Jul 31, 2009 at 5:57 PM, Aaron Boodman<[email protected]> wrote: >> >> On Fri, Jul 31, 2009 at 5:14 PM, Daniel Wagner-Hall<[email protected]> >> wrote: >>> I suppose only allowing contentWindow.eval and not any other interaction >>> with the page's JS would significantly restrict the ability to take over >>> the extension (notably where that ability was only there through >>> laziness/oversight), and hopefully ensure that extension writers >>> properly thought about the consequences of direct page interaction when >>> they wrote it. While it would leave a hole open, it is a much lesser >>> hole, and I believe a significantly useful one. >> >> You can probably setup two-way communication between the content >> script and the js context of the page by using DOM events as a side >> channel. This is something I've heard of people doing in Firefox. >> >> We'll keep thinking about ways to make a (small) first-class hole >> between content scripts and the page, but I think it is a minority use >> case. > > I would like to propose a modification to the API such that there is > an additional method available to content scripts, > executeScriptInPageContext(script[, timeout][, args]). |script| is > the script to be executed as a string. |timeout| is an optional number > of milliseconds after which to give up on the script. |args| is an > optional JSON representation of an array of any args to be passed to > the script. We could make do without the args entirely. I've hacked > together a way of doing this by script tag injection on the DOM (see > below). > > I think it would be *much* nicer if we provided this functionality > directly, rather than expecting extension developers to do it manually > themselves, and this would make it clear that only things wrapped up > in text can be put to the page, or gotten from the page (i.e. objects > cannot be shared). This could be very easily implemented as a > callback-style function (like all the tab and window functions), > though if it could be its own function which simply returns a value, > that would be nicer... I'm not sure how this would be directly > implemented in Chrome, but the javascript is easy enough...
I agree something like this would be nice to add. I think the use cases we've seen could be met by: a) Allowing extensions to opt-into accepting messages from websites (discussed on a previous thread). This would cover the use case of wanting to expose API to websites. b) Providing a convenience function to execute JS in the page context and get a serialized result. We already have a contributor who has volunteered to implement something close to b): http://code.google.com/p/chromium/issues/detail?id=12465. It could probably be adapted to also allow executing short snippets of code in the page context and return serialized results. The fact that you accidentally XSS'd yourself on your first try and implementing this technique (see below) definitely concerns me. > Currently, my executeScriptInPageContext(script) method looks roughly like: > var scriptTag = document.createElement('script'); > //The below may be lacking some required escaping > scriptTag.innerText = 'var e = document.createEvent("MutationEvent");' + > 'var args = "' + args + '";' + > 'var val = eval(' + script + ').apply(window, > JSON.parse(args));' + > 'if (typeof(val) == "string") { val = \'"\' + > val + \'"\'; }' + > 'e.initMutationEvent("DOMAttrModified", true, > false, THIS_ELEMENT, null, "function() { return " + val + "}", null, > 0);' + > 'THIS_ELEMENT.dispatchEvent(e);'; > scriptTag.addEventListener('DOMAttrModified', > returnFromJavascriptInPage, false); > document.getElementsByTagName("body")[0].appendChild(scriptTag); > > I'm getting THIS_ELEMENT by attaching a UUID as the ID of the script > tag and getting element by that, but I'm sure there is a way to do it > without needing an ID... > > My returnFromJavascriptInPage(e) function basically reduces to: > //[Remove the element from the DOM (I'm doing this by ID, but could > use a reference to the element from the event] > return eval(e.newValue)(); You probably don't mean to be eval()'ing code from the interwebs in a privileged extension context, right? ;-). JSON.parse would probably be a better choice here. - a --~--~---------~--~----~------------~-------~--~----~ Chromium Developers mailing list: [email protected] View archives, change email options, or unsubscribe: http://groups.google.com/group/chromium-dev -~----------~----~----~----~------~----~------~--~---
