# QA-15, SEC-12..15, MIM-15: mail-specific vectors. Nothing in a message may cause a
# request before the user allows it -- images, backgrounds, fonts, prefetch hints,
# favicons, refreshes -- and a sender may not forge the pipeline's remote-slot URLs.

== remote-img-slotted
expect: remote=1 slot-refs=1 blocked-min=1 keeps-text=SAFE
--
<img src="https://e.test/a.png" alt="x">SAFE

== remote-img-http-slotted
expect: remote=1 slot-refs=1 blocked-min=1 keeps-text=SAFE
--
<img src="http://e.test/a.png">SAFE

== remote-img-dedupe-order
source: one slot per distinct URL, in document order
expect: remote=2 slot-refs=3 blocked-min=2 keeps-text=SAFE remote0=https://e.test/1.png remote1=https://e.test/2.png
--
<img src="https://e.test/1.png"><img src="https://e.test/2.png"><img src="https://e.test/1.png">SAFE

== remote-img-uppercase-scheme
expect: slot-refs=1 keeps-text=SAFE
--
<img src="HTTPS://E.TEST/A.PNG">SAFE

== remote-img-no-slashes
source: WHATWG reads https:e.test/a.png as https://e.test/a.png (special scheme)
expect: keeps-text=SAFE
--
<img src="https:e.test/a.png"><img src="https:/e.test/b.png"><img src="https:\\e.test\c.png"><img src="http:e.test/d.png">SAFE

== remote-img-entity-scheme
expect: slot-refs=1 keeps-text=SAFE
--
<img src="&#104;ttps://e.test/a.png">SAFE

== remote-img-leading-c0
source: a raw leading C0 control is U+FFFD after decoding (QA-30 raw column): inert, never loaded
expect: remote=0 slot-refs=0 keeps-text=SAFE
--
<img src="\x{1}https://e.test/a.png">SAFE

== remote-img-tab-in-scheme
source: a conformant parser removes the tab: this is a remote image
expect: slot-refs=1 keeps-text=SAFE
--
<img src="ht&#9;tps://e.test/a.png">SAFE

== remote-img-crlf-in-url
source: header injection through a URL the engine will fetch
expect: keeps-text=SAFE
--
<img src="https://e.test/a.png&#13;&#10;X-Injected: 1">SAFE

== remote-img-protocol-relative
expect: keeps-text=SAFE
--
<img src="//e.test/a.png"><img src="\\e.test\a.png"><img src="/\e.test/a.png">SAFE

== remote-img-relative-with-base
source: base is dropped; a relative src must not survive as a resource either
expect: no-element=base keeps-text=SAFE
--
<base href="https://e.test/"><img src="a.png">SAFE

== remote-img-userinfo
source: a URL carrying credentials is not fetched at all (Track D's choice; counted)
expect: remote=0 slot-refs=0 blocked-min=1 keeps-text=SAFE
--
<img src="https://user:pass@e.test/a.png">SAFE

== remote-img-inside-link
expect: remote=1 slot-refs=1 has-attr=href keeps-text=SAFE
--
<a href="https://e.test/"><img src="https://e.test/img.png">SAFE</a>

== remote-link-only
source: a link is not remote content: it stays and nothing is blocked
expect: remote=0 has-attr=href keeps-text=SAFE
--
<a href="https://e.test/page">SAFE</a>

== forged-slot
expect: remote=0 slot-refs=0 no-cid-prefix=hoarse-remote- keeps-text=SAFE
--
<img src="cid:hoarse-remote-0">SAFE

== forged-slot-with-real-remote
source: the forged reference must not alias the real slot 0
expect: remote=1 slot-refs=1 no-cid-prefix=hoarse-remote- keeps-text=SAFE
--
<img src="cid:hoarse-remote-0"><img src="https://e.test/a.png">SAFE

== forged-slot-variants
source: case, entity, whitespace and padding variants of a slot URL
expect: remote=0 slot-refs=0 no-cid-prefix=hoarse-remote- keeps-text=SAFE
--
<img src="CID:hoarse-remote-0"><img src="cid:HOARSE-REMOTE-0"><img src=" cid:hoarse-remote-0"><img src="cid:hoarse&#45;remote-0"><img src="cid:hoarse-remote-00"><img src="cid:hoarse-remote-0?x"><img src="cid:hoarse-remote-1"><img src="cid:hoarse-remote-99999999"><img src="cid:hoarse-remote-"><img src="c&#x09;id:hoarse-remote-0"><img src="cid:%68oarse-remote-0">SAFE

== forged-slot-in-other-attrs
expect: slot-refs=0 no-cid-prefix=hoarse-remote- keeps-text=SAFE
--
<a href="cid:hoarse-remote-0">SAFE</a><table background="cid:hoarse-remote-0"><tr><td>t</td></tr></table>

== cid-kept-and-listed
source: SEC-15: a sender's own cid: stays and is listed for local resolution
expect: cids=logo@e.test,part2@e.test remote=0 keeps-text=SAFE
--
<img src="cid:logo@e.test"><img src="cid:part2@e.test"><img src="cid:logo@e.test">SAFE

== background-attr-remote
expect: remote=0 blocked-min=2 keeps-text=SAFE
--
<table background="https://e.test/bg.png"><tr><td background="http://e.test/td.png">SAFE</td></tr></table>

== css-background-remote
expect: no-css-value=url( remote=0 blocked-min=1 keeps-text=SAFE
--
<div style="background:#fff url(https://e.test/bg.png) no-repeat">SAFE</div>

== css-background-image-remote
expect: no-css-value=url( remote=0 keeps-text=SAFE
--
<div style="background-image:url('https://e.test/bg.png')">SAFE</div>

== css-block-background-remote
expect: no-css-value=url( remote=0 keeps-text=SAFE
--
<style>td{background-image:url(https://e.test/bg.png)}</style><table><tr><td>SAFE</td></tr></table>

== css-hover-tracking
source: a :hover background used as a read/hover beacon
expect: no-css-value=url( remote=0 keeps-text=SAFE
--
<style>a:hover{background:url(https://e.test/hovered.gif)}</style><a href="https://e.test/">SAFE</a>

== css-print-tracking
source: @media print beacons when the message is printed
expect: no-css-value=url( keeps-text=SAFE
--
<style>@media print{body{background:url(https://e.test/printed.gif)}}</style><p>SAFE</p>

== webfont-face
expect: no-css-value=url( remote=0 keeps-text=SAFE
--
<style>@font-face{font-family:Tracker;src:url(https://e.test/f.woff2) format('woff2')}p{font-family:Tracker}</style><p>SAFE</p>

== css-import-block
expect: no-css-value=@import no-css-value=url( remote=0 keeps-text=SAFE
--
<style>@import url(https://e.test/a.css);@import 'https://e.test/b.css';p{color:red}</style><p>SAFE</p>

== meta-refresh
source: OWASP (META refresh)
expect: no-element=meta keeps-text=SAFE
--
<meta http-equiv="refresh" content="0;url=https://e.test/">SAFE

== meta-refresh-js
expect: no-element=meta no-scheme=javascript keeps-text=SAFE
--
<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert(1);">SAFE

== meta-refresh-data
expect: no-element=meta no-scheme=data keeps-text=SAFE
--
<meta http-equiv="refresh" content="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg">SAFE

== meta-link-header-setcookie-csp
expect: no-element=meta keeps-text=SAFE
--
<meta http-equiv="Link" content="&lt;https://e.test/a.css&gt;; rel=stylesheet"><meta http-equiv="Set-Cookie" content="a=b"><meta http-equiv="Content-Security-Policy" content="default-src *">SAFE

== link-prefetch-family
source: SEC-14 names prefetch hints and favicons
expect: no-element=link remote=0 keeps-text=SAFE
--
<link rel="preload" href="https://e.test/a.png" as="image"><link rel="prefetch" href="https://e.test/b"><link rel="dns-prefetch" href="//e.test"><link rel="preconnect" href="https://e.test"><link rel="icon" href="https://e.test/favicon.ico"><link rel="shortcut icon" href="https://e.test/f.ico"><link rel="apple-touch-icon" href="https://e.test/t.png"><link rel="modulepreload" href="https://e.test/m.js"><link rel="stylesheet" href="https://e.test/s.css"><link rel="import" href="https://e.test/i.html">SAFE

== srcset-remote
expect: no-attr=srcset slot-refs=0 keeps-text=SAFE
--
<img srcset="https://e.test/a.png 1x, https://e.test/b.png 2x" src="cid:a@e.test">SAFE

== srcset-and-sizes
expect: no-attr=srcset no-attr=sizes keeps-text=SAFE
--
<img src="https://e.test/a.png" srcset="https://e.test/b.png 300w" sizes="100vw">SAFE

== picture-source
expect: no-element=picture no-element=source keeps-text=SAFE
--
<picture><source srcset="https://e.test/a.webp" type="image/webp"><img src="https://e.test/a.png"></picture>SAFE

== video-poster
expect: no-attr=poster no-element=video keeps-text=SAFE
--
<video poster="https://e.test/poster.png" src="https://e.test/v.mp4"></video>SAFE

== input-image
expect: no-element=input remote=0 keeps-text=SAFE
--
<input type="image" src="https://e.test/i.png">SAFE

== object-embed-iframe-remote
expect: no-element=object no-element=embed no-element=iframe remote=0 keeps-text=SAFE
--
<object data="https://e.test/x.pdf"></object><embed src="https://e.test/x.swf"><iframe src="https://e.test/"></iframe>SAFE

== img-lowsrc-dynsrc-longdesc-remote
expect: no-attr=lowsrc no-attr=dynsrc no-attr=longdesc keeps-text=SAFE
--
<img src="cid:a@e.test" lowsrc="https://e.test/l.png" dynsrc="https://e.test/d.avi" longdesc="https://e.test/desc">SAFE

== a-ping-remote
expect: no-attr=ping has-attr=href keeps-text=SAFE
--
<a href="https://e.test/" ping="https://e.test/ping">SAFE</a>

== img-mailto-src
expect: keeps-text=SAFE
--
<img src="mailto:x@e.test">SAFE

== tracking-pixel-1x1
source: Q11: dropped by the simplifier, so its slot is never fetched
expect: remote=1 simplified-slots=0 pixels-min=1 keeps-text=SAFE
--
<p>SAFE</p><img src="https://t.e.test/open.gif?u=123" width="1" height="1" border="0">

== tracking-pixel-hidden
expect: simplified-slots=0 pixels-min=1 keeps-text=SAFE
--
<p>SAFE</p><img src="https://t.e.test/open.gif?u=123" style="display:none">

== tracking-pixel-css-size
expect: simplified-slots=0 pixels-min=1 keeps-text=SAFE
--
<p>SAFE</p><img src="https://t.e.test/open.gif?u=123" style="width:1px;height:1px">

== tracking-pixel-zero
expect: simplified-slots=0 pixels-min=1 keeps-text=SAFE
--
<p>SAFE</p><img src="https://t.e.test/open.gif?u=123" width="0" height="0">

== slot-in-text-revives-pixel
source: found by E against the real pipeline: text spelling a slot URL revives a dropped pixel
expect: remote=1 simplified-slots=0 pixels-min=1 keeps-text=SAFE
--
<p>SAFE</p><img src="https://t.e.test/open.gif?u=42" width="1" height="1"><p>src="cid:hoarse-remote-0"</p>

== slot-in-text-out-of-range
expect: remote=0 simplified-slots=0 keeps-text=SAFE
--
<p>SAFE src="cid:hoarse-remote-7"</p>

== not-a-pixel
source: a real image keeps its slot through the simplifier
expect: remote=1 simplified-slots=1 keeps-text=SAFE
--
<p>SAFE</p><img src="https://e.test/photo.jpg" width="400" height="300">

== slot-of-image-dropped-by-table-flattening
source: found by the one-hour fuzz run: an image hoisted out of caption into table is not drawn but its slot is fetched
expect: simplified-slots=0 keeps-text=SAFE
--
SAFE<table><td><caption><img src="https://e.test/beacon.png"></caption></td></table>
