{"record":{"id":"76c5ab1440ef0f45","repo":"shadow1ng/fscan","slug":"service-auth-failed-d","errorCode":null,"errorMessage":"service_auth_failed: %d","messagePattern":"service_auth_failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"plugins/services/neo4j.go","lineNumber":112,"sourceCode":"\t\t\tError:     err,\n\t\t}\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\tif resp.StatusCode == 200 {\n\t\treturn &AuthResult{\n\t\t\tSuccess:   true,\n\t\t\tConn:      &neo4jConnWrapper{},\n\t\t\tErrorType: ErrorTypeUnknown,\n\t\t\tError:     nil,\n\t\t}\n\t}\n\n\tif resp.StatusCode == 401 || resp.StatusCode == 403 {\n\t\treturn &AuthResult{\n\t\t\tSuccess:   false,\n\t\t\tErrorType: ErrorTypeAuth,\n\t\t\tError:     fmt.Errorf(i18n.GetText(\"service_auth_failed\")+\": %d\", resp.StatusCode),\n\t\t}\n\t}\n\n\treturn &AuthResult{\n\t\tSuccess:   false,\n\t\tErrorType: ErrorTypeUnknown,\n\t\tError:     fmt.Errorf(i18n.GetText(\"unknown_status_code\")+\": %d\", resp.StatusCode),\n\t}\n}\n\n// neo4jConnWrapper Neo4j连接包装器\ntype neo4jConnWrapper struct{}\n\nfunc (w *neo4jConnWrapper) Close() error {\n\treturn nil\n}\n\n// classifyNeo4jErrorType Neo4j错误分类","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/neo4j.go#L94-L130","documentation":"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.","triggerScenarios":"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).","commonSituations":"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).","solutions":["Treat 401 as a simple wrong-password result — continue with the next credential; nothing to fix in the client.","For 403, verify manually whether the password is actually valid but the account lacks access to /user/neo4j (try a login endpoint instead).","Check for WAF/proxy policies returning 401/403 independent of Neo4j auth, and bypass or allowlist the scanner.","Confirm auth-related Neo4j settings (dbms.security.auth_enabled) if you expected unauthenticated access."],"exampleFix":"// before\nif resp.StatusCode == 401 || resp.StatusCode == 403 {\n    return authFailedWithStatus(resp.StatusCode)\n}\n// after\nif resp.StatusCode == 401 {\n    return authFailedWithStatus(resp.StatusCode) // credentials rejected\n}\nif resp.StatusCode == 403 {\n    return &AuthResult{Success: false, ErrorType: ErrorTypePermission, Error: fmt.Errorf(\"forbidden: %d\", resp.StatusCode)}\n}","handlingStrategy":"try-catch","validationCode":"if resp.StatusCode == 401 || resp.StatusCode == 403 {\n    // record credential as rejected; do not retry the same pair\n}","typeGuard":null,"tryCatchPattern":"res := doNeo4jAuth(ctx, info, cred, session)\nif res.ErrorType == ErrorTypeAuth {\n    // move on to the next credential; check server logs if 403 persists\n}","preventionTips":["Expect 401 as the normal rejection signal during brute force.","Investigate persistent 403s separately: valid password but insufficient privileges.","Rule out WAF/proxy 401/403 responses that are not Neo4j auth failures.","Confirm dbms.security.auth_enabled matches the expected access model."],"tags":["neo4j","http","authentication","http-401"],"backgroundTag":"http-error-response","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}