CVE-2026-58269: @sync in/server Sync-in Server Has A Complete Vulnerability

HIGH
Advisory Identifier: GHSA-92cr-jxw4-5wjg
CVSS 8.1
CWE-288
Published
Advisory Summary

CVE-2026-58269 is a HIGH (CVSS 8.1) sync-in server has a complete vulnerability (CWE-288: Authentication Bypass Using an Alternate Path or Channel) affecting @sync in/server libraries in the npm ecosystem. The issue involves sync-in server has a complete 2fa bypass via `post /api/auth/token`. Remediation is available by upgrading affected packages to version 2.4.0.

CVE-2026-58269 at a Glance

CVE Identifier CVE-2026-58269
GHSA Identifier GHSA-92cr-jxw4-5wjg
Severity HIGH
CVSS v3.1 Base Score 8.1
CWE Classification CWE-288: Authentication Bypass Using an Alternate Path or Channel
Affected Product @sync in/server
Package Ecosystem npm
Published Date
Last Updated

Security Impact

CVSS: 8.1

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required Low (PR:L)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity High (I:H)
Availability None (A:N)

How to Fix CVE-2026-58269

To remediate this vulnerability, upgrade all affected @sync in/server dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

@sync-in/server fixed: 2.4.0
npm install @sync-in/server@2.4.0
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

npm ls @sync-in/server

How to Check if You Are Affected

To determine whether your Node.js application is affected by CVE-2026-58269, inspect your project dependencies using npm:

npm ls @sync-in/server

Analyze the terminal output to locate any version of @sync in/server in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2.4.0), your application is affected.

Note: The npm ls @sync-in/server command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-288: Authentication Bypass Using an Alternate Path or Channel, where the product requires authentication, but the product has an alternate path or channel that does not require authentication. In @sync in/server, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

**Affected component:** Sync-in Server v2.3.0, `POST /api/auth/token` (`auth.controller.ts:50-55`). **Required attacker capability:** Valid username and password for a 2FA-enabled account. ## Summary `POST /api/auth/token` authenticates with username and password only, then calls `getTokens()`, which returns unrestricted Bearer access and refresh JWTs without checking whether the account has TOTP 2FA enabled. An attacker who already knows valid credentials for a 2FA-enabled account can bypass 2FA in a single request. The parallel login endpoint (`POST /api/auth/login`) correctly enforces 2FA by calling `setCookies(user, res, true)`, which gates on `user.twoFaEnabled` when server-side TOTP is enabled. ## Details The token endpoint at `auth.controller.ts:50-55` uses `AuthLocalGuard` (password-only) and calls `getTokens()` directly: ```typescript // auth.controller.ts:50-55 @Post(AUTH_ROUTE.TOKEN) @AuthTokenSkip() @UseGuards(AuthLocalGuard) token(@GetUser() user: UserModel): Promise<TokenResponseDto> { return this.authManager.getTokens(user) } ``` `getTokens()` at `auth.service.ts:25-39` signs and returns access and refresh JWTs. It never reads `user.twoFaEnabled`: ```typescript // auth.service.ts:25-39 async getTokens(user: UserModel, refresh = false): Promise<TokenResponseDto> { const currentTime = currentTimeStamp() // ...expiration logic... return { [TOKEN_TYPE.ACCESS]: await this.jwtSign(user, TOKEN_TYPE.ACCESS, accessExpiration), [TOKEN_TYPE.REFRESH]: await this.jwtSign(user, TOKEN_TYPE.REFRESH, refreshExpiration), // ... } } ``` Compare with the login endpoint at `auth.controller.ts:30-35`, which calls `setCookies(user, res, true)`. Inside `setCookies()` at `auth.service.ts:45`, the 2FA gate fires: ```typescript // auth.service.ts:45 const verify2Fa = init2FaVerify && configuration.auth.mfa.totp.enabled && user.twoFaEnabled ``` When `verify2Fa` is true, `setCookies()` issues only a restricted `ACCESS_2FA` token and requires the user to complete `POST /api/auth/2fa/login/verify` before receiving full session cookies. The token endpoint has no equivalent gate. ## PoC ### Prerequisites - A Sync-in instance with TOTP 2FA enabled server-wide. - A user account with 2FA enrolled (the target). - The target's valid login and password, but not the TOTP secret or current TOTP code. ### Steps 1. **Enable 2FA on the target account.** Log in as the target user, navigate to Settings, and enable TOTP two-factor authentication. 2. **Confirm normal login requires 2FA.** Log out. Log back in with the target's credentials. The UI presents a TOTP code prompt before granting access, and the API response contains only `token.access_2fa_expiration` (a restricted partial token): ``` POST /api/auth/login {"login":"test","password":"..."} Response: {"user":{"twoFaEnabled":true},"server":{"twoFaEnabled":true},"token":{"access_2fa_expiration":1781234379}} ``` 3. **Bypass 2FA via the token endpoint.** Send the same credentials to `/api/auth/token`: ``` POST /api/auth/token {"login":"test","password":"..."} Response: { "access": "eyJhbGciOiJIUzI1NiIs...", "refresh": "eyJhbGciOiJIUzI1NiIs...", "access_expiration": 1781235890, "refresh_expiration": 1781248490 } ``` Unrestricted Bearer access and refresh JWTs are returned. No TOTP code was required. 4. **Confirm API access.** Use the token on a protected endpoint: ``` GET /api/users/me Authorization: Bearer eyJhbGciOiJIUzI1NiIs... Response: {"user":{"id":16,"login":"test","email":"test@lab.local","twoFaEnabled":true,...}} ``` The server returns the user profile. Protected API endpoints that accept Bearer authentication are accessible as the target user. No TOTP code was required at any step. ### Measured observations - The login endpoint (`/api/auth/login`) correctly returns a restricted 2FA-pending response. - The token endpoint (`/api/auth/token`) returns unrestricted Bearer JWTs with the same credentials and no TOTP. - The returned Bearer token grants access to protected API endpoints as a fully authenticated user, though cookie-specific flows may differ. ## Impact An attacker who already knows valid credentials for a 2FA-enabled account can obtain unrestricted Bearer access and refresh JWTs in a single HTTP request, without knowing the TOTP secret or possessing the authenticator device. 2FA security is bypassed for Bearer-token API authentication. ## Remediation Gate the token endpoint behind the same 2FA policy used by the login route. After `AuthLocalGuard` validates the username and password, require a valid TOTP code when server-side TOTP is enabled and `user.twoFaEnabled` is true, before calling `getTokens()`.

CVE-2026-58269 Affected @sync in/server Versions

1 component(s)
Fixed Versions:
2.4.0
Product / Package Ecosystem Affected Versions Fixed Version
@sync-in/server
npm
< 2.4.0
2.4.0

References

Frequently Asked Questions

What is CVE-2026-58269?
CVE-2026-58269 is a security vulnerability in @sync in/server involving Sync-in Server has a complete 2FA Bypass via `POST /api/auth/token` under CWE-288: Authentication Bypass Using an Alternate Path or Channel.
Which @sync in/server versions are affected?
Affected versions include releases prior to 2.4.0 across affected packages: @sync-in/server.
What version fixes CVE-2026-58269?
Upgrading to 2.4.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is @sync-in/server affected?
Yes, @sync-in/server is affected in releases prior to 2.4.0. Upgrade your dependency to 2.4.0 or later.
What is the CVSS score of CVE-2026-58269?
CVE-2026-58269 has a CVSS v3.1 base score of 8.1 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N.
What CWE is associated with CVE-2026-58269?
CVE-2026-58269 is classified under CWE-288: Authentication Bypass Using an Alternate Path or Channel (The product requires authentication, but the product has an alternate path or channel that does not require authentication.).
How can I check npm dependencies for CVE-2026-58269?
Run the dependency tree command: 'npm ls @sync-in/server'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-92cr-jxw4-5wjg",
  "modified" : "2026-09-22T14:46:31Z",
  "published" : "2026-09-22T14:46:30Z",
  "aliases" : [ "CVE-2026-58269" ],
  "summary" : "Sync-in Server has a complete 2FA Bypass via `POST /api/auth/token`",
  "details" : "**Affected component:** Sync-in Server v2.3.0, `POST /api/auth/token` (`auth.controller.ts:50-55`).\n\n**Required attacker capability:** Valid username and password for a 2FA-enabled account.\n\n## Summary\n\n`POST /api/auth/token` authenticates with username and password only, then calls `getTokens()`, which returns unrestricted Bearer access and refresh JWTs without checking whether the account has TOTP 2FA enabled. An attacker who already knows valid credentials for a 2FA-enabled account can bypass 2FA in a single request.\n\nThe parallel login endpoint (`POST /api/auth/login`) correctly enforces 2FA by calling `setCookies(user, res, true)`, which gates on `user.twoFaEnabled` when server-side TOTP is enabled.\n\n## Details\n\nThe token endpoint at `auth.controller.ts:50-55` uses `AuthLocalGuard` (password-only) and calls `getTokens()` directly:\n```typescript\n// auth.controller.ts:50-55\n@Post(AUTH_ROUTE.TOKEN)\n@AuthTokenSkip()\n@UseGuards(AuthLocalGuard)\ntoken(@GetUser() user: UserModel): Promise<TokenResponseDto> {\n  return this.authManager.getTokens(user)\n}\n```\n`getTokens()` at `auth.service.ts:25-39` signs and returns access and refresh JWTs. It never reads `user.twoFaEnabled`:\n```typescript\n// auth.service.ts:25-39\nasync getTokens(user: UserModel, refresh = false): Promise<TokenResponseDto> {\n  const currentTime = currentTimeStamp()\n  // ...expiration logic...\n  return {\n    [TOKEN_TYPE.ACCESS]: await this.jwtSign(user, TOKEN_TYPE.ACCESS, accessExpiration),\n    [TOKEN_TYPE.REFRESH]: await this.jwtSign(user, TOKEN_TYPE.REFRESH, refreshExpiration),\n    // ...\n  }\n}\n```\nCompare with the login endpoint at `auth.controller.ts:30-35`, which calls `setCookies(user, res, true)`. Inside `setCookies()` at `auth.service.ts:45`, the 2FA gate fires:\n```typescript\n// auth.service.ts:45\nconst verify2Fa = init2FaVerify && configuration.auth.mfa.totp.enabled && user.twoFaEnabled\n```\nWhen `verify2Fa` is true, `setCookies()` issues only a restricted `ACCESS_2FA` token and requires the user to complete `POST /api/auth/2fa/login/verify` before receiving full session cookies. The token endpoint has no equivalent gate.\n\n## PoC\n\n### Prerequisites\n\n- A Sync-in instance with TOTP 2FA enabled server-wide.\n- A user account with 2FA enrolled (the target).\n- The target's valid login and password, but not the TOTP secret or current TOTP code.\n\n### Steps\n\n1. **Enable 2FA on the target account.** Log in as the target user, navigate to Settings, and enable TOTP two-factor authentication.\n\n2. **Confirm normal login requires 2FA.** Log out. Log back in with the target's credentials. The UI presents a TOTP code prompt before granting access, and the API response contains only `token.access_2fa_expiration` (a restricted partial token):\n```\nPOST /api/auth/login\n{\"login\":\"test\",\"password\":\"...\"}\n\nResponse: {\"user\":{\"twoFaEnabled\":true},\"server\":{\"twoFaEnabled\":true},\"token\":{\"access_2fa_expiration\":1781234379}}\n```\n3. **Bypass 2FA via the token endpoint.** Send the same credentials to `/api/auth/token`:\n```\nPOST /api/auth/token\n{\"login\":\"test\",\"password\":\"...\"}\n\nResponse:\n{\n  \"access\": \"eyJhbGciOiJIUzI1NiIs...\",\n  \"refresh\": \"eyJhbGciOiJIUzI1NiIs...\",\n  \"access_expiration\": 1781235890,\n  \"refresh_expiration\": 1781248490\n}\n```\nUnrestricted Bearer access and refresh JWTs are returned. No TOTP code was required.\n\n4. **Confirm API access.** Use the token on a protected endpoint:\n```\nGET /api/users/me\nAuthorization: Bearer eyJhbGciOiJIUzI1NiIs...\n\nResponse: {\"user\":{\"id\":16,\"login\":\"test\",\"email\":\"test@lab.local\",\"twoFaEnabled\":true,...}}\n```\nThe server returns the user profile. Protected API endpoints that accept Bearer authentication are accessible as the target user. No TOTP code was required at any step.\n\n### Measured observations\n\n- The login endpoint (`/api/auth/login`) correctly returns a restricted 2FA-pending response.\n- The token endpoint (`/api/auth/token`) returns unrestricted Bearer JWTs with the same credentials and no TOTP.\n- The returned Bearer token grants access to protected API endpoints as a fully authenticated user, though cookie-specific flows may differ.\n\n## Impact\n\nAn attacker who already knows valid credentials for a 2FA-enabled account can obtain unrestricted Bearer access and refresh JWTs in a single HTTP request, without knowing the TOTP secret or possessing the authenticator device. 2FA security is bypassed for Bearer-token API authentication.\n\n## Remediation\n\nGate the token endpoint behind the same 2FA policy used by the login route. After `AuthLocalGuard` validates the username and password, require a valid TOTP code when server-side TOTP is enabled and `user.twoFaEnabled` is true, before calling `getTokens()`.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "npm",
      "name" : "@sync-in/server"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "2.4.0"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 2.3.0"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/Sync-in/server/security/advisories/GHSA-92cr-jxw4-5wjg"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-58269"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/Sync-in/server/pull/228"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/Sync-in/server/commit/3ec74e2ea1f538fe1a3ac9487bdf24a19e548361"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/Sync-in/server"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/Sync-in/server/releases/tag/v2.4.0"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-288" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-09-22T14:46:30Z",
    "nvd_published_at" : "2026-09-21T20:17:26Z"
  }
}