QuickJS is a non-trivial third-party dependency to vendor in, and enables functionality that significantly increases attack surface (which is why it's disabled by default). It should be possible to build a version of chawan without QuickJS, should we not wish to run JS.
-- Seirdy (https://seirdy.one)
Thanks for the feedback :)
QuickJS is a non-trivial third-party dependency to vendor in
Absolutely, and I am not happy about vendoring it either. Until very recently I had little choice, because there did not exist a QJS fork in active development; now I am eyeing quickjs-ng, maybe I will try to upstream changes necessary for JS integration in Chawan there.
and enables functionality that significantly increases attack surface (which is why it's disabled by default).
Yes, enabling execution of remote JS code by default is a bad idea for several reasons. In Chawan's case, it is promoted to a horrible idea for the single reason that we do not have any sandboxing :P
It should be possible to build a version of chawan without QuickJS, should we not wish to run JS.
Disabling anything that depends on the
bindings/quickjs.nim
module does not seem incredibly hard, we could just shim the binding generator macros and put a few metaphorical ifdefs around the code. (I guess it would just take a while to get it done.)The hard part is that Chawan is married to QJS in a few ways that would be difficult to untangle:
- Regex search is based on QuickJS libregexp, so we must keep that part in any case.
Sure, we could use PCRE instead, but that just replaces one external dependency with another :P
Also, QuickJS libunicode is used for Unicode normalization and for retrieval of character classes. OTOH these are "just" smaller auxiliary libraries at 2.5k and 1.5k LOC respectively, that is not much compared to quickjs.c at 54k lines.
- More importantly, pager navigation is completely based on QJS scriptability.
To be clear: this is not the Netscape-style "expose browser controls to websites and hope everything goes well" design, navigation JS code and website-run JS code run in different processes, have access to partly different APIs, and do not know of each other. I could have used any other scripting language, I took JS because linking to one interpreter is less code than linking to two interpreters :)
In fact, we used to have a navigation system more similar to that of w3m (the good old non-turing-complete SCREAMING COMMAND LANGUAGE). I threw it out at some point in favor of what we have now, for reasons that become apparent after using the w3m command language for long enough :P
For getting rid of QJS as a hard dependency, maybe we could add a separate input configuration mode that uses the old-style command language. But I also feel like it would be ugly and/or confusing to accept two different sets of navigation commands depending on compile-time flags... so I'm not sure what the best solution would be here.
Closing this; I remain unconvinced about QJS contributing to the attack surface as it does not run in content processes by default.
Even if the user enables JS, the content process is now syscall-filtered, so it should be reasonably safe. If anything, we would benefit more from a UI to manage which website can run JS - enabling it everywhere shouldn't be the easiest way use it.
Overall, I prefer the approach of "monolithic, just a select few mandatory dependencies" over "modular, many optional dependencies". If you want a browser with a similar scope but subscribing to the latter philosophy, I recommend elinks.