Repository navigation
v1.2.3 - XSS and SSH Key Security Fixes
Security patch release. Fixes items 1 and 2 of #6, reported and fixed by @lewalmeida in #7. Thank you!
Fixed
- HTML injection (XSS) from third-party API data (high).
renderPicks()built each trending card withinnerHTML, concatenating the title/badge/service text straight from TMDB and TVMaze (TVMaze is community-edited, no API key required) without escaping. A crafted title on a show scoring ≥ 8.4 could run script in the app on every TV that displayed it. On a rooted TV this is worse, since the app already callsluna://org.webosbrew.hbchannel.service/execas a launch fallback. Also fixed:pick.posterwas concatenated unvalidated intobackground-image: url('...'), letting it break out of the CSS string, andrenderAppSelectorGrid()had the sameinnerHTMLpattern for installed-app titles (lower risk, requires a malicious installed app).docs/index.htmlhad the same code and got the same fix.- All three now build DOM nodes with
textContentinstead ofinnerHTML. - Poster URLs are only used if they match a strict
https://pattern with no quotes, parens, backslashes, or whitespace - real TMDB/TVMaze URLs still work.
- All three now build DOM nodes with
- Decrypted SSH private key written world-readable (medium).
scripts/install.pywrote~/.ssh/webos_tv_rsaand~/.ssh/webos_tv_rsa_decryptedwith a plainopen(..., "wb"), which under the common umask 022 leaves them mode0644- readable by any local user, and rejected outright by OpenSSH ("UNPROTECTED PRIVATE KEY FILE") on some platforms. Both files are now created mode0600.
Not changed in this release
The issue also noted some lower-severity items for future consideration: disabled host-key verification (StrictHostKeyChecking=no), auto-installing to the first SSDP-discovered TV without confirmation, the install passphrase being visible via argv/ps, and README clarity around Key Server and ACR/telemetry claims. None of these were part of the fix in #7.
Install
Download org.webos.freemytv_1.2.3_all.ipk below, or run python scripts/install.py from a clone of this repo.