rules:
  - id: auth.go.flow.oauth-credential-in-log
    languages:
      - go
    severity: ERROR
    message: |
      An OAuth/OIDC credential from the HTTP request flows into a logging call.
      The tainted value is an authorization `code`, an `access_token` /
      `refresh_token` / `id_token`, a bearer `token`, a `client_secret`, or
      the raw `Authorization` header, and the sink is a `log.*`, `slog.*`,
      `fmt.Print*`, or `logger.*` call. Logs are written to files, shipped to
      aggregators (Datadog, Splunk, CloudWatch) and read by people and systems
      that should never see live credentials. A leaked authorization code or
      token can be replayed to impersonate the user or complete the OAuth
      exchange (CWE-532).

      Never log the raw credential. Redact or mask it before logging, log a
      non-sensitive identifier instead (a user id, a key id), or drop the
      field entirely.
    # Taint mode so indirection is caught: `at := r.FormValue("access_token");
    # log.Println(at)` flags, not just the inline form. The source list is
    # narrowed to OAuth/OIDC credential field names (and the Authorization
    # header), so logging a benign request field such as `r.FormValue("page")`
    # does not fire. Routing the value through a redaction/masking helper clears
    # the taint.
    mode: taint
    pattern-sources:
      # Request getters keyed by a credential-looking parameter name.
      - patterns:
          - pattern-either:
              - pattern: $R.URL.Query().Get($K)
              - pattern: $R.FormValue($K)
              - pattern: $R.PostFormValue($K)
          - metavariable-regex:
              metavariable: $K
              regex: (?i)^"(code|access[_-]?token|accesstoken|refresh[_-]?token|refreshtoken|id[_-]?token|idtoken|token|client[_-]?secret|clientsecret)"$
      # The raw Authorization header carries the bearer / basic credential.
      - patterns:
          - pattern: $R.Header.Get($K)
          - metavariable-regex:
              metavariable: $K
              regex: (?i)^"authorization"$
    pattern-sanitizers:
      # Redaction / masking helpers: the value reaching the log is no longer
      # the live credential.
      - pattern: redact(...)
      - pattern: mask(...)
      - pattern: maskToken(...)
    pattern-sinks:
      # Standard library log / slog / fmt print sinks: any tainted argument.
      - patterns:
          - pattern-either:
              - pattern: log.Print(...)
              - pattern: log.Printf(...)
              - pattern: log.Println(...)
              - pattern: log.Fatal(...)
              - pattern: log.Fatalf(...)
              - pattern: log.Fatalln(...)
              - pattern: log.Panic(...)
              - pattern: log.Panicf(...)
              - pattern: slog.Info(...)
              - pattern: slog.Debug(...)
              - pattern: slog.Warn(...)
              - pattern: slog.Error(...)
              - pattern: fmt.Print(...)
              - pattern: fmt.Printf(...)
              - pattern: fmt.Println(...)
      # A log-named receiver with a log-level method: logger.Info(...),
      # myLog.Printf(...). The receiver-name constraint keeps this off
      # unrelated method calls.
      - patterns:
          - pattern: $LOG.$LEVEL(...)
          - metavariable-regex:
              metavariable: $LOG
              regex: (?i)^.*log(ger)?$
          - metavariable-regex:
              metavariable: $LEVEL
              regex: ^(Print|Printf|Println|Info|Infof|Infow|Debug|Debugf|Debugw|Warn|Warnf|Warning|Error|Errorf|Errorw|Fatal|Fatalf|Panic|Panicf|Trace|Tracef)$
    metadata:
      oauthlint-rule-id: AUTH-GO-FLOW-005
      oauthlint-doc-url: https://oauthlint.dev/rules/go-flow-oauth-credential-in-log
      category: security
      cwe: CWE-532
      owasp: API8:2023
      llm-prevalence: MEDIUM
      technology:
        - net/http
      references:
        - https://cwe.mitre.org/data/definitions/532.html
        - https://datatracker.ietf.org/doc/html/rfc6749#section-10.3
        - https://owasp.org/API-Security/editions/2023/en/0xa8-security-misconfiguration/
