Sam Lazarus · October 2026
Summary
- We put a proxy between the TV and the internet, holding certificates from an authority we’d created minutes earlier.
- LG’s ad server, LG’s platform server and YouTube refused them and hung up, exactly as they should.
- The content recognition server accepted one, so for the first time we could read what the TV says about us.
- It sends audio fingerprints: twelve uploads in 23 minutes of a cartoon played from a laptop, each one acknowledged.
- It also reports which HDMI socket is in use, and what’s plugged into it by make and model.
Where we left off
In our last post we recorded every packet our 2025 LG TV sent over a day. On default settings it contacted Alphonso’s automatic content recognition (ACR) server, tkacr394.alphonso.tv, every minute it was on, and sent three times as much data while a film played from a laptop over HDMI. One setting, Live Plus, stopped it.
Almost everything the TV sends is wrapped in TLS, so we could see the shape of that traffic but not its contents. The bursts looked like fingerprints of what was on screen. We couldn’t prove it.
What a certificate is for
Certificates are the part of HTTPS that answers “am I really talking to who I think I am?”. Anyone can make one claiming to be any website. The signature is what stops that working. A device that checks properly rejects a certificate from an authority it doesn’t trust.
So there’s a clear pass mark. We generated our own authority on the Raspberry Pi, had it mint certificates for whatever the TV asked for, and never installed it on the TV. A TV that checks refuses. A TV that doesn’t hands us everything.
Only the TV’s encrypted web traffic was redirected. One detail mattered: content recognition uses port 4433, not the usual 443. Catching only 443 would have intercepted everything except the one thing worth looking at.
Which connections were accepted, and which refused
Within a minute the answer arrived, and it wasn’t the clean yes or no we expected. In the hostnames below, <cc> replaces a country code.
| Server | What it’s for | Our certificate |
|---|---|---|
<cc>.ad.lgsmartad.com | LG advertising | Refused |
<cc>.nextlgsdp.com | LG platform | Refused |
www.youtube.com | Refused | |
discovery.meethue.com | Smart-home lookup | Accepted |
tkacr394.alphonso.tv:4433 | Content recognition | Accepted |
The refusals were textbook: the TV saw an authority it had never heard of, sent the TLS alert that means exactly that, and hung up. Two came from LG’s own servers.
That rules out the boring explanation. Same TV, same proxy, same invented authority, same minute. The TV is perfectly capable of checking certificates. On the connection carrying what we watch, it doesn’t.
What it was actually sending
With the connection open to us, the channel had three parts.
| Request | Size | What it does |
|---|---|---|
POST /v5/audio/fingerprint | 1.1 to 23 kB | the fingerprints themselves |
POST /v5/user/appsource | 365 B | what is playing and where from |
POST /v5/user/lookups | 193 B | holds a connection open, waiting |
The first settles what the last post left open. The endpoint is named /v5/audio/fingerprint and the server answers each upload with 202 Accepted. During 23 minutes of a cartoon from a laptop the TV sent twelve, from 1.1 kB to 23 kB, in three clusters about six minutes apart. In the 46 idle minutes beforehand, none. That is the burst pattern we measured from outside last time.
Note the word audio. We had assumed the TV was sampling the picture. It is listening. That explains what seemed odd last time, when the TV reported just as diligently on a film arriving over HDMI from a laptop. It needs only to hear the soundtrack.
It also knows what you plugged in
The second request was the surprise. Once a minute, alongside the fingerprints, the TV sends a status report:
{
"app_name": "",
"device_input": "HDMI2",
"hdmi_spd_json_string": "{\"description\":\"<graphics-card-model>\",
\"manufacturer\":\"<vendor>\",
\"type\":\"PC general\"}",
"hdmi_cec_json_string": "{\"osdname\":\"\",\"type\":\"\"}",
"channel_name": "", "channel_number": "",
"livetv_metadata_json_string": "",
"vod_metadata_json_string": ""
}Every HDMI device announces itself to the screen it’s plugged into, in a block called the Source Product Description: who made it, what it is, what class of device it is. Ours forwards that block to Alphonso once a minute, with the socket it arrived on.
So the report isn’t only about what we watched: it named the graphics card inside the laptop, by vendor and model. The fields come through blank on an empty home screen, so this starts only once something is connected.
That is different from content recognition, and worth separating. Fingerprinting tells an advertiser what you watched. This tells them what hardware you own.
What we couldn’t confirm
The third request, /v5/user/lookups, is how a recognition result would come back: it holds a connection open and waits for the server to push an answer. We recorded 68, and not one returned anything we could read.
Three explanations fit and our data cannot separate them. Alphonso may hold no fingerprint for a decades-old cartoon. A match may take longer than our 23-minute run. Or our interception broke the mechanism, since a connection held open is exactly the kind that doesn’t survive being proxied.
So we have proof the TV uploads audio fingerprints and that the server accepts them. We have no proof of what came back, and we won’t claim otherwise.
Why this is worse than it sounds
The traffic is readable by anyone on the path. Not just us in a lab built on purpose: a compromised router, a hostile public network, anyone between the TV and the internet. TLS should make that position useless. For this one stream it doesn’t.
It’s writable too. A TV that accepts our certificate will accept our responses. We didn’t tamper with the replies, but nothing stopped us. Last time we rewrote the TV’s unencrypted home-screen images and it showed our joke posters without warning.
It carries identifiers. Every request puts a persistent user identifier and a device identifier in the URL, alongside an API key. We’ve replaced them with placeholders here. Anyone watching the traffic would not have to.
None of this requires the fingerprinting to be sinister. You can think LG and Alphonso are entitled to run content recognition on a TV that disclosed it, and still think the channel carrying it should check who is on the other end.
What you can do
- Turn off Live Plus. Still the single setting that stops all of this: no fingerprints, no HDMI reports, nothing to intercept. Settings → All Settings → General → System → Additional Settings.
- Don’t assume the padlock means much. That a device checks its own encrypted connections does not hold uniformly, even within one TV from a major manufacturer.
- Keep the TV on its own network. A guest or IoT network limits what an attacker on the path can reach next.
- Consider blocking the domain. Sinkholing
*.alphonso.tvat your router or with a Pi-hole stops the connection entirely. We still haven’t tested what else that breaks.
Previously in this series
What's our LG Smart TV up to?
We recorded every packet a 2025 LG TV sent over a day. On default settings it checked in with LG's ad-tech arm every minute, and sent three times as much while a laptop played a film over HDMI. Turning off one setting, "Live Plus", stopped it within the minute.
Read the post →
Appendix: reproduce it yourself
Same Raspberry Pi access point as last time. The only additions are a proxy and two firewall rules.
# mitmproxy in a venv on the Pi, generating its own CA on first run
python3 -m venv ~/mitm && ~/mitm/bin/pip install mitmproxy
~/mitm/bin/mitmdump --mode transparent --showhost --listen-port 8080 \
--set flow_detail=1 -w p9-flows.mitm
# send only the TV's TLS traffic to it. 4433 is the content recognition port.
table ip tvmitm {
chain prerouting {
type nat hook prerouting priority -100;
iifname "wlan0" ip saddr <tv-ip> tcp dport { 443, 4433 } redirect to :8080
}
# QUIC would bypass the proxy entirely, so force a fallback to TCP
chain forward {
type filter hook forward priority -10; policy accept;
iifname "wlan0" ip saddr <tv-ip> udp dport 443 drop
}
}Two things caught us out. Existing connections keep flowing on their old path, so nothing is intercepted until they re-establish. Content recognition also holds its connections open for minutes, which makes it the last to reconnect.
References
- Our previous post, “What’s our LG Smart TV up to?”, on the traffic this TV sends with its default settings.
- G. Anselmi, Y. Vekaria, A. D’Souza, P. Callejo, A. M. Mandalari, Z. Shafiq. “Watching TV with the Second-Party: A First Look at Automatic Content Recognition Tracking in Smart TVs”, ACM Internet Measurement Conference (IMC) 2024.
All testing was done on a device we own, on our own network, against servers our own device chose to contact. Identifiers have been replaced with placeholders throughout.