[object Object]

← back to Cli Printing Press

fix(cli): score auth prefixes from config (#332)

8bad2efd83dc85c125b69471c8b4336aec7d4dff · 2026-04-27 01:30:50 -0700 · Trevin Chow

Files touched

Diff

commit 8bad2efd83dc85c125b69471c8b4336aec7d4dff
Author: Trevin Chow <trevin@trevinchow.com>
Date:   Mon Apr 27 01:30:50 2026 -0700

    fix(cli): score auth prefixes from config (#332)
---
 internal/pipeline/scorecard.go            | 19 ++++++++--
 internal/pipeline/scorecard_tier2_test.go | 62 +++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/internal/pipeline/scorecard.go b/internal/pipeline/scorecard.go
index f8e68ed0..dd869334 100644
--- a/internal/pipeline/scorecard.go
+++ b/internal/pipeline/scorecard.go
@@ -1707,17 +1707,17 @@ func scoreAuthScheme(clientContent, configContent, authContent string, scheme op
 	switch {
 	case strings.Contains(nameLower, "bot"):
 		scoreable = true
-		if strings.Contains(clientContent, `"Bot "`) || strings.Contains(clientContent, "`Bot `") {
+		if authPrefixLiteralPresent("Bot", clientContent, configContent, authContent) {
 			authHeaderMatched = true
 		}
 	case strings.Contains(nameLower, "bearer") || (scheme.Type == "http" && scheme.Scheme == "bearer"):
 		scoreable = true
-		if strings.Contains(clientContent, `"Bearer "`) || strings.Contains(clientContent, "`Bearer `") {
+		if authPrefixLiteralPresent("Bearer", clientContent, configContent, authContent) {
 			authHeaderMatched = true
 		}
 	case strings.Contains(nameLower, "basic") || (scheme.Type == "http" && scheme.Scheme == "basic"):
 		scoreable = true
-		if strings.Contains(clientContent, `"Basic "`) || strings.Contains(clientContent, "`Basic `") {
+		if authPrefixLiteralPresent("Basic", clientContent, configContent, authContent) {
 			authHeaderMatched = true
 		}
 	case strings.EqualFold(scheme.Type, "apikey"):
@@ -1733,7 +1733,7 @@ func scoreAuthScheme(clientContent, configContent, authContent string, scheme op
 		}
 	case strings.EqualFold(scheme.Type, "oauth2"), strings.EqualFold(scheme.Type, "openidconnect"):
 		scoreable = true
-		if strings.Contains(clientContent, `"Bearer "`) || strings.Contains(clientContent, "`Bearer `") {
+		if authPrefixLiteralPresent("Bearer", clientContent, configContent, authContent) {
 			authHeaderMatched = true
 		}
 	}
@@ -1782,6 +1782,17 @@ func scoreAuthScheme(clientContent, configContent, authContent string, scheme op
 	return score, true
 }
 
+func authPrefixLiteralPresent(prefix string, contents ...string) bool {
+	doubleQuoted := `"` + prefix + ` "`
+	rawQuoted := "`" + prefix + " `"
+	for _, content := range contents {
+		if strings.Contains(content, doubleQuoted) || strings.Contains(content, rawQuoted) {
+			return true
+		}
+	}
+	return false
+}
+
 func isHTTPMethod(method string) bool {
 	switch strings.ToLower(method) {
 	case "get", "put", "post", "delete", "options", "head", "patch", "trace":
diff --git a/internal/pipeline/scorecard_tier2_test.go b/internal/pipeline/scorecard_tier2_test.go
index b4243084..75ae69db 100644
--- a/internal/pipeline/scorecard_tier2_test.go
+++ b/internal/pipeline/scorecard_tier2_test.go
@@ -663,6 +663,68 @@ func setAuth(req *request, token string) {
 		assert.Greater(t, sc.Steinberger.AuthProtocol, 0)
 	})
 
+	t.Run("bearer prefix in config scores auth protocol", func(t *testing.T) {
+		dir := t.TempDir()
+		writeScorecardFixture(t, dir, "internal/client/client.go", `
+package client
+
+import "net/http"
+
+func setAuth(req *http.Request, authHeader string) {
+	req.Header.Set("Authorization", authHeader)
+}
+`)
+		writeScorecardFixture(t, dir, "internal/config/config.go", `
+package config
+
+import "os"
+
+type Config struct {
+	CalComToken string
+}
+
+func Load() Config {
+	return Config{CalComToken: os.Getenv("CAL_COM_TOKEN")}
+}
+
+func (c Config) AuthHeader() string {
+	return "Bearer " + c.CalComToken
+}
+`)
+
+		specPath := filepath.Join(dir, "spec-bearer-config.json")
+		writeScorecardFixture(t, dir, "spec-bearer-config.json", `{
+  "paths": {
+    "/bookings": {
+      "get": {
+        "security": [
+          {
+            "CAL_COM_TOKEN": []
+          }
+        ],
+        "responses": {
+          "200": { "description": "ok" }
+        }
+      }
+    }
+  },
+  "components": {
+    "securitySchemes": {
+      "CAL_COM_TOKEN": {
+        "type": "http",
+        "scheme": "bearer"
+      }
+    }
+  }
+}`)
+
+		pipelineDir := t.TempDir()
+		sc, err := RunScorecard(dir, pipelineDir, specPath, nil)
+		assert.NoError(t, err)
+		assert.NotContains(t, sc.UnscoredDimensions, "auth_protocol")
+		assert.GreaterOrEqual(t, sc.Steinberger.AuthProtocol, 7)
+	})
+
 	t.Run("anonymous alternative leaves auth unscored", func(t *testing.T) {
 		dir := t.TempDir()
 		writeScorecardFixture(t, dir, "internal/client/client.go", `

← 09dccfb9 feat(cli): add probe-reachability for no-browser challenge c  ·  back to Cli Printing Press  ·  fix(cli): printing-press P1 machine fixes (issue #333) (#335 6b2be74d →