{"record":{"id":"2925c3d5e413e4f9","repo":"shadow1ng/fscan","slug":"invalid-scram-nonce","errorCode":null,"errorMessage":"invalid SCRAM nonce","messagePattern":"invalid SCRAM nonce","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/mongodb.go","lineNumber":511,"sourceCode":"\t\t\tpos += 16\n\t\tdefault:\n\t\t\treturn reply, fmt.Errorf(\"unsupported bson type 0x%02x for key %s\", typ, key)\n\t\t}\n\t}\n\treturn reply, nil\n}\n\nfunc buildMongoSCRAMClientFinal(username, password, clientFirstBare, serverFirst string) (string, error) {\n\tattrs := parseSCRAMAttributes(serverFirst)\n\tserverNonce := attrs[\"r\"]\n\tsaltB64 := attrs[\"s\"]\n\titerText := attrs[\"i\"]\n\tif serverNonce == \"\" || saltB64 == \"\" || iterText == \"\" {\n\t\treturn \"\", fmt.Errorf(\"invalid SCRAM server-first payload\")\n\t}\n\tclientNonce := scramAttr(clientFirstBare, \"r\")\n\tif clientNonce == \"\" || !strings.HasPrefix(serverNonce, clientNonce) {\n\t\treturn \"\", fmt.Errorf(\"invalid SCRAM nonce\")\n\t}\n\tsalt, err := base64.StdEncoding.DecodeString(saltB64)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid SCRAM salt: %w\", err)\n\t}\n\titerations, err := strconv.Atoi(iterText)\n\tif err != nil || iterations <= 0 {\n\t\treturn \"\", fmt.Errorf(\"invalid SCRAM iteration count\")\n\t}\n\n\tclientFinalWithoutProof := \"c=biws,r=\" + serverNonce\n\tauthMessage := clientFirstBare + \",\" + serverFirst + \",\" + clientFinalWithoutProof\n\tdigest := md5.Sum([]byte(username + \":mongo:\" + password))\n\tsaltedPassword := pbkdf2.Key([]byte(fmt.Sprintf(\"%x\", digest)), salt, iterations, sha1.Size, sha1.New)\n\tclientKey := mongoHMAC(saltedPassword, []byte(\"Client Key\"))\n\tstoredKey := sha1.Sum(clientKey)\n\tclientSignature := mongoHMAC(storedKey[:], []byte(authMessage))\n\tproof := make([]byte, len(clientKey))","sourceCodeStart":493,"sourceCodeEnd":529,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/mongodb.go#L493-L529","documentation":"During SCRAM the server's nonce (r=) must begin with the client nonce the plugin generated in its client-first message. If the client nonce is empty or the server nonce is not prefixed by it, this error is thrown — the reply is either from a different handshake or is malicious/spoofed.","triggerScenarios":"serverFirst's r attribute does not start with the client-first bare message's r value: replies out of order, a replayed/foreign challenge, or a server that echoes a fresh nonce without incorporating the client's.","commonSituations":"MITM or spoofed responses during a scan; multiplexed connections where a reply from another session is read; a deliberately deceptive target service.","solutions":["Retry the handshake on a fresh connection to rule out a mixed-up response stream","Verify no proxy is interleaving MongoDB protocol frames","Confirm the client-first message sent actually contained an r= attribute","Treat repeated occurrences as evidence the target is not a legitimate SCRAM-speaking MongoDB"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"clientNonce := scramAttr(clientFirstBare, \"r\")\nif clientNonce == \"\" || !strings.HasPrefix(attrs[\"r\"], clientNonce) {\n    return errors.New(\"server nonce does not extend client nonce\")\n}","typeGuard":"func nonceExtendsClient(serverFirst, clientFirstBare string) bool {\n    return strings.HasPrefix(scramAttr(serverFirst, \"r\"), scramAttr(clientFirstBare, \"r\"))\n}","tryCatchPattern":"if err := doMongoDBAuth(ctx, addr, cred); err != nil && strings.Contains(err.Error(), \"invalid SCRAM nonce\") {\n    log.Warn(\"possible spoofed/replayed challenge; retrying on fresh connection\")\n    return retryFreshConn(ctx, addr, cred)\n}","preventionTips":["Always run SCRAM on a dedicated single-use connection","Treat nonce mismatch as a security signal, not just a parse failure","Verify no TLS-terminating proxy re-injects MongoDB frames"],"tags":["mongodb","scram","nonce","security"],"backgroundTag":"invalid-argument-value","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"}