;; lib/dream/tests/html.sx — HTML escaping (+ demo XSS regression). (define dream-ht-pass 0) (define dream-ht-fail 0) (define dream-ht-fails (list)) (define dream-ht-test (fn (name actual expected) (if (= actual expected) (set! dream-ht-pass (+ dream-ht-pass 1)) (begin (set! dream-ht-fail (+ dream-ht-fail 1)) (append! dream-ht-fails {:name name :actual actual :expected expected}))))) (dream-ht-test "escape ampersand" (dream-escape "a & b") "a & b") (dream-ht-test "escape lt gt" (dream-escape "") "<b>") (dream-ht-test "escape quote" (dream-escape "say \"hi\"") "say "hi"") (dream-ht-test "escape apostrophe" (dream-escape "it's") "it's") (dream-ht-test "escape script tag" (dream-escape "") "<script>alert(1)</script>") (dream-ht-test "ampersand first (no double-escape)" (dream-escape "<") "&lt;") (dream-ht-test "safe string unchanged" (dream-escape "hello world") "hello world") (dream-ht-test "attr escapes value" (dream-attr "title" "a\"b") "title=\"a"b\"") (dream-ht-test "escape-join" (dream-escape-join " " (list "" "")) "<a> <b>") ;; ── todo demo escapes user input (XSS regression) ────────────────── (define dream-ht-store (dream-todo-store)) ((get dream-ht-store :add) "") (define dream-ht-ctx (assoc (dream-request "GET" "/" {} "") :dream-csrf {:sign dream-csrf-sign-default :sid "s1" :secret "k"})) (define dream-ht-rendered (dr/todo-render dream-ht-store dream-ht-ctx)) (dream-ht-test "todo escapes script" (contains? dream-ht-rendered "<script>") true) (dream-ht-test "todo has no raw script" (contains? dream-ht-rendered "