# Security and Escaping

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 [htmx](https://htmx.org) 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 [`woof`](https://pkg.go.dev/github.com/mavolin/corgi/woof) package.

## HTML

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

{% tabs %}
{% tab title="Corgi" %}
```pug
p(foo=`bar"`) This <p> will be escaped.
```
{% endtab %}

{% tab title="HTML" %}
```markup
<p foo="bar&#34;">This &lt;p> will be escaped.</p>
```
{% endtab %}
{% endtabs %}

## 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.

{% tabs %}
{% tab title="Corgi" %}
{% code lineNumbers="true" %}
```pug
-
  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})")
```
{% endcode %}
{% endtab %}

{% tab title="HTML" %}
{% code overflow="wrap" lineNumbers="true" %}
```markup








<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>
```
{% endcode %}
{% endtab %}
{% endtabs %}

## 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.

{% tabs %}
{% tab title="Corgi" %}
```pug
- 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!
```
{% endtab %}

{% tab title="HTML" %}
```markup


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

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


{% endtab %}
{% endtabs %}

## Srcset

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