title: Default/correct context for HTML href attributes in Sightly
body: <p>I'm using Sightly and while investigating a bug in my application I noticed a behaviour I didn't expect.</p>
  <p>Some of the links would render with ampersands in the query string escaped twice. Example:</p>
  <pre><code>&lt;a href=&quot;http://www.google.com?a=1&amp;amp;amp;b=2&amp;amp;amp;c=3&quot;&gt;
      link with explicit attribute context
  &lt;/a&gt;
  </code></pre>
  <p>Upon closer inspection, it turned out we had an <code>org.apache.sling.rewriter.Transformer</code> implementation escaping special characters in all <code>href</code> attributes running in AEM.</p>
  <p>Coupled with Sightly XSS protection, this resulted in double escapes.</p>
  <p>While investigating this further, I disabled the transformer and noticed a strange behaviour in Sightly itself.</p>
  <h2>The attribute context and the default context in href attributes don't match</h2>
  <p>Given the following three elements, I'd expect them to render the <code>href</code> value in the same way (with the query string escaped, consistent with W3C standards)</p>
  <pre><code>&lt;a href=&quot;${'http://www.google.com?a=1&amp;b=2&amp;c=3'}&quot;&gt;no explicit context, expression used&lt;/a&gt;
  &lt;a href=&quot;http://www.google.com?a=1&amp;b=2&amp;c=3&quot;&gt;no explicit context&lt;/a&gt;
  &lt;a href=&quot;${'http://www.google.com?a=1&amp;b=2&amp;c=3' @ context='attribute'}&quot;&gt;
      explicit attribute context
  &lt;/a&gt;
  </code></pre>
  <p>However, only the last one performs the escaping and I get</p>
  <pre><code>&lt;a href=&quot;http://www.google.com?a=1&amp;b=2&amp;c=3&quot;&gt;no explicit context, expression used&lt;/a&gt;
  &lt;a href=&quot;http://www.google.com?a=1&amp;b=2&amp;c=3&quot;&gt;no explicit context&lt;/a&gt;
  &lt;a href=&quot;http://www.google.com?a=1&amp;amp;amp;b=2&amp;amp;amp;c=3&quot;&gt;
      explicit attribute context
  &lt;/a&gt;
  </code></pre>
  <p>For some reason, the the last one, using <code>context='attribute'</code> (the only one that does something with the <code>&amp;</code> characters) escapes the ampersands twice, yielding invalid links.</p>
  <p>This can be achieved with arbitrary element and attribute names so I think I can safely assume this is not some rewriter kicking in.</p>
  <pre><code>&lt;stargate data-custom=&quot;${'http://www.google.com?a=1&amp;b=2&amp;c=3' @ context='attribute'}&quot;&gt;
      attribute context in custom tag
  &lt;/stargate&gt;
  </code></pre>
  <p>Outputs:</p>
  <pre><code>&lt;stargate data-custom=&quot;http://www.google.com?a=1&amp;amp;amp;b=2&amp;amp;amp;c=3&quot;&gt;
      attribute context in custom tag
  &lt;/stargate&gt;
  </code></pre>
  <p>Furthermore, the <a href="https://github.com/Adobe-Marketing-Cloud/sightly-spec/blob/master/SPECIFICATION.md#121-display-context" rel="nofollow noreferrer">Display Context Specification</a> gave me the impression that the context, when rendering an attribute, would be picked up automatically as <code>attribute</code></p>
  <blockquote>
  <p>To protect against cross-site scripting (XSS) vulnerabilities, Sightly automatically recognises the context within which an output string is to be displayed within the final HTML output, and escapes that string appropriately.</p>
  </blockquote>
  <p>Is the observed behaviour here to be expected or am I looking at a potential bug in Sightly?</p>
  <p><strong>Which context should I be using here? All contexts apart from <code>attribute</code> ignore the fact that query strings should be escaped in <code>href</code>. <code>attribute</code> on the other hand appears to be doing this twice. What's going on?</strong></p>
  <p>I'm using <em>Adobe Granite Sightly Template Engine (compatibility)io.sightly.bundle   1.1.72</em></p>
  <h2>The uri context does not escape query strings in the way expected in HTML5 href attributes</h2>
  <p>I did also try using</p>
  <pre><code>&lt;a href=&quot;${'http://www.google.com?a=1&amp;b=2&amp;c=3' @ context='uri'}&quot;&gt;explicit uri context&lt;/a&gt;
  </code></pre>
  <p>But it fails to escape the <code>&amp;</code> chars, resulting in invalid HTML5.</p>
  <pre><code>&lt;a href=&quot;http://www.google.com?a=1&amp;b=2&amp;c=3&quot;&gt;explicit uri context&lt;/a&gt;
  </code></pre>
  <p>Result of validation as HTML5:</p>
  <blockquote>
  <p><strong>Error Line 70, Column 35:</strong> <strong>&amp; did not start a character reference. (&amp; probably should have been escaped as &amp;.)</strong></p>
  <p><code>&lt;a href=&quot;http://www.google.com?a=1&amp;b=2&amp;c=3&quot;&gt;explicit uri context&lt;/a&gt;</code></p>
  </blockquote>
  <h2>The html context correctly renders links with multiple query parameters in href attributes</h2>
  <p>It seems the only context I could possibly use here at the moment is <code>html</code> (<code>text</code> escapes <code>&amp;</code> twice, just like <code>attribute</code>)</p>
  <pre><code>&lt;a href=&quot;${'http://www.google.com?a=1&amp;b=2&amp;c=3' @ context='html'}&quot;&gt;explicit html context&lt;/a&gt;
  </code></pre>
  <p>yields</p>
  <pre><code>&lt;a href=&quot;http://www.google.com?a=1&amp;amp;b=2&amp;amp;c=3&quot;&gt;explicit html context&lt;/a&gt;
  </code></pre>
  <p>Changing to this context would allow me to get the right value in the href, as rendered by the browser. However, it doesn't seem to have the correct semantics.</p>
  <p>To quote <a href="https://github.com/Adobe-Marketing-Cloud/sightly-spec/blob/master/SPECIFICATION.md#121-display-context" rel="nofollow noreferrer">the description of the <code>html</code> context from the Sightly spec</a>:</p>
  <blockquote>
  <p>Use this in case you want to output HTML - Removes markup that may contain XSS risks</p>
  </blockquote>