"I built a web language with Haskell-like syntax for fun

I’ve been building a web language with Haskell-like syntax and a PHP-like execution model server/client separation in the same file. It’s not complete but it’s functional. Built it mostly for fun rather than to solve any specific problem. Leaving it here in case anyone finds it interesting.

5 Likes

Looks Cool!

I was wondering, how hard would it be to cut out the PHP-style parsing of HTML interleaved with code into some standalone reusable functionality? I assume people would love to plug in various custom other ad-hoc DSLs into this scheme.

(I guess there’s a lot of gotchas, mainly syntax collisions with the magic brackets, but perhaps there’s some unexplored design space there.)

1 Like

That’s an interesting direction I hadn’t considered. Interpolating is technically separable from Haskell evaluation; it’s really just a matter of parsing the boundaries between HTML and embedded expressions. With Megaparsec, you could probably abstract it into a generic interface with its own built-in evaluator. I’m not sure how clean it would be in practice, but it’s worth exploring. Would you be interested in something like that?

Out of curiosity, do you expect this to ever become production ready?

1 Like

Fun to build, but yes — production ready is the goal.

Yeah I thought something structured, like the HTML ADT from Lucid with the extra “language” mixed in that. (Or perhaps the language AST intermixed with Lucid structure?)

1 Like

I actually built a small QuasiQuotes library for the HTML parsing — partly to avoid the Lucid dependency, partly to keep the syntax closer to actual HTML. Though it could probably be adapted to work with Lucid as well.

I’ve just published an updated documentation with more examples and features. Thanks for your support.

If you plan to publish this as “production ready”, I would urge you to think about how you want to avoid PHP’s billion dollar mistake. I’m talking about interpolating strings into HTML output, leaving the burden of making sure they are properly HTML-encoded to the programmer.

The first example in the README is actually just one step short of illustrating how this can easily lead to XSS vulnerabilities. All you need to do is change the name argument to a user-provided string; now an attacker can pass a malicious name (e.g. <script>doSomethingBad();</script>world) to run arbitrary JavaScript in the context of your website’s domain.

Since you already have distinct constructors VHtml and VString, the fix should be relatively straightforward: in the valueToHtml function, apply HTML-encoding when converting a VString or VOther. This way, anything that’s supposed to already be HTML-encoded (VHtml values) will remain unaffected, while raw strings (VString) and values that result from applying show (VOther) will be HTML-encoded, as they should. You could then expose an unsafeRawHtml function that wraps its argument in VHtml, as an escape hatch for user code that wants to inject pre-encoded HTML from elsewhere, with the understanding that this is “unsafe” and requires you to verify the pre-encoded HTML yourself somehow.

PHP does this wrong, and it’s causing a lot of unnecessary issues; but you are in a position to easily fix this.

2 Likes

Are you suggesting that when converting a VString or VOther to HTML, I should automatically escape characters like <, >, &, and " to their HTML entities, while leaving the VHtml values ​​unescaped since they are already valid HTML, Although that would break the idea of ​​returning HTML, it could also be avoided by escaping the <script,src,etc sequence, I suppose not?
So, in the case that the instruction breaks due to a string, that’s what you mean… because as such, when wrapping in VHTML, it could be escaped directly if it’s a normal String.

Fixed…
Thank you for FeedBack