VYPR
High severity8.6NVD Advisory· Published May 20, 2026

CVE-2026-39310

CVE-2026-39310

Description

Trilium Notes is a cross-platform, hierarchical note taking application focused on building large personal knowledge bases. In versions 0.102.1 and prior, the Clipper API in Trilium Desktop (v0.101.3) allows full authentication bypass when running in an Electron environment. When Trilium detects an Electron environment, it explicitly disables authentication middleware for the Clipper API, exposing endpoints such as /api/clipper/notes to the network with no password, API token, or CSRF protection. An attacker on a shared network (for example, a corporate LAN or public Wi-Fi) can scan for open high-range ports using a tool like nmap, since Trilium often binds to ports such as 37840. Once a candidate port is found, an unauthenticated request to the Clipper handshake endpoint, which also bypasses authentication, confirms a Trilium instance by returning the application name and protocol version. This facilitates unauthorized data access, phishing, and local system compromise. The issue has been fixed in version 0.102.2.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Trilium Notes Desktop v0.101.3–v0.102.1 disables authentication for the Clipper API in Electron mode, allowing unauthenticated remote attackers on the same network to access and inject notes.

Vulnerability

In Trilium Notes Desktop versions 0.101.3 through 0.102.1, the Clipper API routes (e.g., /api/clipper/notes) are exposed without authentication when the application detects an Electron environment. The check in apps/server/src/routes/routes.ts explicitly sets the middleware to an empty array for Electron builds, bypassing the normal ETAPI token validation [1]. Affected versions include all releases prior to 0.102.2.

Exploitation

An attacker on the same network (e.g., a corporate LAN or public Wi-Fi) can scan for open high-range ports (such as 37840) using tools like nmap. Once an open port is found, an unauthenticated GET /api/clipper/handshake request confirms the instance by returning {"appName":"trilium",...} [1]. The attacker can then craft a POST /api/clipper/notes request to inject arbitrary note content (e.g., a phishing message) directly into the victim's database—no credentials, API token, or CSRF token required.

Impact

A successful attack allows the attacker to write malicious notes into the victim's Trilium knowledge base, which can contain phishing links or other harmful content. This can lead to unauthorized data access (since the attacker can also read notes if they enumerate endpoints), social engineering attacks, and potential local system compromise if the injected content is rendered unsafely (e.g., via SVG or Mermaid diagrams, which were also patched in 0.102.2 [2]).

Mitigation

The vulnerability is fixed in Trilium Notes Desktop version 0.102.2 [2]. All users running 0.102.1 or earlier should upgrade immediately. No workaround is available for the Clipper API authentication bypass. The vendor also enabled Electron fuses and improved application integrity checks in the same release to harden the desktop application against further abuse [2].

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

2
13b1e0afbbd9

fix(desktop): make failing due to wrong version of fuses

https://github.com/triliumnext/triliumElian DoranApr 5, 2026Fixed in 0.102.2via llm-release-walk
2 files changed · +12 23
  • apps/desktop/package.json+1 1 modified
    @@ -40,7 +40,7 @@
         "@electron-forge/maker-zip": "7.11.1",
         "@electron-forge/plugin-auto-unpack-natives": "7.11.1",
         "@electron-forge/plugin-fuses": "7.11.1",
    -    "@electron/fuses": "1.0.0",
    +    "@electron/fuses": "1.8.0",
         "@triliumnext/commons": "workspace:*",
         "@triliumnext/server": "workspace:*",
         "@types/electron-squirrel-startup": "1.0.2",
    
  • pnpm-lock.yaml+11 22 modified
    @@ -447,10 +447,10 @@ importers:
             version: 7.11.1
           '@electron-forge/plugin-fuses':
             specifier: 7.11.1
    -        version: 7.11.1(@electron/fuses@1.0.0)
    +        version: 7.11.1(@electron/fuses@1.8.0)
           '@electron/fuses':
    -        specifier: 1.0.0
    -        version: 1.0.0
    +        specifier: 1.8.0
    +        version: 1.8.0
           '@triliumnext/commons':
             specifier: workspace:*
             version: link:../../packages/commons
    @@ -2394,8 +2394,9 @@ packages:
         engines: {node: '>=10.12.0'}
         hasBin: true
     
    -  '@electron/fuses@1.0.0':
    -    resolution: {integrity: sha512-VjWIlZHEB7a93tXl+6tX2YzN+s1/mS0RM8WX4GZlMOqAzlmRfTMP6pp0MM0LtkzWZB+KQOv+zJt5Dlgdik+DUQ==}
    +  '@electron/fuses@1.8.0':
    +    resolution: {integrity: sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==}
    +    hasBin: true
     
       '@electron/get@2.0.3':
         resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==}
    @@ -16658,8 +16659,6 @@ snapshots:
           '@ckeditor/ckeditor5-widget': 47.4.0
           ckeditor5: 47.4.0
           es-toolkit: 1.39.5
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-icons@47.4.0': {}
     
    @@ -16702,8 +16701,6 @@ snapshots:
           '@ckeditor/ckeditor5-ui': 47.4.0
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-inspector@5.0.0': {}
     
    @@ -16713,8 +16710,6 @@ snapshots:
           '@ckeditor/ckeditor5-ui': 47.4.0
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-line-height@47.4.0':
         dependencies:
    @@ -16739,8 +16734,6 @@ snapshots:
           '@ckeditor/ckeditor5-widget': 47.4.0
           ckeditor5: 47.4.0
           es-toolkit: 1.39.5
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-list-multi-level@47.4.0':
         dependencies:
    @@ -16764,8 +16757,6 @@ snapshots:
           '@ckeditor/ckeditor5-ui': 47.4.0
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-markdown-gfm@47.4.0':
         dependencies:
    @@ -16803,8 +16794,6 @@ snapshots:
           '@ckeditor/ckeditor5-utils': 47.4.0
           '@ckeditor/ckeditor5-widget': 47.4.0
           ckeditor5: 47.4.0
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-mention@47.4.0(patch_hash=5981fb59ba35829e4dff1d39cf771000f8a8fdfa7a34b51d8af9549541f2d62d)':
         dependencies:
    @@ -17618,11 +17607,11 @@ snapshots:
           - bluebird
           - supports-color
     
    -  '@electron-forge/plugin-fuses@7.11.1(@electron/fuses@1.0.0)':
    +  '@electron-forge/plugin-fuses@7.11.1(@electron/fuses@1.8.0)':
         dependencies:
           '@electron-forge/plugin-base': 7.11.1
           '@electron-forge/shared-types': 7.11.1
    -      '@electron/fuses': 1.0.0
    +      '@electron/fuses': 1.8.0
         transitivePeerDependencies:
           - bluebird
           - supports-color
    @@ -17709,9 +17698,11 @@ snapshots:
           glob: 7.2.3
           minimatch: 3.1.2
     
    -  '@electron/fuses@1.0.0':
    +  '@electron/fuses@1.8.0':
         dependencies:
    +      chalk: 4.1.2
           fs-extra: 9.1.0
    +      minimist: 1.2.8
     
       '@electron/get@2.0.3':
         dependencies:
    @@ -23164,8 +23155,6 @@ snapshots:
       ckeditor5-collaboration@47.4.0:
         dependencies:
           '@ckeditor/ckeditor5-collaboration-core': 47.4.0
    -    transitivePeerDependencies:
    -      - supports-color
     
       ckeditor5-premium-features@47.4.0(bufferutil@4.0.9)(ckeditor5@47.4.0)(utf-8-validate@6.0.5):
         dependencies:
    
176de87b6b45

feat(desktop): add Electron fuses

https://github.com/triliumnext/triliumElian DoranApr 5, 2026Fixed in 0.102.2via llm-release-walk
3 files changed · +63 33
  • apps/desktop/electron-forge/forge.config.ts+12 0 modified
    @@ -1,4 +1,5 @@
     import type { ForgeConfig } from "@electron-forge/shared-types";
    +import { FuseV1Options, FuseVersion } from "@electron/fuses";
     import { LOCALES } from "@triliumnext/commons";
     import { existsSync } from "fs";
     import fs from "fs-extra";
    @@ -166,6 +167,17 @@ const config: ForgeConfig = {
             {
                 name: "@electron-forge/plugin-auto-unpack-natives",
                 config: {}
    +        },
    +        {
    +            name: "@electron-forge/plugin-fuses",
    +            config: {
    +                version: FuseVersion.V1,
    +                [FuseV1Options.RunAsNode]: false,
    +                [FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
    +                [FuseV1Options.EnableNodeCliInspectArguments]: false,
    +                [FuseV1Options.EnableCookieEncryption]: true,
    +                [FuseV1Options.OnlyLoadAppFromAsar]: true
    +            }
             }
         ],
         hooks: {
    
  • apps/desktop/package.json+9 7 modified
    @@ -27,15 +27,10 @@
         "electron-debug": "4.1.0",
         "electron-dl": "4.0.0",
         "electron-squirrel-startup": "1.0.1",
    -    "jquery.fancytree": "2.38.5",
    -    "jquery-hotkeys": "0.2.2"
    +    "jquery-hotkeys": "0.2.2",
    +    "jquery.fancytree": "2.38.5"
       },
       "devDependencies": {
    -    "@types/electron-squirrel-startup": "1.0.2",
    -    "@triliumnext/commons": "workspace:*",
    -    "@triliumnext/server": "workspace:*",
    -    "copy-webpack-plugin": "13.0.1",
    -    "electron": "40.6.1",
         "@electron-forge/cli": "7.11.1",
         "@electron-forge/maker-deb": "7.11.1",
         "@electron-forge/maker-dmg": "7.11.1",
    @@ -44,6 +39,13 @@
         "@electron-forge/maker-squirrel": "7.11.1",
         "@electron-forge/maker-zip": "7.11.1",
         "@electron-forge/plugin-auto-unpack-natives": "7.11.1",
    +    "@electron-forge/plugin-fuses": "7.11.1",
    +    "@electron/fuses": "2.1.1",
    +    "@triliumnext/commons": "workspace:*",
    +    "@triliumnext/server": "workspace:*",
    +    "@types/electron-squirrel-startup": "1.0.2",
    +    "copy-webpack-plugin": "13.0.1",
    +    "electron": "40.6.1",
         "prebuild-install": "7.1.3"
       }
     }
    \ No newline at end of file
    
  • pnpm-lock.yaml+42 26 modified
    @@ -445,6 +445,12 @@ importers:
           '@electron-forge/plugin-auto-unpack-natives':
             specifier: 7.11.1
             version: 7.11.1
    +      '@electron-forge/plugin-fuses':
    +        specifier: 7.11.1
    +        version: 7.11.1(@electron/fuses@2.1.1)
    +      '@electron/fuses':
    +        specifier: 2.1.1
    +        version: 2.1.1
           '@triliumnext/commons':
             specifier: workspace:*
             version: link:../../packages/commons
    @@ -2345,6 +2351,12 @@ packages:
         resolution: {integrity: sha512-lKpSOV1GA3FoYiD9k05i6v4KaQVmojnRgCr7d6VL1bFp13QOtXSaAWhFI9mtSY7rGElOacX6Zt7P7rPoB8T9eQ==}
         engines: {node: '>= 16.4.0'}
     
    +  '@electron-forge/plugin-fuses@7.11.1':
    +    resolution: {integrity: sha512-Td517mHf+RjQAayFDM2kKb7NaGdRXrZfPbc7KOHlGbXthp5YTkFu2cCZGWokiqt1y1wsFaAodULhqBIg7vbbbw==}
    +    engines: {node: '>= 16.4.0'}
    +    peerDependencies:
    +      '@electron/fuses': ^1.0.0
    +
       '@electron-forge/publisher-base@7.11.1':
         resolution: {integrity: sha512-rXE9oMFGMtdQrixnumWYH5TTGsp99iPHZb3jI74YWq518ctCh6DlIgWlhf6ok2X0+lhWovcIb45KJucUFAQ13w==}
         engines: {node: '>= 16.4.0'}
    @@ -2382,6 +2394,11 @@ packages:
         engines: {node: '>=10.12.0'}
         hasBin: true
     
    +  '@electron/fuses@2.1.1':
    +    resolution: {integrity: sha512-38ho27/mtUV/LpsZ1LCDJUomKBBSUZDk/qBH4FNNtoN5fmnkmWDcIp5pm1Kv3InqhRjKZKs7Jzx+wWZNMArHrA==}
    +    engines: {node: '>=22.12.0'}
    +    hasBin: true
    +
       '@electron/get@2.0.3':
         resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==}
         engines: {node: '>=12'}
    @@ -16058,6 +16075,8 @@ snapshots:
           '@ckeditor/ckeditor5-core': 47.4.0
           '@ckeditor/ckeditor5-upload': 47.4.0
           ckeditor5: 47.4.0
    +    transitivePeerDependencies:
    +      - supports-color
     
       '@ckeditor/ckeditor5-ai@47.4.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)':
         dependencies:
    @@ -16198,12 +16217,16 @@ snapshots:
           '@ckeditor/ckeditor5-utils': 47.4.0
           '@ckeditor/ckeditor5-widget': 47.4.0
           es-toolkit: 1.39.5
    +    transitivePeerDependencies:
    +      - supports-color
     
       '@ckeditor/ckeditor5-cloud-services@47.4.0':
         dependencies:
           '@ckeditor/ckeditor5-core': 47.4.0
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
    +    transitivePeerDependencies:
    +      - supports-color
     
       '@ckeditor/ckeditor5-code-block@47.4.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)':
         dependencies:
    @@ -16396,6 +16419,8 @@ snapshots:
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
           es-toolkit: 1.39.5
    +    transitivePeerDependencies:
    +      - supports-color
     
       '@ckeditor/ckeditor5-editor-classic@47.4.0':
         dependencies:
    @@ -16405,6 +16430,8 @@ snapshots:
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
           es-toolkit: 1.39.5
    +    transitivePeerDependencies:
    +      - supports-color
     
       '@ckeditor/ckeditor5-editor-decoupled@47.4.0':
         dependencies:
    @@ -16414,6 +16441,8 @@ snapshots:
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
           es-toolkit: 1.39.5
    +    transitivePeerDependencies:
    +      - supports-color
     
       '@ckeditor/ckeditor5-editor-inline@47.4.0':
         dependencies:
    @@ -16447,8 +16476,6 @@ snapshots:
           '@ckeditor/ckeditor5-table': 47.4.0
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-emoji@47.4.0':
         dependencies:
    @@ -16505,8 +16532,6 @@ snapshots:
           '@ckeditor/ckeditor5-ui': 47.4.0
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-export-word@47.4.0':
         dependencies:
    @@ -16531,6 +16556,8 @@ snapshots:
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
           es-toolkit: 1.39.5
    +    transitivePeerDependencies:
    +      - supports-color
     
       '@ckeditor/ckeditor5-font@47.4.0':
         dependencies:
    @@ -16666,8 +16693,6 @@ snapshots:
           '@ckeditor/ckeditor5-ui': 47.4.0
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-indent@47.4.0':
         dependencies:
    @@ -16791,8 +16816,6 @@ snapshots:
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
           es-toolkit: 1.39.5
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-merge-fields@47.4.0':
         dependencies:
    @@ -16805,8 +16828,6 @@ snapshots:
           '@ckeditor/ckeditor5-widget': 47.4.0
           ckeditor5: 47.4.0
           es-toolkit: 1.39.5
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-minimap@47.4.0':
         dependencies:
    @@ -16815,8 +16836,6 @@ snapshots:
           '@ckeditor/ckeditor5-ui': 47.4.0
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-operations-compressor@47.4.0':
         dependencies:
    @@ -16871,8 +16890,6 @@ snapshots:
           '@ckeditor/ckeditor5-utils': 47.4.0
           '@ckeditor/ckeditor5-widget': 47.4.0
           ckeditor5: 47.4.0
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-pagination@47.4.0':
         dependencies:
    @@ -16992,8 +17009,6 @@ snapshots:
           '@ckeditor/ckeditor5-ui': 47.4.0
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-source-editing-enhanced@47.4.0':
         dependencies:
    @@ -17041,8 +17056,6 @@ snapshots:
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
           es-toolkit: 1.39.5
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-table@47.4.0':
         dependencies:
    @@ -17055,8 +17068,6 @@ snapshots:
           '@ckeditor/ckeditor5-widget': 47.4.0
           ckeditor5: 47.4.0
           es-toolkit: 1.39.5
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-template@47.4.0':
         dependencies:
    @@ -17131,8 +17142,6 @@ snapshots:
           '@ckeditor/ckeditor5-icons': 47.4.0
           '@ckeditor/ckeditor5-ui': 47.4.0
           '@ckeditor/ckeditor5-utils': 47.4.0
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-upload@47.4.0':
         dependencies:
    @@ -17169,8 +17178,6 @@ snapshots:
           '@ckeditor/ckeditor5-engine': 47.4.0
           '@ckeditor/ckeditor5-utils': 47.4.0
           es-toolkit: 1.39.5
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@ckeditor/ckeditor5-widget@47.4.0':
         dependencies:
    @@ -17190,8 +17197,6 @@ snapshots:
           '@ckeditor/ckeditor5-utils': 47.4.0
           ckeditor5: 47.4.0
           es-toolkit: 1.39.5
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@codemirror/autocomplete@6.18.6':
         dependencies:
    @@ -17615,6 +17620,15 @@ snapshots:
           - bluebird
           - supports-color
     
    +  '@electron-forge/plugin-fuses@7.11.1(@electron/fuses@2.1.1)':
    +    dependencies:
    +      '@electron-forge/plugin-base': 7.11.1
    +      '@electron-forge/shared-types': 7.11.1
    +      '@electron/fuses': 2.1.1
    +    transitivePeerDependencies:
    +      - bluebird
    +      - supports-color
    +
       '@electron-forge/publisher-base@7.11.1':
         dependencies:
           '@electron-forge/shared-types': 7.11.1
    @@ -17697,6 +17711,8 @@ snapshots:
           glob: 7.2.3
           minimatch: 3.1.2
     
    +  '@electron/fuses@2.1.1': {}
    +
       '@electron/get@2.0.3':
         dependencies:
           debug: 4.4.3(supports-color@8.1.1)
    

Vulnerability mechanics

Root cause

"The Clipper API in Trilium Desktop disables all authentication middleware when running in an Electron environment, exposing endpoints to the network without any credential checks."

Attack vector

An attacker on the same network (e.g., corporate LAN or public Wi-Fi) scans for open high-range ports where Trilium Desktop typically binds (e.g., port 37840). Once a candidate port is found, the attacker sends an unauthenticated request to the Clipper handshake endpoint, which returns the application name and protocol version without requiring any password, API token, or CSRF token. The attacker can then call endpoints such as /api/clipper/notes to read, create, or modify notes, enabling unauthorized data access, phishing, and potential local system compromise [CWE-306].

Affected code

The advisory states that when Trilium detects an Electron environment, it explicitly disables authentication middleware for the Clipper API, exposing endpoints such as /api/clipper/notes. The patch modifies `apps/desktop/electron-forge/forge.config.ts` and `apps/desktop/package.json` to add Electron Fuses configuration; it does not show changes to the Clipper API authentication logic itself.

What the fix does

The patch adds the `@electron-forge/plugin-fuses` and `@electron/fuses` dependencies and configures Electron Fuses in the Forge config [patch_id=877571]. Specifically, it enables `OnlyLoadAppFromAsar`, disables `RunAsNode`, disables `EnableNodeOptionsEnvironmentVariable`, disables `EnableNodeCliInspectArguments`, and enables `EnableCookieEncryption`. These fuses harden the Electron runtime by preventing the app from being run as a plain Node.js process, blocking environment-variable-based injection, disabling CLI inspect arguments, and ensuring cookies are encrypted. While the patch does not directly modify the authentication-bypass logic in the Clipper API, it mitigates the impact by making local system compromise via the Electron environment significantly harder.

Preconditions

  • configTrilium Desktop must be running in an Electron environment (the default for the desktop app).
  • networkThe attacker must be on the same network as the victim (e.g., shared LAN, public Wi-Fi).
  • authNo authentication credentials (password, API token, CSRF token) are required.

Generated on May 20, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

2

News mentions

0

No linked articles in our index yet.