/customers/iconara.net/iconara.net/httpd.www/blog/wp-content/plugins/wp-super-cache/wp-cache-phase1.php Iconara » Abusing the ExternalInterface

Abusing the ExternalInterface

The documentation for the ExternalInterface.call function says that it takes as first argument the name of a JavaScript function. That isn’t really true, you can abuse it and make it run arbitrary code, which is actually very handy.

Before I start thinking aloud on the possibilities of this, let me first show you the proof. Try this code:

ExternalInterface.call("function( ) { alert('weeeha'); }");

Why does this work?

So far I have read the documentation literally, that is, that the first argument should be the name of a JavaScript function. Then it struck me that of course that isn’t so, what it means is that the first argument should resolve to a function in the page’s JavaScript context. The function is then run with the apply-method, passing in the arguments as the second argument. The code above translates to the Flash plug-in calling this JavaScript code:

(function( ) { alert('wheeha'); }).apply(undefined, []);

What this means is that frameworks such as SWFAddress don’t need to be external scripts that you invoke with chunky ExternalInterface calls. Instead they can be written in ActionScript and use ExternalInterface internally to run the necessary JavaScript code when needed. This removes a dependency, which I think is a really good thing.

Another though that came to me was that it would be possible to use JavaScript’s eval function to parse JSON to objects. After a few tries I can conclude that it works, but only if the call to eval is in a function that is actually defined on the page. I couldn’t even make it work by first running some code which created a function which nested the eval function, referencing the eval function in non-direct ways, or any other trick I could think of. It seems to me like there is a security rule against injection of code which uses the eval function, which might not be so bad after all…

Update: I am so stupid. There is no need for the eval-function, simply do this to get an object structure from a JSON string:

var json : String = "{a: 1, b: 'hello world', c: [1, 3, 4, 5]}";

var o : Object = ExternalInterface.call("function( ) { return " + json + ";"}");

The variable o should now contain an object representation of the JSON string json. Don’t do this with data from untrusted sources.

Footnote: this was tested in ActionScript 3 and Firefox, but I’m pretty sure it’s the same in ActionScript 2 and other web browsers.

6 Responses to “Abusing the ExternalInterface”

  1. Ed McManus Says:

    I’d be cautious of using External Interface to parse JSON strings. Complex objects tend to get mangled during Flash’s AMF XML serialization/deserialization process. This is most evident with plug-in versions 9,0,28 and earlier.

    Your best bet is to use Flash’s core library to parse JSON strings. It requires some additional overhead, but not enough to get hung up on.

  2. Theo Says:

    Yes, this was not a serious proposition, as you can see here: http://blog.iconara.net/2007/02/03/parsing-json-using-externalinterface-follow-up/

  3. Dasa Says:

    I found another way to make the call: var o : Object = ExternalInterface.call(“eval”, ‘(‘ + jsonS + ‘)’);

    In my tests with a 12 KB json string, it’s faster in Safari 3.1, but slower in IE 6, than using the as3corelib.

  4. Jeremy Daley Says:

    I like this article.

    Trying eval() on some JS like this though seems to run multiple times: document.getElementsByTagName(‘body’)[0].innerHTML += ‘dude’;

    I can’t figure out why. It’s like it runs on an interval or something.

  5. Jeremy Daley Says:

    Sorry. Let me clarify that… What I meant was that both ways of using ExternalInterface.call():

    ExternalInterface.call(“function() {document.getElementsByTagName(‘body’)[0].innerHTML += ‘dude’; }”);

    and

    ExternalInterface.call(“eval”, “document.getElementsByTagName(‘body’)[0].innerHTML += ‘dude’; “);

    …cause the browser to execute multiple times. Perhaps it has something to do with the DOM changing, I’m not sure.

  6. a_[w] Says:

    It runs with interval because this action ExternalInterface.call(“function() {document.getElementsByTagName(‘body’)[0].innerHTML += ‘dude’; }”); forces to remove all objects that exists in the body and replaces it with the same content, with “dude” added text to last text node. While executing this script your flash application will be removed and new instance will be placed and it will execute the same code and so on.

Leave a Reply