2024

Invisible marks in audio: finding who leaked a recording from a private community

In early 2024 I built content protection for a blogger. He posted audio clips and voice messages to a private community, and they kept leaking. The goal: every subscriber gets their own, slightly different copy, and from a leaked file you can tell whose it is. Then that person can be banned, and information stops leaking out of the private community.

I wrote a service for it in TypeScript on top of ffmpeg. Each way of hiding the subscriber’s number is a separate plugin, and they can be combined.

  • Metadata. The code in the file’s tags. The simplest and the most fragile: one re-save removes it.
  • Quiet sounds. At certain moments barely audible sounds — noises and “waves” — are mixed into the recording. Each bit of the number is a choice of one of two sounds in its slot; the marks repeat at the start and at the end.
  • Tempo. The file is cut into pieces, and each piece is sped up or slowed down a tiny bit — inaudible, but the number can be read from the segment lengths.
  • Pauses. The program finds the pauses between words and stretches them by different amounts.
  • Equaliser. On some segments, a narrow boost and cut of a single frequency.
  • Segments — the trickiest one. The author recorded several takes of the same text. The program stitched together phrases from different takes, so every subscriber got their own combination. Each phrase’s length was matched with tempo so the seams couldn’t be heard. A mark like that can’t be removed by re-encoding or filters: it isn’t an effect laid on top, it’s the text itself in a different delivery.

What if they leak together? Several people can compare their copies and mix them. Then the combined file keeps only the marks they have in common. For that case I wrote a separate script: from those leftovers it goes through the triples of subscribers who could have produced exactly that mix.

What happened next. Apparently the guys had several accounts. They compared the voice messages, realised the copies were different, started digging — and in the end stopped leaking audio altogether. We didn’t manage to work out who was doing it back then, but the audio leaks stopped.

Instead they started transcribing everything and posting it as text. We thought about that too: using ChatGPT to add a little something to each copy — filler words, different wording. But when the leaker has two accounts, he compares two versions and cleans out the differences, and that is practically impossible to beat.

Video. In spring video was added. The clips were shown through the VdoCipher player, and viewers carried their number right on the screen: the watermark’s position and the intervals at which it moves were computed from the bits of their number, information was encoded in colours, pop-ups appeared. The leakers got used to blurring all of that — and relaxed. And we added audio marks to the video as well. That’s what finally gave them away, and they were banned.

What I took from it: no single method survives everything — metadata is lost on re-save, sounds can be cut out, a visible mark blurred. So there have to be several marks of different kinds. And the most dangerous mark for a leaker is the one he doesn’t know about: while they fought what they could see, the sound gave them away.