Issue 1 — scripts/run_qa.sh:14-21 — Bug: Multi-URL argument handling is broken
When multiple URLs are passed as CLI arguments, the script builds URL_ARGS in a loop but never uses it. The actual qa_pipeline.py call only uses $1 (the first URL). All URLs after the first are silently ignored.
# URL_ARGS is built but never used:
for url in $URLS; do
URL_ARGS="$URL_ARGS --url $url"
done
python3 "$SCRIPT_DIR/qa_pipeline.py" --url "$1" ... # only $1 is passed
Issue 2 — scripts/qa_pipeline.py:27 — Security: Script path in world-writable /tmp directory
MONITOR_SCRIPT = "/tmp/x-monitor/scripts/monitor.py" points to /tmp, which is world-writable on Linux. Any local user or process can create/replace that file, causing arbitrary code execution when fetch_replies() is called via subprocess.run(["python3", MONITOR_SCRIPT, ...]).
Issue 3 — scripts/qa_pipeline.py:243 — Bug: Unguarded KeyError on screen_name
"tweet_author": tweet_data["tweet"]["screen_name"] if tweet_data and "tweet" in tweet_data else "",
The guard checks that "tweet" key exists but does not check for "screen_name" inside it. If the fetcher returns a tweet object without screen_name, this raises an unhandled KeyError and the entire tweet result is lost.
Issue 4 — scripts/generate_site.py:271 — Security: javascript: URL XSS in href attribute
<a href="{escape_html(tweet_url)}" target="_blank">
escape_html() only escapes &, <, >, " — it does not validate the URL scheme. If tweet_url in the JSON data contains javascript:alert(1), it passes through unfiltered and renders as a clickable XSS payload in the generated index.html.
Issue 5 — feeds/subscribers.json:15 — Security: Webhook endpoint uses plain HTTP
"url": "http://43.163.91.147:9378/teahouse-feed"
Webhook payloads (containing comment bodies and author names) are sent over unencrypted HTTP, exposing data to network interception and allowing man-in-the-middle modification.
Issue 1 — scripts/run_qa.sh:14-21 — Bug: Multi-URL argument handling is broken
When multiple URLs are passed as CLI arguments, the script builds
URL_ARGSin a loop but never uses it. The actualqa_pipeline.pycall only uses$1(the first URL). All URLs after the first are silently ignored.Issue 2 — scripts/qa_pipeline.py:27 — Security: Script path in world-writable /tmp directory
MONITOR_SCRIPT = "/tmp/x-monitor/scripts/monitor.py"points to/tmp, which is world-writable on Linux. Any local user or process can create/replace that file, causing arbitrary code execution whenfetch_replies()is called viasubprocess.run(["python3", MONITOR_SCRIPT, ...]).Issue 3 — scripts/qa_pipeline.py:243 — Bug: Unguarded KeyError on
screen_nameThe guard checks that
"tweet"key exists but does not check for"screen_name"inside it. If the fetcher returns a tweet object withoutscreen_name, this raises an unhandledKeyErrorand the entire tweet result is lost.Issue 4 — scripts/generate_site.py:271 — Security: javascript: URL XSS in href attribute
escape_html()only escapes&,<,>,"— it does not validate the URL scheme. Iftweet_urlin the JSON data containsjavascript:alert(1), it passes through unfiltered and renders as a clickable XSS payload in the generatedindex.html.Issue 5 — feeds/subscribers.json:15 — Security: Webhook endpoint uses plain HTTP
Webhook payloads (containing comment bodies and author names) are sent over unencrypted HTTP, exposing data to network interception and allowing man-in-the-middle modification.