Glk stylesheets: the Plan

I read the Short Form only, and just wanted to say - this sounds pretty cool.

I mean that JS modules would not be in the blorb file, but in an external library provided by the interpreter. The game could only call those ready-made blocks, not provide its own modules.

But, I’m looking at this from a certain perspective. As long as there’s some way of getting access to JavaScript from the story, I’m happy :slight_smile:

I think the best approach for forward compatibility is to store the JS code in the blorb. That way if future browser incompatibilities make it nonfunctional, someone else could rip the blorb resources, rewrite the JS in a compatible way, and repack the blorb.

I’m not excited about external libraries because then the games are no longer self-contained, and there is a nontrivial version management / change control process that those libraries would have to follow in order to avoid breaking existing games hosted in the same environment.

I have mixed feelings about embedded JS literals. On the one hand I’ve just finished a quick TADS 3 extension that allows an author to do exactly that, and I must say it’s quite liberating to be able to script the entire UI from game logic. On the other hand, there’s some concern about forward compatibility this way.

For Vorple/StructIO what I was imagining is more of an RPC system, rather than a scripting environment. When I implement Glk in StructIO I intend to allow direct access to StructIO too, but it will be via passing commands in JSON or YAML. It will be limited to quite basic element manipulation, but will be there for people who want more than Glk’s windows, paragraphs and spans.

However with this new plan instead of a Vorple API that we access, there could instead be a Vorple library that could be compiled into the blorb. The paragraph IDs are just longing to be used for error folding. The jQuery subset I’ve been talking about will again be an API, but as it will be low level compared to Vorple we won’t have to update it much, or ever. jQuery is frequently updated, but the core of it has been stable for a very long time.

Or you could stick to an API, either within Glk, or parallel to it. But then it would have tricky version management problems as Ben said. I think Vorple might well have a higher rate of change than Glk. (And the Glk rate of change we see now is higher than it’s been in a long time!)

Oh, and I’ve just realised that we can use Web Workers as a much simpler and faster sandbox. They’re quite widely supported now. :slight_smile:

And for non-JavaScript interpreters?

I don’t understand the omission of this straightforward, standard text formatting feature that’s already in HTML/CSS and the Z-machine. IMO, the lack of dynamic styling has always been the weak spot in Glk, and this is the perfect time to fix it. If it’s not going to be in the standard, I hope zarf is still willing to reserve a few selector numbers for it, because I plan to personally add it to every open source interpreter I can build.

Proposed subset of the jQuery API that would not be allowed for web Glk. Only basic AJAX stuff allowed, no direct DOM access.
I’m not sure about the ones with a ?

jQuery.browser ?
jQuery.Callbacks ?
.html ?

I’m not familiar enough with jQuery to know whether this is a good list, or sufficient to resolve security questions.

Are you still thinking of checking code textually, or using a self-hosted Javascript interpreter?

Currently I’m thinking of isolating it by using web workers - it would have all the speed of the browser but wouldn’t have direct DOM access or access to the normal scope.

That sounds like the right plan. I assume you then insert functions into the worker environment that call back to jquery.

Yeah, there would be a kind of proxy API. It doesn’t seem like it will be too complicated, but it will probably be harder than I’m expecting. Most things are!

However I don’t know if it will really accomplish what I want. Web Workers are eventually supposed to get access to IndexedDB (and possibly other database systems too?) meaning they’d have full access to the database. Possibly a self-hosted interpreter may be the only truly safe option.

I’m not sure if it’s even worth it. Asking users to give permission may be enough. If a malicious file got uploaded to the Archive would we be able to request that it be removed?

I don’t see the security issues that big as long as the interpreter is properly hosted (install it to a subdomain to disallow AJAXing other files etc). The most you could do is to mess up other games’ saves or other related local data.

The hosted interpreter model has other issues than security as well, like namespace collisions and running out of cookie space. Perhaps the best approach would be to allow only the most basic (and safe) operations and if the game needs anything else, either have it ask for full permissions or let those games be self-hosted only. Most authors won’t be building their own JavaScript features anyway.

It’s only savefiles and other data, but if we can try to secure the system before someone tries to break it we should. Especially as they could load parchment in an iframe and you wouldn’t even know. And I’d love to sometime in the future allow us to sync local data to a server and between devices, so you could play on a phone or kindle, and then switch to your desktop when you get home.

I also don’t want to push people to host their own stories. I’d like for to play every standard story, and everything can be included in a blorb easily enough. But I don’t want to restrict these features to rare fancy games either. Graham may even want to switch on Vorple by default in some future version of I7. So making users agree to run JS on what could be potentially every future game isn’t ideal either.

A possible alternative to web workers: use the browser’s normal sandboxing by running the main window js in an iframe.

Ugh. Just realised neither web workers nor iframes will work for functions which return a value like $.val().

Looks like I’ll need narcissus. I don’t think static analysis will be reliable enough. If we went down that road we might as well just use a simpler language like lua or something.

Alternative we could drop the idea of having a jQuery compatible API.

An alternative to Narcissus: … y-scripts/

My current plan is to get users to confirm that they want to allow arbitrary JS to run once per file. Annoying, but should be safe enough. We can consider later whether one of these sandboxing options will be functional enough, and whether they’ll be worth it just to stop nagging the users.

I presume that it will be possible for Glk to wait for the user’s confirmation before returning from glk_gestalt?

Yes – it’s awkward, but glk_fileref_create_by_prompt() has to do it so the infrastructure exists.

More brainstorming: JS Blorb resources could be cryptographically signed so that jQuery and Vorple etc could be loaded without hesitation. Unsigned scripts would still be subject to user approval. And subject to a manual inspection other libraries could be signed too. Or we can give access to a website which does the signing to those IF community regulars we trust not to be evil.

If you stick with only allowing access by GlkEntry.receive(), then as long as that function isn’t mapped to eval (which obviously would not be allowed for signed resources) then all bytecode will be safe and the users will only need to be asked for approval for unsigned blorb resources.

I haven’t looked into JS cryptography solutions yet but I assume we could find one sufficiently lightweight. Or write one.

Sounds like you’re reinventing Java and Silverlight.

Maybe. But when we open up the sandbox of the VM we have to do something. And because it’s possible that something like Vorple might one day be included in Inform 7 I’d like to come up with a solution that doesn’t require the user to approve every story file they play, both because it would be annoying, and because it would train people to approve everything without thinking.

Now you could already be evil and write a game which would delete other game’s data files. But web terps are a lot more vulnerable because with an iframe you could do that without the user’s knowledge. (This is possibly already possible? I haven’t tried.) There are other concerns too, because a malicious script could not only delete stuff, but get access to your library/play history etc and send it elsewhere on the net.

Sure, you definitely need some kind of security system if you’re going to let the game pass arbitrary code out to its host. But this is the point in the process where I’d be reconsidering whether that’s worth doing, at least with a JavaScript host. I mean, if you want Java, it’s right over there.

No one wants java. We want html and javascript. Even davec seems to have moved away from silverlight.