zebra-audio: stop displaying peer IP/port in path status — no dox
reportPath used to print 'you A:B ↔ peer C:D' in path-status and the log, exposing both participants' real IP addresses to anyone glancing at the screen. Show DIRECT vs RELAYED and the candidate types (host/srflx/relay) only; addresses are gone. CLAUDE.md gains a 'Web UI privacy — never display peer IPs' rule so this does not regress.
This commit is contained in:
parent
5e1c4402b2
commit
17ba25f9cb
2 changed files with 21 additions and 8 deletions
10
CLAUDE.md
10
CLAUDE.md
|
|
@ -120,6 +120,16 @@ Handshake frame: `[0x5A 0x42 0x01 baud_lo baud_hi xor_cksum]` — 6 bytes at 50
|
|||
- userland only — survives without root
|
||||
- **Operation Voyeur**: all terminal output is public — never pass secrets through these channels unencrypted. The web page does ECDH key exchange + AES-256-GCM before TX.
|
||||
|
||||
### Web UI privacy — never display peer IPs
|
||||
|
||||
`chat.html` and `zebra-audio.html` must never print peer IP addresses or ports
|
||||
in the page UI or in any visible log. Our users do not run Wireshark — if it
|
||||
is not on the screen, peers cannot dox each other. Candidate types
|
||||
(`host`/`srflx`/`relay`) from `pc.getStats()` are abstract and fine to show
|
||||
(they tell you direct vs relayed); `loc.address` / `loc.port` /
|
||||
`rem.address` / `rem.port` are not. The WebRTC stack already obfuscates host
|
||||
candidates via mDNS by default — do not undo that work in the UI.
|
||||
|
||||
### Web page integrity stamping
|
||||
|
||||
Each deployed page (`web/chat.html`, `web/zebra-audio.html`, `web/how-it-works.html`,
|
||||
|
|
|
|||
|
|
@ -317,13 +317,16 @@ async function reportPath(){
|
|||
if (!sel) stats.forEach(r=>{ if(r.type==='candidate-pair'&&r.state==='succeeded'&&(r.nominated||r.selected)) sel=r; });
|
||||
if (!sel){ setPath('path: connecting…', null); return; }
|
||||
const loc=stats.get(sel.localCandidateId)||{}, rem=stats.get(sel.remoteCandidateId)||{};
|
||||
const la=(loc.address||loc.ip||'?')+':'+(loc.port||'?'), ra=(rem.address||rem.ip||'?')+':'+(rem.port||'?');
|
||||
const relayed = loc.candidateType==='relay'||rem.candidateType==='relay';
|
||||
/* show the real endpoints so it's verifiable: host = the two devices' IPs;
|
||||
* relay = the TURN server's IP (142.93.73.64) appears on at least one side. */
|
||||
setPath('path: '+(relayed?'RELAYED via TURN':'DIRECT P2P')+' — you '+la
|
||||
+' ↔ peer '+ra+' ('+(loc.candidateType||'?')+'/'+(rem.candidateType||'?')+')', relayed?'err':'ok');
|
||||
logLine('', 'active pair: '+la+' ['+(loc.candidateType||'?')+'] ↔ '+ra+' ['+(rem.candidateType||'?')+']');
|
||||
/* deliberately do NOT surface loc.address/loc.port/rem.address/rem.port —
|
||||
* printing them would dox the peer to anyone who glances at the screen.
|
||||
* candidate types (host/srflx/relay) are abstract enough to show: they
|
||||
* tell you whether you're direct or relayed without leaking an address. */
|
||||
setPath('path: '+(relayed
|
||||
? 'RELAYED via TURN — a server forwards your (encrypted) audio'
|
||||
: 'DIRECT peer-to-peer — nobody between you')
|
||||
+' ('+(loc.candidateType||'?')+'/'+(rem.candidateType||'?')+')', relayed?'err':'ok');
|
||||
logLine('', 'transport: '+(relayed?'relayed via TURN':'direct peer-to-peer')+' ('+(loc.candidateType||'?')+'/'+(rem.candidateType||'?')+')');
|
||||
} catch(_){}
|
||||
}
|
||||
|
||||
|
|
@ -641,8 +644,8 @@ else wirePuppet();
|
|||
|
||||
<footer style="max-width:560px;margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
|
||||
<span id="pi-seal" style="color:#777;cursor:default;user-select:none" title="">page integrity</span> · built <span class="stamp-date">2026-05-29</span><br>
|
||||
md5 <span class="stamp-md5">1e587958aedf93270535fb510aa946e7</span><br>
|
||||
sha256 <span class="stamp-sha">ba1975bd8011a139f8dec8a868cc218e2aeb09a969831343f02564524412f726</span><br>
|
||||
md5 <span class="stamp-md5">70f28512b6bc9af9121f6c533676024d</span><br>
|
||||
sha256 <span class="stamp-sha">7ca19b46a6738039f4e4d10e026019a142c769d1a96017419f562f7d701be6ac</span><br>
|
||||
<span style="color:#bbb">hashes are of this page with these two fields zeroed — to verify, blank them and re-hash</span><br>
|
||||
<span style="color:#bbb">one self-contained file — <strong>save a copy</strong> and verify it against these hashes; point it at your own servers with ?signal= and ?turncred=, or <a href="host-your-own.html" style="color:#999">host your own community</a></span>
|
||||
</footer>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue