fix(tirith): suppress .app lookalike_tld false positives in warn verdicts

Tirith flags .app domains with a lookalike_tld finding because the TLD
"can be confused with file extensions". This is a false positive for
legitimate production APIs (e.g. api.example.app, lark.app).

Add _is_app_tld_finding() and a post-parse suppression block in
check_command_security(): if the only finding(s) on a warn verdict are
lookalike_tld entries for .app, downgrade the action to allow.

Mixed findings (e.g. .app + shortened_url) and block verdicts are
unaffected. Non-.app lookalike_tld findings (.zip, .exe, etc.) are
preserved.

Add 15 regression tests covering: .app-only suppression, mixed-finding
preservation, non-.app TLD preservation, block-verdict invariance, and
the helper's field-name and case-insensitivity behaviour.

Closes #24461
This commit is contained in:
Wesley Simplicio 2026-05-12 18:53:44 -03:00 committed by Teknium
parent 1634397ddb
commit fae0fa4325
2 changed files with 149 additions and 0 deletions

View file

@ -771,4 +771,33 @@ def check_command_security(command: str) -> dict:
elif action == "warn":
summary = "security warning detected (details unavailable)"
# Suppress warn verdicts that consist solely of a lookalike_tld finding for
# the .app TLD. .app is a legitimate gTLD used by many production services
# and the "can be confused with file extensions" heuristic generates false
# positives for normal API calls. Any other finding (including other
# lookalike_tld entries for non-.app TLDs) preserves the warn action.
if action == "warn" and findings:
non_suppressible = [f for f in findings if not _is_app_tld_finding(f)]
if not non_suppressible:
action = "allow"
findings = []
summary = ""
return {"action": action, "findings": findings, "summary": summary}
def _is_app_tld_finding(finding: dict) -> bool:
"""Return True if this finding is a lookalike_tld warning for the .app TLD only.
Checks the rule_id and inspects common value/detail field names that
Tirith may use to carry the TLD string.
"""
if not isinstance(finding, dict):
return False
if finding.get("rule_id") != "lookalike_tld":
return False
for field in ("value", "tld", "detail", "description", "message"):
val = finding.get(field)
if val is not None and ".app" in str(val).lower():
return True
return False