{"record":{"id":"5e6a8b30588f1ea2","repo":"shadow1ng/fscan","slug":"invalid-scram-salt-w","errorCode":null,"errorMessage":"invalid SCRAM salt: %w","messagePattern":"invalid SCRAM salt: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/mongodb.go","lineNumber":515,"sourceCode":"\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))\n\tfor i := range clientKey {\n\t\tproof[i] = clientKey[i] ^ clientSignature[i]\n\t}\n\treturn clientFinalWithoutProof + \",p=\" + base64.StdEncoding.EncodeToString(proof), nil","sourceCodeStart":497,"sourceCodeEnd":533,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/mongodb.go#L497-L533","documentation":"Guard in buildMongoSCRAMClientFinal: the base64-decoded SCRAM salt from the MongoDB server-first message could not be used (decode failure or unusable length). The SCRAM-SHA-1 exchange cannot continue because ClientKey computation requires the salt and iteration count.","triggerScenarios":"The s= attribute in the server-first payload contains characters outside the standard base64 alphabet or has wrong padding — e.g. URL-safe base64 (-/ instead of +/), whitespace, or truncation by a middlebox.","commonSituations":"Proxies rewriting payloads; custom server implementations that URL-safe-encode the salt; corrupted scan traffic over unreliable links.","solutions":["Inspect the s= value for non-standard base64 characters or bad padding","Support RawStdEncoding/URL-safe fallback decoding if a non-standard server is expected","Capture the raw reply to check for truncation en route","Confirm against a known-good mongod that the payload decodes cleanly"],"exampleFix":"// before\nsalt, err := base64.StdEncoding.DecodeString(saltB64)\n// after\nsalt, err := base64.StdEncoding.DecodeString(saltB64)\nif err != nil {\n    salt, err = base64.RawStdEncoding.DecodeString(strings.TrimRight(saltB64, \"=\"))\n}","handlingStrategy":"validation","validationCode":"if _, err := base64.StdEncoding.DecodeString(saltB64); err != nil {\n    return fmt.Errorf(\"salt not standard base64: %w\", err)\n}","typeGuard":"func isValidB64(s string) bool {\n    _, err := base64.StdEncoding.DecodeString(s)\n    return err == nil && len(s) > 0\n}","tryCatchPattern":"final, err := buildMongoSCRAMClientFinal(u, p, cfb, serverFirst)\nif err != nil {\n    var b64Err base64.CorruptInputError\n    if errors.As(err, &b64Err) {\n        log.Warnf(\"salt base64 corrupt at offset %d\", int(b64Err))\n        return\n    }\n    return err\n}","preventionTips":["Check the s= attribute alphabet before decoding","Capture raw replies when scanning through proxies","Only expect standard base64 salts from stock mongod"],"tags":["mongodb","scram","base64","validation"],"backgroundTag":"invalid-argument-format","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"}