Как декодировать Base64 в HTML
- Вставьте Base64 в поле Base64 или data URI. URI
data:text/html;base64,тоже подойдёт. Большое тело письма, сохранённое как текст, откройте кнопкой Открыть файл .txt. - В сведениях показаны кодировка и число строк. Ниже во фрейме-песочнице отображается отрисованная страница с подсказкой «Предпросмотр в песочнице: скрипты, формы и внешние ресурсы заблокированы. Исходный код ниже.»
- В блоке Текст под превью лежит исходный код. Скопировать текст копирует его целиком.
- Нажмите Скачать файл, чтобы сохранить
decoded.html.
Ничего никуда не отправляется. Декодирование идёт в браузере, а странице запрещено выполнять сетевые запросы, кроме счётчика просмотров Cloudflare.
Зачем превью в песочнице
HTML из неизвестного источника бывает и документом, и программой. Тело письма может нести пиксель отслеживания, который сообщает, когда и где письмо открыли; фишинговая страница может содержать форму входа, которая отправляет данные злоумышленнику; любая страница может запускать скрипты. Превью устроено так, чтобы ничего из этого не произошло:
| Угроза | Что её останавливает |
|---|---|
Скрипты, включая встроенные onclick и <script> | У iframe есть атрибут sandbox без разрешений, поэтому скрипты не запускаются |
| Формы, отправляющие пароли | Песочница не разрешает отправку форм |
| Всплывающие окна и перенаправление основной страницы | Запрещены песочницей |
| Чтение этой страницы или её хранилища | Содержимое песочницы получает уникальный origin без доступа к чему-либо |
| Пиксели отслеживания, внешние картинки, шрифты и CSS | Политика безопасности контента страницы блокирует любой запрос к другому серверу |
Политика блокирует и встроенные стили, поэтому превью выглядит просто. Картинки, встроенные как URI data:, разрешены и показываются нормально. Текст, ссылки и структура сообщения на месте, но выглядят проще, чем в почтовом клиенте.
Страницы больше 2 MB не отображаются («Документ слишком большой для предпросмотра. Смотрите исходный код ниже или скачайте файл»). Блок исходного кода показывает первые 256 KB любого документа; Скопировать текст копирует весь исходный код документов размером до 8 MB.
Как узнать HTML в Base64
| Base64 начинается с | Начало после декодирования |
|---|---|
PCFET0NUWVBFIGh0bWw | <!DOCTYPE html |
PCFkb2N0eXBlIGh0bWw | <!doctype html |
PGh0bWw | <html |
77u/PCFET0NUWVBF | Метка порядка байтов UTF-8, затем <!DOCTYPE |
CjwhRE9DVFlQRS | Перенос строки, затем <!DOCTYPE |
PGRpdg, PHA+ | <div, <p>: фрагмент HTML, определяется как HTML |
Кодировка определяется по байтам: метка порядка байтов, UTF-16, корректный UTF-8 или, в крайнем случае, Windows-1252. Тег <meta charset> внутри документа не учитывается, поэтому у страницы в другой устаревшей кодировке (например, Windows-1251 или KOI8-R) в превью могут поехать буквы, а скачанный файл сохранит исходные байты.
Откуда берётся HTML в Base64
Почта. HTML-версия письма часто лежит в MIME-части с Content-Type: text/html и Content-Transfer-Encoding: base64. Вставьте сюда только закодированные строки этой части или откройте всё исходное письмо в декодере EML, который показывает все части и вложения. Структура объясняется в статье Base64 в электронной почте.
Вебхуки и API. Некоторые сервисы, которые принимают или отрисовывают письма, отдают HTML-тело полем Base64 в JSON, а API шаблонов и рендеринга PDF иногда так же возвращают сгенерированный HTML. Декодирование Base64 внутри JSON разбирает всю полезную нагрузку за раз.
URI data:text/html. Фишинговые рассылки используют их, чтобы уместить целую поддельную страницу входа в ссылку или вложение. Если вставить такой URI сюда, страница отобразится, но не запустится. Как собирать такие URI, смотрите на странице HTML в Base64.
Как показать недоверенный HTML в своём приложении
Тот же подход работает на любой веб-странице: декодируйте и поместите результат в iframe с пустым атрибутом sandbox. Сама по себе песочница не мешает загрузке внешних картинок и таблиц стилей, поэтому добавьте в начало политику безопасности контента для фрейма:
function previewHtml(b64, container) {
const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
const html = new TextDecoder().decode(bytes);
const csp = `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src data:; style-src 'unsafe-inline'">`;
const frame = document.createElement("iframe");
frame.setAttribute("sandbox", "");
frame.srcdoc = csp + html;
container.append(frame);
}
В Chrome тестовая страница со скриптом, внешней таблицей стилей и внешней картинкой с этой функцией не выполнила ни одного скрипта и не сделала ни одного запроса; без строки <meta> картинка и таблица стилей загрузились. В отличие от превью на этой странице, функция сохраняет встроенные стили. Подробнее в статье Base64 в JavaScript.
Вопросы и ответы
Как декодировать Base64 в HTML?
Вставьте строку в поле выше. Исходный код HTML появится в блоке Текст, над ним откроется превью в песочнице, а Скачать файл сохранит его как файл .html.
Безопасно ли смотреть здесь HTML из фишингового письма?
В превью выключены все разрешения песочницы: скрипты не выполняются, формы не отправляются, а политика безопасности контента (CSP) страницы не даёт загрузить ничего из интернета, включая пиксели отслеживания. Если открыть скачанный файл в обычной вкладке браузера, ни одной из этих защит не будет.
Почему превью выглядит без стилей?
Стили блокируются вместе со всем остальным: политика безопасности, которая не пускает внешний контент, заодно останавливает встроенные блоки <style> и атрибуты style. Превью показывает текст, ссылки и встроенные картинки data:, и этого хватает, чтобы понять, о чём сообщение.
Base64 декодируется в HTML, а инструмент пишет XML или Text. Почему?
Инструмент распознаёт HTML по <!doctype html, <html или распространённому HTML-тегу вроде <div>, <p> или <table> в начале. Фрагмент, который начинается с пользовательского элемента или простого текста, показывается как XML или Text. Впишите text/html в поле MIME-тип, чтобы получить HTML-превью, и html в поле Расширение перед скачиванием.