aboutsummaryrefslogtreecommitdiffstats
path: root/docs/BACKLOG.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/BACKLOG.md')
-rw-r--r--docs/BACKLOG.md65
1 files changed, 65 insertions, 0 deletions
diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md
index 87ec4b3..a520ae0 100644
--- a/docs/BACKLOG.md
+++ b/docs/BACKLOG.md
@@ -10,6 +10,7 @@ number and gains a status rather than being renumbered.
| 3 | Expose kept cases so qtmaildir can tag spam | ? | open, unsized |
| 4 | `Report-Type: phishing` is unverified against x-arf | XS | closed |
| 5 | `report.build()` raises KeyError on an identity with no email | XS | closed |
+| 6 | VirusTotal as a destination, or as enrichment | S | open, deferred |
## 1. Skip boilerplate namespace URLs
@@ -183,3 +184,67 @@ remaining gap is a hand-edited config and the error message it deserves.
alone, since where the check lives decides whether the user sees an exit code
and a sentence or a traceback. Not a leak: the failure is loud and nothing is
sent.
+
+## 6. VirusTotal as a destination, or as enrichment
+
+**Deferred**, not rejected. Recorded with the findings so it is reconsidered
+from checked documentation rather than from memory.
+
+**Observed.** The report spec's addendum settles three destinations, MISP,
+AbuseIPDB and URLhaus. VirusTotal was examined in the same pass and left out.
+
+**What the documentation says**, read 2026-09-10 from `docs.virustotal.com`
+and the endpoint index at `virustotal.readme.io/llms.txt`:
+
+- The only submission endpoints are `POST /urls` and file upload. **There is
+ no endpoint that submits a domain or an IP address as a new indicator.**
+ `POST /ip/{ip}/analyse` and `POST /domains/{domain}/analyse` re-analyse data
+ VirusTotal already holds, which is not reporting.
+- Files are submitted as FILES. This tool holds an attachment's sha256 and
+ never the attachment, so a hash IOC earns no VirusTotal submission either.
+- The auth header is `x-apikey`.
+
+So its submit side accepts URLs and nothing else, which is exactly URLhaus's
+accepted type. There is no case where VirusTotal earns a row and URLhaus does
+not.
+
+**Why it was left out.** The overlap above, plus a difference in kind:
+`POST /urls` means "scan this", not "this is malicious". It carries no verdict,
+no category and no comment, so the argument the x-arf body makes, what happened
+and what is wanted, has nowhere to land. Recording a judgement would mean a
+second call to `POST /urls/{id}/votes` with different semantics. URLhaus is
+purpose-built for reporting a malicious URL and takes a threat classification
+and tags.
+
+**The interesting half is the READ side, and it collides with a property.**
+`GET /domains/{d}` and `GET /ip/{ip}` answer questions review actually has:
+how old is this domain, has anyone else flagged this host, is this dedicated
+attacker infrastructure or a compromised legitimate one. That would change
+what a user writes in a report and whether they send one.
+
+Two obstacles, and the second is the real one:
+
+- The second property says nothing is ever fetched or resolved. A VirusTotal
+ lookup asks a third party ABOUT an indicator rather than fetching it, so no
+ tracker fires and nothing confirms the address is live. That is the same
+ shape as an RDAP query, which the tool already makes. The property survives.
+- The fourth property is the obstacle. A query discloses which host is being
+ investigated, and `contacts.is_queryable()` is the single admission point
+ that exists because that leak happened three times. **A URL lookup cannot
+ pass it**: VirusTotal's URL endpoint takes a URL, and the fourth property is
+ precisely that a query carries a bare host or IP and never a URL. Redacting
+ the URL first does not rescue it, since a redacted URL hashes to a different
+ `/urls/{id}` than the real one and the lookup returns nothing. Domain and IP
+ lookups are bare values and would be fine.
+
+There is also a preference cost: VirusTotal is Google-owned, and every lookup
+tells Google which infrastructure a named consultant is investigating. RDAP
+carries the same disclosure but is unavoidable if the tool wants an abuse
+contact; this would be optional convenience.
+
+**Before building.** Use the tool on real cases first and find out whether
+review actually feels under-informed. Enrichment built against a guess about
+what review will want is the first rung of the ladder failing. If it is built,
+it is a `contacts`-time enrichment over domains and IPs through the existing
+admission point, writing what it learns into the manifest, and it needs its
+own spec: it changes a module that is already swept and settled.