I originally wrote this up as a GitHub issue, but I want to make sure I'm not missing anything by emailing this list first.
It would be nice if it was easier to rewrite `html/template` files but the current tools (`html/template` and `x/net/html`) seem to have a gap between them. Maybe there's a way to do this that I've missed, so let me explain the problems I wanted to solve in detail. I'm trying to make it easy to support CSP inline hashing in my templates without nagging users and requiring them to remember to use some custom funcs instead of the usual HTML. It'd also be nice to have form-based CSRF protection which would be implemented in a similar way. I'm sure there are other similar rewrites, but these security-focused ones were the first I've run into. Both CSP inline hashing and form-based CSRF protection involve a developer adding additional attributes or elements to a template. In the CSP inline hashing case, it's an attribute or nonce added `script` tags. In form-based CSRF protection, it can be a hidden `input` that sends up a per-request token inside a `form` tag. It would be nice to be able to, at parse time, not execution time, pull apart a `html/template` template, inspect it for the relevant tags, and then change the template for the user instead of returning an error if they forgot the important elements. At parse time, the code has all the data it needs to adjust the template. Similar to why `gofmt` is capable of rewriting a file, not just telling a developer how to adjust the file, adjusting a template automatically instead of telling them they made an error would a much nicer experience for the developer. In the form-based CSRF case, the template rewrite would be adding a `input` tag that calls a template func (or struct value) that has the token data. In the CSP inline hashing case, the rewrite would be detecting if the `script` tag contained only static information and adding the hash automatically, or returning an error if the developer needs to get involved (usually, to handle the case of requesting javascript files from elsewhere on the web). However, `html/template` only has `text/template/parse` as its AST which doesn't suffice for working at the level of HTML semantics. Folks have offered up `x/net/html`'s `ParseFragment` as a solution but that doesn't work well. One problem is that `x/net/html`'s `ParseFragment` makes it difficult to render exactly back what was in a template. Without providing a context `*html.Node`, you'll get back a tree with additional bogus nodes added around the outside. This doesn't work well because rewriting code may need to behave differently depending on what context `*html.Node` is in play instead of guessing that all templates are in `body` or whatever. But calculating that context `*html.Node` is difficult since a template can be loaded from other templates. That would involve writing similar template loading code to what is already inside `text/template`. A second problem since some of those templates will be called in different escaping contexts, folks using `ParseFragment` have to re-do the escape context code in `html/template` within `x/net/html`'s AST. I haven't found a way to make my templates better without requiring the developer to handle more of what would otherwise be easily automated problems. Is there an obvious solution I'm missing that doesn't involve giving up context escaping and the other goodies by using an alternate templating library? -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.