| @@ -2,7 +2,7 @@ | |||||
| Place your source `.html` or `.htm` files here or in subfolders. Importing a file stores a new version in the Access database. Images are copied into that version, so later edits to source files do not change an imported snapshot. Keep private campaign artwork under `templates/local/`, which Git ignores. | Place your source `.html` or `.htm` files here or in subfolders. Importing a file stores a new version in the Access database. Images are copied into that version, so later edits to source files do not change an imported snapshot. Keep private campaign artwork under `templates/local/`, which Git ignores. | ||||
| The current importer accepts **well-formed HTML written as XML**. Close every tag and quote every attribute, including `<img ... />` and `<br />`. It accepts basic text, links, tables, and constrained inline `style` attributes. It rejects scripts, forms, external stylesheets, event handlers, remote images, SVG, and CSS image URLs. Image paths must be relative to the HTML file's folder and use PNG, JPEG, or GIF. | |||||
| The current importer accepts **well-formed HTML written as XML**. Close every tag and quote every attribute, including `<img ... />` and `<br />`. It accepts basic text, HTTP/HTTPS and `mailto:` links, tables, and constrained inline `style` attributes. It rejects scripts, forms, external stylesheets, event handlers, remote images, SVG, and CSS image URLs. Image paths must be relative to the HTML file's folder and use PNG, JPEG, or GIF. | |||||
| Example: | Example: | ||||
| @@ -8,13 +8,12 @@ | |||||
| <td style="padding:28px;line-height:1.6;font-size:16px"> | <td style="padding:28px;line-height:1.6;font-size:16px"> | ||||
| <p style="margin-top:0">Hi, I'm sorry to bug you.</p> | <p style="margin-top:0">Hi, I'm sorry to bug you.</p> | ||||
| <p>I'm mailing a big 9x12 postcard to 5,000 homes in Grand Rapids featuring local businesses. I'm looking for a chiropractor to feature. Would that be something you might want to be on?</p> | <p>I'm mailing a big 9x12 postcard to 5,000 homes in Grand Rapids featuring local businesses. I'm looking for a chiropractor to feature. Would that be something you might want to be on?</p> | ||||
| <p>There is a sample ad below:</p> | |||||
| <p>Here is a sample ad:</p> | |||||
| <p style="margin-top:0;margin-bottom:8px"><img src="chiropractor_ad.png" alt="Illustrative chiropractic postcard ad with placeholder practice details" width="540" /></p> | <p style="margin-top:0;margin-bottom:8px"><img src="chiropractor_ad.png" alt="Illustrative chiropractic postcard ad with placeholder practice details" width="540" /></p> | ||||
| <p style="margin-top:0;font-size:12px;color:#48677b">Sample layout; practice name and contact details are placeholders.</p> | |||||
| <p style="margin-bottom:0">To learn more call, reply, or text<br /> | <p style="margin-bottom:0">To learn more call, reply, or text<br /> | ||||
| Daniel Covington<br /> | Daniel Covington<br /> | ||||
| 616-299-7328<br /> | 616-299-7328<br /> | ||||
| <a href="https://www.postcardmojo.com" style="color:#176b9b;text-decoration:underline">www.postcardmojo.com</a> | |||||
| <a href="http://www.postcardmojo.com" style="color:#176b9b;text-decoration:underline">www.postcardmojo.com</a> | |||||
| </p> | </p> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -78,7 +78,7 @@ function Assert-TemplateNode { | |||||
| if ($name -eq 'alt' -and $tag -eq 'img') { continue } | if ($name -eq 'alt' -and $tag -eq 'img') { continue } | ||||
| if ($name -eq 'src' -and $tag -eq 'img') { continue } | if ($name -eq 'src' -and $tag -eq 'img') { continue } | ||||
| if ($name -eq 'href' -and $tag -eq 'a' -and | if ($name -eq 'href' -and $tag -eq 'a' -and | ||||
| $value -match '^(https://[^\s<>"'']+|mailto:[^\s<>"'']+)$') { continue } | |||||
| $value -match '^(https?://[^\s<>"'']+|mailto:[^\s<>"'']+)$') { continue } | |||||
| if ($name -in @('width', 'height', 'border', 'cellpadding', 'cellspacing') -and | if ($name -in @('width', 'height', 'border', 'cellpadding', 'cellspacing') -and | ||||
| $value -match '^[0-9]{1,4}(%|px)?$') { continue } | $value -match '^[0-9]{1,4}(%|px)?$') { continue } | ||||
| if ($name -eq 'align' -and $value -in @('left', 'center', 'right')) { continue } | if ($name -eq 'align' -and $value -in @('left', 'center', 'right')) { continue } | ||||
| @@ -22,7 +22,7 @@ try { | |||||
| $png = [Convert]::FromBase64String('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jRZkAAAAASUVORK5CYII=') | $png = [Convert]::FromBase64String('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jRZkAAAAASUVORK5CYII=') | ||||
| [System.IO.File]::WriteAllBytes($imagePath, $png) | [System.IO.File]::WriteAllBytes($imagePath, $png) | ||||
| $safe = '<html><body><h1 style="color:#112233; font-size:20px">Postcard</h1><p>See our offer.</p><img src="images/logo.png" width="1" height="1" alt="Logo" /><a href="https://example.invalid">Details</a></body></html>' | |||||
| $safe = '<html><body><h1 style="color:#112233; font-size:20px">Postcard</h1><p>See our offer.</p><img src="images/logo.png" width="1" height="1" alt="Logo" /><a href="http://example.invalid">Details</a></body></html>' | |||||
| [System.IO.File]::WriteAllText($templatePath, $safe, [System.Text.Encoding]::UTF8) | [System.IO.File]::WriteAllText($templatePath, $safe, [System.Text.Encoding]::UTF8) | ||||
| & $powerShellX86 -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot 'import-template.ps1') -Path $templatePath -ConfigPath $configPath | & $powerShellX86 -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot 'import-template.ps1') -Path $templatePath -ConfigPath $configPath | ||||
| @@ -40,7 +40,8 @@ try { | |||||
| foreach ($invalid in @( | foreach ($invalid in @( | ||||
| $safe.Replace('<p>See our offer.</p>', '<script>alert(1)</script>'), | $safe.Replace('<p>See our offer.</p>', '<script>alert(1)</script>'), | ||||
| $safe.Replace('images/logo.png', '../secret.png'), | $safe.Replace('images/logo.png', '../secret.png'), | ||||
| $safe.Replace('color:#112233', 'background-image:url(file:///C:/secret)') | |||||
| $safe.Replace('color:#112233', 'background-image:url(file:///C:/secret)'), | |||||
| $safe.Replace('http://example.invalid', 'javascript:alert(1)') | |||||
| )) { | )) { | ||||
| [System.IO.File]::WriteAllText($templatePath, $invalid, [System.Text.Encoding]::UTF8) | [System.IO.File]::WriteAllText($templatePath, $invalid, [System.Text.Encoding]::UTF8) | ||||
| $ErrorActionPreference = 'Continue' | $ErrorActionPreference = 'Continue' | ||||
Powered by TurnKey Linux.