惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
H
Heimdal Security Blog
K
Kaspersky official blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
Schneier on Security
G
GRAHAM CLULEY
U
Unit 42
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
C
CERT Recently Published Vulnerability Notes
Google DeepMind News
Google DeepMind News
罗磊的独立博客
Stack Overflow Blog
Stack Overflow Blog
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
C
Cisco Blogs
Cyberwarzone
Cyberwarzone
T
The Exploit Database - CXSecurity.com
Project Zero
Project Zero
Security Archives - TechRepublic
Security Archives - TechRepublic
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 司徒正美
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
V
Visual Studio Blog
博客园 - Franky
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
Jina AI
Jina AI
P
Proofpoint News Feed
P
Proofpoint News Feed
有赞技术团队
有赞技术团队
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
N
News and Events Feed by Topic
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 聂微东
T
The Blog of Author Tim Ferriss
Spread Privacy
Spread Privacy
Application and Cybersecurity Blog
Application and Cybersecurity Blog
IT之家
IT之家
S
Security Affairs
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
N
News | PayPal Newsroom
Cloudbric
Cloudbric
AWS News Blog
AWS News Blog
W
WeLiveSecurity
The Last Watchdog
The Last Watchdog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
NISL@THU
NISL@THU

dgl.cx

SSH port knocking with OpenBSD 7.9 SSH port knocking with OpenBSD 7.9 Bash a newline: Exploiting SSH via ProxyCommand, again (CVE-2025-61984) Switchable dark mode with 5 lines of JavaScript CVE-2025-48384: Breaking Git with a carriage return and cloning RCE Can your terminal do emojis? How big? Blink and you'll miss it — a URL handler surprise Using HAProxy to protect me from scrapers Déjà vu: Ghostly CVEs in my terminal title Restrict sftp with Linux user namespaces ""?! ANSI Terminal security in 2023 and finding 10 CVEs NAT-Again: IRC NAT helper flaws ip.wtf and showing you your actual HTTP request
Images over DNS
2025-09-20 · via dgl.cx

What's the limit of what can be in a TXT record?

Some places say 255 bytes. They are wrong. Within a TXT record there are multiple character-strings (RFC 1035 section 3.3.14) and those are limited in length (because a single byte is used for their length), however there can be many of them.

The actual limit is limited by the size of the DNS payload, which for UDP is these days around 1232 bytes. That is obviously quite low. However if we use TCP, which doesn't require anything special, other than the normal fallback to TCP that DNS does, then we can serve up to 64 KB.

I set out to demonstrate exactly that, by using Google Public DNS's JSON API and then serving large TXT responses over TCP, from a custom server. Those responses happen to be images.

This mostly just works, the main issue is not with the length, but with binary data, because JSON isn't really designed to handle binary data. Therefore I had to write some slightly custom JSON parsing. Using raw binary data in a TXT record avoids the overhead of Base64 or another encoding, meaning more data can be packed in.

👉 See it in action. For more read the comments in image.html.

Non-browser

It is possible to query this via dig. Although turning it back into binary output is a bit tricky, as the presentation form of DNS responses is escaped for output.

You can retrieve the data with dig and a little Perl to unescape and combine the character sequences:

$ dig +short dog.log.battery.st TXT | perl -pe'chomp; s/" "//g; s/^"//; s/"$//; s/\\(\d{3})/chr $1/eg; s/\\([\\"])/$1/g' > dog.avif
$ sha256sum dog.avif
7058fbd20ef2af84d5efb0ae7d91f87ce7a912380636c468b32f2c759cbb9130  dog.avif

(This is actually just a modified version of the Perl one liner from my Wikipedia over DNS from 2008, nothing changes.)

Because the web version uses Google's JSON resolver we know it doesn't have problems querying very large TXT records, however your local recursor may not support this. If it doesn't work you can add @dns.google to the dig command line to send the query to Google's Public DNS servers (or any other open recursor, @9.9.9.9 seems to work too).

Why?

I thought it was a cute hack when I realised it was possible.

For those interested in security there is a consideration here, attackers have long tunnelled over DNS, but tunnelling large payloads to a browser is potentially something new. Because Google Public DNS has a certificate that includes 8.8.8.8 and so on, HTTPS traffic can go directly from a browser without a DNS lookup. This may be unexpected in environments that use DNS filtering. This is something that will become more common once Lets Encrypt fully rolls out IP address certificates, the difference here is piggybacking on an existing IP address certificate.

This deliberately uses a low TTL (10 seconds) to avoid filling DNS recursor's caches with useless content. It would be possible to increase this and therefore get caching from the recursors, a bit like a free distributed CDN (although I suspect if someone actually did this they would adaptively limit TTLs, if something like that isn't already done).

Server side

The server is a custom Go DNS server. To be honest it was written by ChatGPT because it's not that clever, the idea is what matters. (Although ChatGPT did get some details like truncation wrong so I fixed the code myself.)

All the code is here. AI was only used for the server component, this blog post and the client HTML code is my own work.

20th September 2025