[racket] Escaping things in templates?

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Sat Oct 22 23:29:44 EDT 2011

web-server/template and Scribble produce strings, that's why you
create a response by plopping in the string from include-template. The
Web Server has no idea what kind of string you making, so it imposes
no special XML rules.

The template-less version your servlet does exactly what you seem to want:

#lang web-server/insta

(require web-server/templates)

(define (start req)
  (let ([some-input
         (if (exists-binding? 'some-input (request-bindings req))
          (extract-binding/single 'some-input (request-bindings req))
          "nothing yet")])
       (head (title "Testing"))
        (h1 "You said:" ,some-input)
        (form ([method "get"] [action "#"])
              (input ([name "some-input"] [type "text"]))
              (input ([type "submit"]))))))))

But if you want to use templates to produce XML strings and get XML
quoting, then you have to quote explicitly by treating your user's
string as if it is a string Xexpr (the representation for XML in the
Web Server):

#lang web-server/insta

(require web-server/templates

(define (start req)
  (let ([some-input
          (if (exists-binding? 'some-input (request-bindings req))
              (extract-binding/single 'some-input (request-bindings req))
              "nothing yet"))])
    (response/full 200 #"Okay" (current-seconds) TEXT/HTML-MIME-TYPE
                   (list (string->bytes/utf-8 (include-template

Notice the addition of the (require xml) and the single call to
(xexpr->string ...) around the user's input.


On Sat, Oct 22, 2011 at 8:38 PM, Michael W <mwilber at uccs.edu> wrote:
> Hello! Thanks for making racket! It's the coolest.
> The web server template documentation:
> http://docs.racket-lang.org/web-server/templates.html has several
> great examples of templates, but it doesn't mention whether
> strings included in templates are entity-escaped XML or not.
> More seriously, searching for "escape" in the help desk doesn't
> even mention anything useful. It looks like the only way of
> creating templates that escape the variables included in them is
> by adding (require xml/private/writer) to the top of your script
> and saying @escape[foo escape-table] every single time you use a
> variable in your templates! Surely there must be a better way?
> Am I doing it wrong? Take a look at this simple servlet, which
> simply spits out what you type in a form:
> https://gist.github.com/1306759 Try typing <u>test</u> for
> example, or perhaps some javascript.
> Certain web frameworks try to implicitly protect you from these
> kinds of mistakes. Take Django, for example.
> https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs
> The Django team are so upfront about their template system's
> escaping behavior that it's literally the first thing they
> mention in the first section of their documentation.
> Other template systems intentionally make it harder to include
> unescaped content by using syntactic differentiation. Mustache,
> for example, requires you to use triple braces like
> {{{some-input}}} if you want to include some-input as unescaped.
> https://github.com/janl/mustache.js/
> What's the best way of solving this? Obviously we can't change
> scribble, but could we have, say, (include-template) add an
> @escape[...] function to the namespace just before it evaluates
> the template?
> If I'm missing something, please feel free to flame away. ;) If
> not, I'd love to help fix this by writing a patch or some
> documentation or something.
> Thanks again for such a nice framework.
> --
> For the Future!
>    _mike
> _________________________________________________
>  For list-related administrative tasks:
>  http://lists.racket-lang.org/listinfo/users

Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University

"The glory of God is Intelligence" - D&C 93

Posted on the users mailing list.