T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/badge_verify.py:50
- Finding
- Certificates Can Be Reported as Verified Without Authoritative Validation## Vulnerability Details **File Location**: `scripts/badge_verify.py`, lines 50-69 **Vulnerability Type**: Authentication bypass caused by optional trust-source validation **Risk Level**: High **Vulnerable Code**: ```python canon = json.dumps({k: cert[k] for k in REQUIRED[:-1]}, ensure_ascii=False, sort_keys=True) recomputed = sha256_of(canon) checks.append(("指纹防篡改", recomputed == cert.get("fingerprint"), f"重算={recomputed[:16]}… vs 证书={str(cert.get('fingerprint'))[:16]}…")) reg_ok, reg_note = None, "未提供台账,跳过对账" if a.registry: rp = pathlib.Path(a.registry) if rp.exists(): reg = json.loads(rp.read_text(encoding="utf-8")) hit = [x for x in reg.get("issued", []) if x.get("serial") == cert.get("serial")] reg_ok = bool(hit) and hit[0].get("fingerprint") == cert.get("fingerprint") reg_note = "台账命中且指纹一致" if reg_ok else "台账无此编号或指纹不一致(伪造/已吊销)" else: reg_ok = False reg_note = f"台账不存在: {a.registry}" if reg_ok is not None: checks.append(("台账对账", reg_ok, reg_note)) ok = all(c[1] for c in checks) ``` ### Technical Analysis The certificate fingerprint is an unkeyed SHA-256 digest calculated exclusively from certificate fields controlled by the party presenting the certificate. It proves only that the fields and fingerprint are internally consistent; it does not prove that a trusted issuer created the certificate. Registry validation is optional. When `--registry` is omitted, no authoritative check is added to `checks`, and `all(c[1] for c in checks)` can return `True` based solely on structural completeness and an attacker-generated fingerprint. The resulting output uses `verified: true` or an equivalent success message, which overstates the security property established by the code. ### Attack Path 1. An attacker creates arbitrary values for `badge`, `serial`, `holder`, `issuer`, `issued_at`, and `evidence_sha256`. 2. The attacker ...[truncated 717 chars]
- Remediation
- ## Remediation Suggestions - Require a trusted registry for any result labeled `verified`. - If no registry is supplied, return a distinct result such as `integrity_valid_but_authenticity_unverified` and use a non-success exit status where authenticity is required. - Prefer issuer authentication through a digital signature verified with a pinned or otherwise trusted issuer public key. - Define a versioned canonicalization and signature format to prevent implementation differences. - Clearly distinguish integrity checks from issuer-authenticity checks in CLI output and documentation. - Add tests proving that a self-generated certificate cannot receive an authoritative verified status without a trusted registry or valid issuer signature.
