shadow1ng/fscan · warning

service_auth_failed: %d

Error message

service_auth_failed: %d

What it means

doNeo4jAuth probes the Neo4j HTTP endpoint (/user/neo4j) with basic-auth credentials. A 401 or 403 response means the credentials were rejected, so it returns an AuthResult with ErrorTypeAuth and the localized 'service_auth_failed' message plus the status code.

Source

Thrown at plugins/services/neo4j.go:112

			Error:     err,
		}
	}
	defer func() { _ = resp.Body.Close() }()

	if resp.StatusCode == 200 {
		return &AuthResult{
			Success:   true,
			Conn:      &neo4jConnWrapper{},
			ErrorType: ErrorTypeUnknown,
			Error:     nil,
		}
	}

	if resp.StatusCode == 401 || resp.StatusCode == 403 {
		return &AuthResult{
			Success:   false,
			ErrorType: ErrorTypeAuth,
			Error:     fmt.Errorf(i18n.GetText("service_auth_failed")+": %d", resp.StatusCode),
		}
	}

	return &AuthResult{
		Success:   false,
		ErrorType: ErrorTypeUnknown,
		Error:     fmt.Errorf(i18n.GetText("unknown_status_code")+": %d", resp.StatusCode),
	}
}

// neo4jConnWrapper Neo4j连接包装器
type neo4jConnWrapper struct{}

func (w *neo4jConnWrapper) Close() error {
	return nil
}

// classifyNeo4jErrorType Neo4j错误分类

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Treat 401 as a simple wrong-password result — continue with the next credential; nothing to fix in the client.
  2. For 403, verify manually whether the password is actually valid but the account lacks access to /user/neo4j (try a login endpoint instead).
  3. Check for WAF/proxy policies returning 401/403 independent of Neo4j auth, and bypass or allowlist the scanner.
  4. Confirm auth-related Neo4j settings (dbms.security.auth_enabled) if you expected unauthenticated access.

Example fix

// before
if resp.StatusCode == 401 || resp.StatusCode == 403 {
    return authFailedWithStatus(resp.StatusCode)
}
// after
if resp.StatusCode == 401 {
    return authFailedWithStatus(resp.StatusCode) // credentials rejected
}
if resp.StatusCode == 403 {
    return &AuthResult{Success: false, ErrorType: ErrorTypePermission, Error: fmt.Errorf("forbidden: %d", resp.StatusCode)}
}
Defensive patterns

Strategy: try-catch

Validate before calling

if resp.StatusCode == 401 || resp.StatusCode == 403 {
    // record credential as rejected; do not retry the same pair
}

Try / catch

res := doNeo4jAuth(ctx, info, cred, session)
if res.ErrorType == ErrorTypeAuth {
    // move on to the next credential; check server logs if 403 persists
}

Prevention

When it happens

Trigger: Any GET to http://<target>/user/neo4j with the candidate Credential's basic-auth that the server answers with HTTP 401 (bad user/pass) or 403 (authenticated but forbidden).

Common situations: Neo4j instances where auth is enabled and the guessed password is wrong (expected during scanning); 403 returned because the account lacks permissions to the /user endpoint even with a valid password; a reverse proxy in front returning 401/403 for its own reasons (IP blocklist, WAF).

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/76c5ab1440ef0f45. Report an issue: GitHub.