# GO-CRYPTO-002: Use of SHA1 Weak Hash Algorithm

> **Severity:** HIGH | **CWE:** CWE-328 | **OWASP:** A02:2021

- **Language:** Go
- **Category:** Security
- **URL:** https://codepathfinder.dev/registry/golang/security/GO-CRYPTO-002
- **Detection:** `pathfinder scan --ruleset golang/GO-CRYPTO-002 --project .`

## Description

SHA-1 was broken in practice by the SHAttered attack (February 2017), produced by
Marc Stevens (CWI Amsterdam) and Google Research. The attack found two distinct PDF
files with identical SHA-1 digests using 9.2 × 10^18 SHA-1 computations — equivalent
to 6,500 CPU-years and 100 GPU-years, at a cost of roughly $110,000 on cloud hardware.

NIST announced in December 2022 that SHA-1 is being deprecated for ALL applications
(not just digital signatures). The deadline is December 31, 2030, after which any FIPS
140-validated module listing SHA-1 as an approved algorithm moves to the historical list.

All major browser vendors (Chrome, Firefox, Edge, Safari) stopped trusting SHA-1
TLS certificates by January–March 2017. The CA/Browser Forum banned issuance of
SHA-1-signed TLS certificates effective January 1, 2016.

Git still uses SHA-1 for object naming (commit/tree/blob hashes), and migration to
SHA-256 is in progress since Git 2.29 (2020). The SHAttered team noted that crafting
a colliding Git object is harder than generic collision due to format constraints,
but the technical feasibility is established.

**SHA-1 in HMAC (edge case)**: HMAC-SHA1 is not directly affected by SHA-1 collision
attacks because HMAC's security proof relies on PRF properties, not collision resistance.
HMAC-SHA1 remains used in OAuth 1.0a. However, HMAC-SHA256 is universally supported
and preferred for all new implementations.


## Vulnerable Code

```python
# --- file: vulnerable.go ---
// GO-CRYPTO-002 positive test cases — all SHOULD be detected
package main

import "crypto/sha1"

func weakSHA1New() {
	h := sha1.New()           // SINK: SHA1 collision attack known
	h.Write([]byte("data"))
	_ = h.Sum(nil)
}

func weakSHA1Sum() {
	hash := sha1.Sum([]byte("data")) // SINK: SHA1 weak hash
	_ = hash
}

# --- file: go.mod ---
module example.com/go-crypto-002/positive

go 1.21

# --- file: go.sum ---

```

## Secure Code

```python
// SECURE: SHA-256 for file integrity
import "crypto/sha256"

func hashFile(data []byte) string {
    h := sha256.Sum256(data)
    return fmt.Sprintf("%x", h)
}

// SECURE: SHA-256 streaming for large files
func hashFileLarge(r io.Reader) (string, error) {
    h := sha256.New()
    if _, err := io.Copy(h, r); err != nil {
        return "", err
    }
    return fmt.Sprintf("%x", h.Sum(nil)), nil
}

// SECURE: HMAC-SHA256 for message authentication
import "crypto/hmac"

func computeHMAC(key, data []byte) []byte {
    mac := hmac.New(sha256.New, key)
    mac.Write(data)
    return mac.Sum(nil)
}

// Migration note: SHA-256 output is 32 bytes (64 hex chars)
// vs SHA-1's 20 bytes (40 hex chars).
// Widen any database columns or cache keys storing these values.

```

## Detection Rule (Python SDK)

```python
"""GO-CRYPTO-002: Use of SHA1 weak hash algorithm."""

from codepathfinder.go_rule import QueryType
from codepathfinder import flows
from codepathfinder.go_decorators import go_rule


class GoCryptoSHA1(QueryType):
    fqns = ["crypto/sha1"]
    patterns = ["sha1.*"]
    match_subclasses = False


@go_rule(
    id="GO-CRYPTO-002",
    severity="HIGH",
    cwe="CWE-328",
    owasp="A02:2021",
    tags="go,security,crypto,sha1,weak-hash,CWE-328,OWASP-A02",
    message=(
        "Detected use of the SHA1 hash algorithm (crypto/sha1). "
        "SHA1 is cryptographically weak — it has known collision attacks (SHAttered, 2017). "
        "Use crypto/sha256 or crypto/sha512 instead for new code."
    ),
)
def detect_sha1_weak_hash():
    """Detect use of SHA1 hashing (crypto/sha1.New or sha1.Sum)."""
    return GoCryptoSHA1.method("New", "Sum")
```

## How to Fix

- Replace sha1.New() and sha1.Sum() with sha256.New() and sha256.Sum256().
- For SHA-512 where larger output is needed: use crypto/sha512.
- Audit stored SHA-1 hashes and plan migration to SHA-256 for all security-relevant uses.
- For HMAC, prefer HMAC-SHA256 over HMAC-SHA1 in all new code.
- Note output size change (20 bytes → 32 bytes) — update any fixed-width columns.
- For password hashing, use bcrypt or argon2id — not any variant of SHA.

## Security Implications

- **Forged TLS Certificates:** A SHA-1 collision enables certificate forgery. In the 2008 rogue CA attack (Sotirov et al.),
researchers used MD5 collisions to create a rogue CA certificate. The same attack class
applies to SHA-1. Browser vendors removed SHA-1 trust precisely to prevent this.

- **Code Signing Bypass:** If a build system or software distribution pipeline verifies code signatures using SHA-1,
an attacker who can produce a colliding binary passes the integrity check. The SHAttered
PDFs demonstrate the collision is real and producible with nation-state resources.

- **Git Repository Poisoning:** In Git's SHA-1-based object model, a commit/tree/blob hash acts as both the object ID
and its integrity proof. A SHA-1 collision attack against Git objects could theoretically
insert malicious content while preserving the expected hash, though the attack is more
complex than generic file collisions due to Git object format requirements.


## References

- [SHAttered — First SHA-1 Collision (IACR ePrint 2017/190)](https://eprint.iacr.org/2017/190)
- [SHAttered paper PDF — Stevens et al. (CWI/Google, CRYPTO 2017)](https://eprint.iacr.org/2017/190.pdf)
- [NIST: Transitioning Away from SHA-1 for All Applications (December 2022)](https://csrc.nist.gov/news/2022/nist-transitioning-away-from-sha-1-for-all-apps)
- [NIST retires SHA-1 cryptographic algorithm (news release, 2022)](https://www.nist.gov/news-events/news/2022/12/nist-retires-sha-1-cryptographic-algorithm)
- [NIST SP 800-131A Revision 2 — Transitioning Cryptographic Algorithms](https://csrc.nist.gov/pubs/sp/800/131/a/r2/final)
- [CWI announcement: First SHA-1 collision](https://www.cwi.nl/en/news/cwi-and-google-announce-first-collision-for-industry-security-standard-sha-1/)
- [Chrome SHA-1 deprecation timeline (Chromium security)](https://www.chromium.org/Home/chromium-security/education/tls/sha-1/)
- [Git hash-function-transition documentation](https://git-scm.com/docs/hash-function-transition)
- [Go crypto/sha256 package documentation](https://pkg.go.dev/crypto/sha256)
- [Go crypto/sha1 package documentation](https://pkg.go.dev/crypto/sha1)
- [CWE-328: Use of Weak Hash](https://cwe.mitre.org/data/definitions/328.html)
- [OWASP Cryptographic Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html)

---

Source: https://codepathfinder.dev/registry/golang/security/GO-CRYPTO-002
Code Pathfinder — Open source, type-aware SAST with cross-file dataflow analysis
