**Phase 2 update (2026-11-02):** the two candidates ranked here were tested under
approved read-only/minimal-touch rules and **both dead-ended** — see
`XSS_PHASE2_REPORT.md`. No confirmed DOM-XSS in either phase.
Target program: Tencent Security Response Center (TSRC)
Scope: *.mail.qq.com, *.exmail.qq.com, jiazhang.qq.com, doc.qq.com
Phase: 1 — static/passive only. HARD STOP on active scanning maintained.
Date: 2026-11-02 (UTC)
Author: operator-assisted agent run
---
response header. Nothing is asserted from memory.
tencent/logs/phase1_commands.log (and the earlier tencent/server_commands.log).
Ground truth from `find/FINAL_RANKING.md` (verified earlier, not re-litigated):
Tencent score 55.00, no bonus. Prioritised hosts per that audit: app.mail.qq.com
(jQuery 1.10.2), jiazhang.qq.com (jQuery 1.11.3), doc.qq.com, and the
`*.exmail.qq.com` family (jQuery 1.11.0). `service.qq.com`, `fanyi.qq.com`,
`tenpay.com` are **out of scope** and were excluded.
---
| Tool | Version | Where | Purpose |
|---|---|---|---|
| curl | 8.22 | local | fetch HTML/JS + capture headers (polite, one request per asset) |
| python3 | 3.14.7 | local | `analyze_sinks.py` static source→sink census; regex tracing |
| grep / awk / sort | coreutils, ripgrep | local | byte-offset sink context extraction |
| jq | 1.8.2 | local | parse Cloudflare API JSON |
| ssh | OpenSSH | local→server | server admin for PoC infra |
| Caddy | v2.11.7 | server 216.73.157.146 | PoC web server (TLS, logging) |
| Cloudflare API | v4 | local | DNS record + Origin Rule for PoC host |
| dig, whatweb, httpx, subfinder | (prior survey) | local | inventory provenance (see `xss_targets.csv`) |
nuclei, nmap, ffuf, gobuster, amass were available but not run in
this phase — they are active tools and are out of scope until Phase 2 approval.
---
tencent/xss_targets.csv — 14 rows, one per in-scope host, with priority,
in-scope basis, jQuery version, tech signals, live status, page URLs to analyse,
and the evidence file that established each version.
Priority order used for mirroring and analysis:
app.mail.qq.com — jQuery 1.10.2 (oldest in scope)jiazhang.qq.com — jQuery 1.11.3doc.qq.com — 302 → docs.qq.com (no first-party content served)*.exmail.qq.com × 11 hosts — jQuery 1.11.0 (cnc, download, en, mail,set1, set2, ssl, tel, tls, tp, xc)
---
Mirrored under tencent/static/<host>/ (HTML + all first-party JS + response
headers for the entry page):
| Host dir | HTML | First-party JS |
|---|---|---|
| `static/app.mail.qq.com/` | `index.html` (137 991 B) | `jquery-1.10.2.min.js`, `new.js`, `app_landing-web.js`, `vendor_page-web.js` |
| `static/jiazhang.qq.com/` | `index.html`, `index-m.html`, `index-ie.html` | 12 files incl. `jquery.js`, `index.js`, `superplayer.js`, `swiper.js`, `aq_common.js`, `beacon_web.js`, `reporter.js`, `animate.js`, `scroll-trigger.js`, `gsap.js`, `lazyload.min.js`, `aegis1.43.6.min.js` |
| `static/exmail.qq.com/` | `cnc.html` (50 766 B) | `jquery-1.11.0.min462fc5.js`, `index74e89a.js`, `pkg74e89b.js`, `global7fa051.js`, `responsiveslides462fc5.js` |
| `static/doc.qq.com/` | `index.html` (137 B redirect stub) | — |
Response headers captured (see *.headers files). Behaviour-relevant results:
script-src with 'unsafe-inline' and 'unsafe-eval'; jiazhang has no CSP header at all (served by tencent-cos).
referrer-policy: origin; app.mail and jiazhang donot set one.
X-Frame-Options: SAMEORIGIN; jiazhang/app.mail do not(recorded for Phase 2, not claimed as a finding here).
---
Tool: tencent/analyze_sinks.py (read-only, offline). Output:
tencent/logs/sink_census.txt (264 lines). Sources scanned: location.hash,
location.search, location.href, document.referrer, window.name,
postMessage, addEventListener("message"), URLSearchParams. Sinks scanned:
innerHTML, outerHTML, insertAdjacentHTML, document.write, eval,
setTimeout(string), .html(), .append(), .attr("href"|"src"|…),
createContextualFragment, .srcdoc, dangerouslySetInnerHTML.
Files tagged [UPSTREAM-LIB] (jQuery, Swiper, GSAP, lazyload, aegis,
vendor_page-web) were scanned but their internal matches are not app-level
findings.
Full ranked table with offsets and confidence:
tencent/xss_candidates.md. Summary of what the census proved:
getPageUrl() only *strips* sid= from location.href for telemetry; its jsonp token is a hardcoded
cube.weixinbridge.com beacon, not a script load.
addEventListener("message") / BroadcastChannel.onmessage handlers are Bluebird's task scheduler and Axios's
async trampoline, both with self-source equality checks. No app message sink.
document.write is the fixed document.domain="qq.com" iframe trampoline; postMessage is an internal
bridge bus; DBF location.hash/document.referrer reads feed telemetry only.
hashNavigation reads location.hash but only compares it to slide data-hash; no HTML sink.
location.search to a fixed static target (./index-m.html, ./index-ie.html).
No DOM sink; at most a nuisance redirect (query string preserved).
($(".index_hot_wrap").html(n.data.hot_log_html)), fed by AJAX
/qy_mng_logic/wwhelp.
getUrlParam returns unescape(location.search…), used only as an AJAX data param and in a string compare; no DOM sink.
document.write, innerHTML, insertAdjacentHTML); a control, not a sink.
---
All three jQuery copies are < 3.0.0, so they *contain* the CVE-2015-9251
cross-domain-AJAX→script path:
| Host | File | Version |
|---|---|---|
| app.mail.qq.com | `static/app.mail.qq.com/js/jquery-1.10.2.min.js` | v1.10.2 |
| jiazhang.qq.com | `static/jiazhang.qq.com/js/jquery.js` | v1.11.3 |
| *.exmail.qq.com | `static/exmail.qq.com/js/jquery-1.11.0.min462fc5.js` | v1.11.0 |
Verdict: present-but-untriggered. Library internals expose getScript and
dataType:"script", but a scan of every first-party app file found zero
callers passing a user-controlled URL, and zero classic JSONP callback=?
sinks. Likewise, no $(userInput) selector-injection call site exists in app
code (all selectors are string literals or this).
---
Goal: a report-verifiable test host reachable from anywhere (not just the local
machine), with timestamped request logging.
Host: https://tencent-poc.msedigh.lol → Cloudflare (proxied) → origin
216.73.157.146:8443 (Caddy).
Setup (all verified live):
tencent-poc.msedigh.lol → 216.73.157.146 (record id 7001d447b1b86add4b56bf90a52dedf2), set to proxied.
022a6a2abd004ca4b94cb2a9d9cc83cc (phase http_request_origin): (http.host eq "tencent-poc.msedigh.lol") →
origin port 8443. Existing rules preserved (diff vs /tmp/origin_rules_before.json
showed only the added rule).
(/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/tencent-poc.msedigh.lol).
(http-01 solved after the DNS record was briefly set to DNS-only for validation.)
/etc/caddy/Caddyfile, appended; backup at /etc/caddy/Caddyfile.bak-tencentpoc-20261102T132246Z):
`
tencent-poc.msedigh.lol:8443 {
log { output file /var/log/caddy/tencent-poc-access.log format json }
root * /srv/tencent-poc
handle /collect { reverse_proxy 127.0.0.1:8780 }
handle { file_server }
}
`
by the VLESS/xray inbound, so the PoC serves on origin port 8443 (already
allowed and already used by cors-proof.msedigh.lol).
VLESS tunnel integrity check (post-reload): port 443 still owned by
xray-linux-amd64; all xray processes alive; Reality handshake still returns the
camo certificate. Tunnel intact.
Request logging: every hit is written as JSON to
/var/log/caddy/tencent-poc-access.log (path, query, headers, remote IP, time).
The root-level POST /collect path proxies to the existing collector
(127.0.0.1:8780, cors-proof-collector.service) for canary/callback capture; it is
POST-only (a bare GET returns 501, a malformed POST returns 400 — verified).
How to operate it:
/srv/tencent-poc/poc/ on the server → served at https://tencent-poc.msedigh.lol/poc/<file>.
ssh [email protected] 'cat /var/log/caddy/tencent-poc-access.log'.curl -X POST https://tencent-poc.msedigh.lol/collect ...(see the collector's expected payload shape before use).
/etc/caddy/Caddyfile.bak-tencentpoc-20261102T132246Z and systemctl reload caddy.
---
No confirmed DOM-based XSS was found in this static phase. This is an
acceptable Phase-1 result: the mirrored first-party code contains no
attacker-controlled source→executing-sink path *at rest*.
Most promising candidates for a **controlled, TSRC-compliant Phase 2 verification
round (needs explicit operator approval before any active test):**
$(".index_hot_wrap").html(n.data.hot_log_html) — the only genuine executing HTML sink. Phase-2 question: can the /qy_mng_logic/wwhelp response
body be influenced (parameter, cache, or account-side data)? Investigate the
endpoint contract read-only first.
location.search — low value, but thequery string is carried into a redirect; worth a read-only check whether any
downstream page reflects it (e.g. index-ie.html / index-m.html).
new first-party module that calls $.getScript/JSONP with user input is
discovered in a future crawl.
Explicitly not findings (recorded so we do not re-litigate):
unsafe-inline/unsafe-eval in CSP, missing jiazhang CSP, absent X-Frame-Options, referrer-policy differences — posture observations only.
from/kvclick href assignment on app.mail (fixed HTTPS prefix, propertyassignment).
document.write and postMessage bus (defensive/internal).---
mirrored. Deeper app routes (logged-in app.mail.qq.com states, exmail account
pages behind auth) were not touched — that requires an operator-owned test
account and explicit authorisation.
cnc.exmail.qq.com was mirrored asrepresentative. Per-host divergence was not exhaustively diffed.
rescdn.qqmail.com, mat1.gtimg.com, res.wx.qq.com)were not mirrored (they are first-party CDN, but the review focused on
origin-served app code).
doc.qq.com was a 302 stub; the real app is docs.qq.com — confirm whether docs.qq.com is in TSRC scope before spending time there.
load; deferred to Phase 2).
---
| Artifact | Path |
|---|---|
| Inventory | `tencent/xss_targets.csv` |
| Candidate table | `tencent/xss_candidates.md` |
| Sink census | `tencent/logs/sink_census.txt` |
| Analyzer | `tencent/analyze_sinks.py` |
| Command log | `tencent/logs/phase1_commands.log`, `tencent/server_commands.log` |
| Mirrored assets | `tencent/static/<host>/` |
| Captured headers | `tencent/static/*/*.headers`, `tencent/evidence/` |
| This report (HTML) | `https://tencent-poc.msedigh.lol/poc/report.html` |