🐕
Corgi
  • 🐕About Corgi
  • 🎓Learning Corgi
    • 📂File Structure
    • 🎉Getting Started
    • 🔟Code
    • 📄Arrow Blocks
    • 🪄If and Switch
    • ✏️Interpolation
    • 🔁For
    • 🤝Attributes
    • 🎭Expressions
    • 👮Security and Escaping
    • 💉Nonce Injection
    • ➡️Block Expansions
    • ➕Mixins
    • 📚Libraries
    • ✨The Standard Library
    • 💬Comments
    • ⛓️Filters
    • 🖨️Include
    • 👪Inheritance (Extending)
    • ⚡Breaking Changes
Powered by GitBook
On this page
  • HTML
  • JavaScript
  • CSS
  • URLs
  • Srcset

Was this helpful?

  1. Learning Corgi

Security and Escaping

PreviousExpressionsNextNonce Injection

Last updated 1 year ago

Was this helpful?

Corgi follows the same security model Go's built-in html/template template engine does. That means, it can contextually escape HTML, CSS, JS, and URL and srcset attributes using the same strategy to determine the type of an attribute. Additionally, corgi also correctly contextually escapes attributes.

Just like Go's engine, corgi assumes that template authors are trusted, but expressions are not.

You can also use pre-escaped expressions by using the types provided in corgi's package.

HTML

Corgi automatically escapes all HTML you write to prevent you from accidentally closing or opening a tag or prematurely ending an attribute.

p(foo=`bar"`) This <p> will be escaped.
<p foo="bar&#34;">This &lt;p> will be escaped.</p>

JavaScript

Corgi prints text in script elements verbatim, only escaping </script> to <\/script> to prevent accidental closing of the script element in strings.

String text in JS attributes will have quotes escaped.

Expressions aof type woof.JS are printed verbatim. Expressions of type woof.JSStr are printed verbatim inside double quotes (with quotes escaped in JS attributes). All other expressions are printed as JSON values.

-
  c := struct{
      A string
      B struct{C int}
    }{
      A: "foo",
      B: struct{C int}{C: 123},
    }
script.
  let a = #{123};
  let b = #{"abc\n"};
  let c = #{c};

button(onclick="f(#{123})")
button(onclick="f(#{"abc\n"})")
button(onclick="f(#{c})")








<script>
  let a = 123;
  let b = "abc\n";
  let c = {"A": "foo", "B": {"C": 123}};
</script>
<button onclick="f(123)"></button>
<button onclick="f(&#34;abc\n&#34;)"></button>
<button onclick="f({&#34;A&#34;: &#34;foo&#34;, &#34;B&#34;: {&#34;C&#34;: 123}})"></button>

CSS

Just like inside script elements, text inside style elements is also printed verbatim, only escaping </style> to <\/style> to prevent accidental closing of the script element in strings.

When writing expressions, the value is escaped/filtered using woof.FilterCSS unless it is of type woof.CSS.

URLs

Like any other attribute, attributes containing URLs will always have quotes escaped.

Additionally, corgi filters out URLs with interpolated protocols/expressions with protocols other than http, https, tel, or mailto.

String text is normalized, keeping valid percent escapes, but percent escaping runes that haven't yet been.

Expressions before the start of queries are also just normalized, after the start of queries expressions will be escaped so that they form a valid URL query parameter value.

- searchEngine := "google.com/search"
  q := corgis <3
a(href="https://#{searchEngine}?q=#{q}") Search Google
- danger := "ftp://foo.com"
a(href=danger) Don't click me!


<a href="https://
google.com/search?q=corgi%20%3c3">Search Google</a>

<a href="#ZcorgiZ">Don't click me!</a>

Srcset

URLs in srcset attributes are escaped using the same strategy as URL attributes.

🎓
👮
htmx
woof