Skip to content

fix: the password hashing implementation uses scrypt... in... - #5

Open
anupamme wants to merge 1 commit into
Xiaokebuyu:mainfrom
anupamme:fix-repo-nodesign-scrypt-cost-parameter-v-001
Open

fix: the password hashing implementation uses scrypt... in...#5
anupamme wants to merge 1 commit into
Xiaokebuyu:mainfrom
anupamme:fix-repo-nodesign-scrypt-cost-parameter-v-001

Conversation

@anupamme

Copy link
Copy Markdown

Summary

Fix high severity security issue in server/auth/users-store.js.

Vulnerability

Field Value
ID V-001
Severity HIGH
Scanner multi_agent_ai
Rule V-001
File server/auth/users-store.js:49
Assessment Likely exploitable
Chain Complexity 2-step

Description: The password hashing implementation uses scrypt with N=16384 (2^14), which is below the recommended minimum of 2^15 (32768) iterations. This makes offline brute-force attacks significantly easier if an attacker obtains the password database through a data breach.

Evidence

Exploitation scenario: An attacker who obtains the password database can perform offline brute-force attacks with reduced computational cost.

Scanner confirmation: multi_agent_ai rule V-001 flagged this pattern.

Production code: This file is in the production codebase, not test-only code.

Threat Model Context

This is a web service - vulnerabilities in request handlers are directly exploitable by remote attackers.

Changes

  • server/auth/users-store.js

Behavior Preservation

The change is scoped to 1 file on the vulnerable path; it only tightens handling of untrusted input and leaves valid inputs unaffected.

Security Invariant

Property: The security boundary is maintained under adversarial input

Regression test
import { describe, test, expect } from 'vitest';
import { hashPassword } from './server/auth/users-store.js';

describe("password hashing uses sufficient scrypt iterations (N >= 32768)", () => {
  const passwords = [
    "weak",           // weak password - should still have strong KDF
    "a".repeat(1000), // boundary: long password
    "ValidP@ss123",   // valid input
  ];

  test.each(passwords)("hashes password '%s' with adequate iterations", (password) => {
    const hash = hashPassword(password);
    const parts = hash.split('$');
    expect(parts[0]).toBe('scrypt');
    const N = parseInt(parts[1], 10);
    expect(N).toBeGreaterThanOrEqual(32768);
  });
});

This test guards against regressions — it's useful independent of the code change above.


Automated security fix by OrbisAI Security

Automated security fix generated by OrbisAI Security
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant