/

CVE-2026-47727

Severity:

HIGH RISK

(8.8)

Server-Side Template Injection (CWE-94) in Trilium

CVE-2026-47727

Analyzed

Vulnerability type

Category:

Server-Side Template Injection

CWE:

CWE-94, CWE-1336

Impact:

Remote Code Execution

Severity:

HIGH RISK

(8.8)

CVSS version:

3.1

Catch this CVE while code is being written

Detect vulnerable code directly in pull requests, so CVEs are fixed before merge.

Summary

Trilium's default-on safe import filter does not treat the shareTemplate relation as dangerous, allowing a crafted import archive to add a server-side template to a note.

If the note is later published, an unauthenticated request to its public share can cause attacker-controlled EJS code to execute in the server's Node.js process.

Trilium's default-on safe import filter does not treat the shareTemplate relation as dangerous, allowing a crafted import archive to add a server-side template to a note.

If the note is later published, an unauthenticated request to its public share can cause attacker-controlled EJS code to execute in the server's Node.js process.

Affected context

The vulnerability occurs in Trilium installations that accept imported note archives and use the public sharing feature. It becomes risky when the import filter permits a shareTemplate relation to survive import, and a user subsequently publishes the affected note so the share renderer processes the linked EJS code on the server.

The vulnerability occurs in Trilium installations that accept imported note archives and use the public sharing feature. It becomes risky when the import filter permits a shareTemplate relation to survive import, and a user subsequently publishes the affected note so the share renderer processes the linked EJS code on the server.

Exploit preconditions

  • Attack surface: Trilium note archive import and public share rendering
  • Required access: Ability to provide an attacker-controlled import archive; publication of the imported note is also required
  • Trigger point: Rendering an imported note through its public share endpoint
  • Why exploitation is possible: The safe import filter omits shareTemplate from its dangerous-attribute restrictions, allowing attacker-controlled EJS source to reach the server-side template compiler
  • Attack surface: Trilium note archive import and public share rendering
  • Required access: Ability to provide an attacker-controlled import archive; publication of the imported note is also required
  • Trigger point: Rendering an imported note through its public share endpoint
  • Why exploitation is possible: The safe import filter omits shareTemplate from its dangerous-attribute restrictions, allowing attacker-controlled EJS source to reach the server-side template compiler

Why this happens

The underlying flaw is an incomplete security allowlist or denylist in the import sanitization logic. Because shareTemplate is not classified as a dangerous relation, imported content can establish a link to an EJS code note. The public share renderer then passes the linked note's raw contents to ejs.render, treating attacker-controlled data as executable template code. This maps primarily to CWE-94: Improper Control of Generation of Code, with a related classification of CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine.

The underlying flaw is an incomplete security allowlist or denylist in the import sanitization logic. Because shareTemplate is not classified as a dangerous relation, imported content can establish a link to an EJS code note. The public share renderer then passes the linked note's raw contents to ejs.render, treating attacker-controlled data as executable template code. This maps primarily to CWE-94: Improper Control of Generation of Code, with a related classification of CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine.

Potential impact

  • An attacker may execute arbitrary JavaScript in the Trilium server process
  • The attacker could access server-side environment variables and application secrets
  • The attacker may read, alter, or delete files available to the Node.js process
  • The attacker could make network requests from the server's execution context
  • Compromise may enable data theft, service disruption, or further internal network access
  • An attacker may execute arbitrary JavaScript in the Trilium server process
  • The attacker could access server-side environment variables and application secrets
  • The attacker may read, alter, or delete files available to the Node.js process
  • The attacker could make network requests from the server's execution context
  • Compromise may enable data theft, service disruption, or further internal network access

General mitigation guidance

Mitigation generally focuses on preventing imported content from creating executable server-side templates and separating data rendering from code execution.

Common defensive patterns include:

  • Treating all code-loading and template-related relations, including shareTemplate, as dangerous during import
  • Using strict allowlists for relations and attributes that may be retained from untrusted archives
  • Rendering imported content with context-aware escaping and non-executable template modes
  • Avoiding evaluation of user-controlled strings as templates or program code
  • Applying strong authorization controls before publishing imported notes
  • Running the application with least-privilege filesystem, process, and network permissions
  • Isolating public rendering services from sensitive application and host resources

Mitigation generally focuses on preventing imported content from creating executable server-side templates and separating data rendering from code execution.

Common defensive patterns include:

  • Treating all code-loading and template-related relations, including shareTemplate, as dangerous during import
  • Using strict allowlists for relations and attributes that may be retained from untrusted archives
  • Rendering imported content with context-aware escaping and non-executable template modes
  • Avoiding evaluation of user-controlled strings as templates or program code
  • Applying strong authorization controls before publishing imported notes
  • Running the application with least-privilege filesystem, process, and network permissions
  • Isolating public rendering services from sensitive application and host resources

How teams detect issues like this

Detection can combine code review, static analysis, runtime monitoring, and import-policy enforcement.

  • Search for template compilation APIs such as ejs.render receiving note content, request data, or other untrusted values
  • Review import filters for incomplete dangerous-relation lists and missing allowlist enforcement
  • Flag flows where imported content can influence template names, template bodies, or rendering options
  • Monitor public share requests for unexpected template compilation, process execution, filesystem access, or outbound network activity
  • Add automated tests that import archives containing every code-related relation and verify that executable links are removed or rejected
  • Use automated security review tools to identify server-side template injection and code-generation paths

Detection can combine code review, static analysis, runtime monitoring, and import-policy enforcement.

  • Search for template compilation APIs such as ejs.render receiving note content, request data, or other untrusted values
  • Review import filters for incomplete dangerous-relation lists and missing allowlist enforcement
  • Flag flows where imported content can influence template names, template bodies, or rendering options
  • Monitor public share requests for unexpected template compilation, process execution, filesystem access, or outbound network activity
  • Add automated tests that import archives containing every code-related relation and verify that executable links are removed or rejected
  • Use automated security review tools to identify server-side template injection and code-generation paths

Sources

SourceLink
github.comgithub.com/TriliumNext/Trilium/commit/0db3d4403ab26de13d19a8739f014ee72b716239
github.comgithub.com/TriliumNext/Trilium/security/advisories/GHSA-c26q-6pwv-wf25

Frequently asked

questions

Yes, after the malicious archive has been imported and the affected note has been published, an unauthenticated request to the public share may trigger server-side execution.

The attacker must be able to supply an import archive, which may require an authenticated import capability or another route into the application's import workflow. The final execution request to a public share does not require authentication.

Ensure untrusted imports cannot create template or code-loading relations, and never pass attacker-controlled note content directly to an executable server-side template engine.

Maintain strict relation allowlists, test sanitization logic for every executable content path, require explicit authorization before publishing imported content, and enforce least privilege for the application process.

Yes, after the malicious archive has been imported and the affected note has been published, an unauthenticated request to the public share may trigger server-side execution.

The attacker must be able to supply an import archive, which may require an authenticated import capability or another route into the application's import workflow. The final execution request to a public share does not require authentication.

Ensure untrusted imports cannot create template or code-loading relations, and never pass attacker-controlled note content directly to an executable server-side template engine.

Maintain strict relation allowlists, test sanitization logic for every executable content path, require explicit authorization before publishing imported content, and enforce least privilege for the application process.

Find out what's already
exploitable in your codebase.