Jun 17, 2026·6 min read·14 visits
A scope misconfiguration in n8n's Evaluation Test Runs Controller allows authenticated, read-only 'viewer' accounts to trigger, cancel, and delete workflow test runs without proper authorization.
An incorrect authorization vulnerability exists in the open-source workflow automation platform n8n within the Evaluation Test Runs Controller. In deployments utilizing Advanced Permissions, an authenticated user assigned a low-privilege project:viewer role can bypass configured permission policies. This allows the unauthorized user to execute, terminate, or delete workflow evaluation test runs by exploiting misconfigured API scope validations that map read-only scopes to mutating endpoints.
The Evaluation Test Runs component in n8n enables developers and operators to run diagnostic testing routines on defined workflow automation pipelines. Within enterprise-grade and cloud deployments of n8n, access control boundaries are enforced utilizing Advanced Permissions, which implement a Role-Based Access Control (RBAC) model. This system defines granular permissions such as project:viewer, project:editor, and project:admin to restrict interactions based on user roles.
The vulnerability is classified under Improper Privilege Management and Broken Authorization. The core attack surface consists of the HTTP endpoints exposed by the Evaluation Test Runs Controller. These endpoints are meant to gate sensitive, state-altering operations behind write-level scopes. Due to a declaration error in the backend controller decorators, mutating endpoints were configured to accept a read-only validation scope.
An authenticated user with read-only access (project:viewer) can exploit this vulnerability to perform unauthorized modifications within their associated projects. The visual flow below demonstrates how the role permission mapping bypasses the authorization guard:
The root cause of this vulnerability lies in the improper mapping of authorization scopes to controller methods within n8n's NestJS framework backend. In n8n, permission checks are processed by route guards, specifically the ProjectMemberGuard. This guard intercepts incoming HTTP requests, decodes the caller's JSON Web Token (JWT), evaluates the user's role on the project, and matches it against the required scopes specified by a @Scopes() decorator on the target route.
To maintain security boundaries, read-only permissions such as viewing workflow schemas or execution histories are mapped to the workflow:read scope. State-changing actions, such as triggering executions, require the elevated workflow:execute scope, while schema alterations or database writes require workflow:update or workflow:delete scopes.
The vulnerability manifests because the developer utilized the @Scopes('workflow:read') decorator on three mutating endpoints within the Evaluation Test Runs Controller. Because the controller declared the read scope rather than execution or update scopes, the authorization engine permitted users possessing the low-privilege project:viewer role to successfully pass security validation.
To understand the implementation flaw, we examine the conceptual configuration of the vulnerable controller against the patched logic. In the vulnerable version, the routes handling creation, cancellation, and deletion of test runs were declared with weak scope requirements:
// VULNERABLE ROUTE DECLARATION
@Controller('evaluation-test-runs')
@UseGuards(ProjectMemberGuard)
export class EvaluationTestRunsController {
@Post()
@Scopes('workflow:read') // VULNERABILITY: Permitted read-only users to trigger executions
async createEvaluationRun(@Body() data: CreateRunDto) {
return this.evaluationService.start(data);
}
@Post(':id/cancel')
@Scopes('workflow:read') // VULNERABILITY: Permitted read-only users to terminate active tasks
async cancelEvaluationRun(@Param('id') id: string) {
return this.evaluationService.cancel(id);
}
@Delete(':id')
@Scopes('workflow:read') // VULNERABILITY: Permitted read-only users to delete database records
async deleteEvaluationRecord(@Param('id') id: string) {
return this.evaluationService.delete(id);
}
}The patch remediates this security flaw by updating the decorator metadata to align with appropriate access scopes, effectively hardening the endpoints against low-privilege access:
// PATCHED ROUTE DECLARATION
@Controller('evaluation-test-runs')
@UseGuards(ProjectMemberGuard)
export class EvaluationTestRunsController {
@Post()
@Scopes('workflow:execute') // FIXED: Now requires execution scope
async createEvaluationRun(@Body() data: CreateRunDto) {
return this.evaluationService.start(data);
}
@Post(':id/cancel')
@Scopes('workflow:execute') // FIXED: Now requires execution scope
async cancelEvaluationRun(@Param('id') id: string) {
return this.evaluationService.cancel(id);
}
@Delete(':id')
@Scopes('workflow:update') // FIXED: Now requires update/delete scope to alter records
async deleteEvaluationRecord(@Param('id') id: string) {
return this.evaluationService.delete(id);
}
}This fix is complete and robust because it leverages n8n's central role mapping framework. Once the correct scopes are defined, any attempt by a project:viewer to make request modifications triggers an immediate authorization rejection prior to controller execution.
To exploit this vulnerability, an attacker must have valid credentials to the target n8n instance and belong to a project with a minimum privilege level of project:viewer. Because the user interface suppresses buttons for execution or deletion based on the UI configuration, the attacker must bypass the frontend and interact directly with the API.
First, the attacker authenticates to obtain a valid JWT. Using read-only access, they query the workflow API to retrieve the target workflowId and associated projectId. Once these identifiers are obtained, they send direct HTTP requests targeting the vulnerable endpoints.
An attacker can trigger an unauthorized evaluation run by sending the following request:
POST /api/v1/evaluation-test-runs HTTP/1.1
Host: n8n.target-domain.com
Authorization: Bearer <Viewer_JWT_Token>
Content-Type: application/json
{
"workflowId": "Wf_12345_Target",
"projectId": "Proj_98765",
"testData": {}
}To disrupt operational activities, the attacker can cancel active, in-flight evaluation tests run by other engineers. They do this by querying active run IDs and dispatching a cancellation payload:
POST /api/v1/evaluation-test-runs/run_abc123_active/cancel HTTP/1.1
Host: n8n.target-domain.com
Authorization: Bearer <Viewer_JWT_Token>Finally, the attacker can cover their tracks or alter historical compliance logs by issuing a delete instruction against the evaluation history database:
DELETE /api/v1/evaluation-test-runs/run_abc123_active HTTP/1.1
Host: n8n.target-domain.com
Authorization: Bearer <Viewer_JWT_Token>The security impact of this vulnerability is measured by the potential disruption to automated testing pipelines and resource consumption. The ability to cancel in-flight evaluation runs allows malicious actors to execute a partial denial of service against continuous integration and testing suites, leading to delays in software deployment pipelines.
Furthermore, the deletion capability degrades system integrity by making historical testing trends and security log audits unreliable. This can pose compliance challenges in highly regulated corporate environments. Unauthorized execution of workflows also presents a platform abuse concern, as viewer accounts can repeatedly trigger tests that consume critical processing infrastructure, system memory, and external service provider API limits.
This vulnerability only affects deployments utilizing the Advanced Permissions structure, which is restricted to Enterprise and Cloud-licensed products. Standard community editions of n8n that do not use multi-tenant projects or role separation are not vulnerable to this vector, as authenticated users typically hold uniform execution and administrative privileges by design.
The primary remediation for this vulnerability is upgrading the n8n application to a secure version. Deployment administrators must apply the corresponding patch based on their operational release branch:
If immediate software patching is not possible, organizations should implement temporary mitigations to lower risk. Administrators should audit project configurations and remove the project:viewer role from users who do not require live dashboard access. Instead, share static workflow exports to maintain operational airgaps.
To identify potential abuse of this vulnerability, security operations teams should inspect API logs for mutating HTTP methods (POST and DELETE) sent to the /api/v1/evaluation-test-runs path. Cross-referencing the executing JWT identity against the active n8n role mapping database will expose anomalies. Any mutating event initiated by an account with strict read-only authorization indicates successful exploitation.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
n8n n8n-io | < 1.123.55 | 1.123.55 |
n8n n8n-io | >= 2.0.0 < 2.25.7 | 2.25.7 |
n8n n8n-io | >= 2.26.0 < 2.26.2 | 2.26.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-863 (Incorrect Authorization) |
| Attack Vector | Network |
| CVSS v3.1 | 5.4 |
| Exploit Status | Proof of Concept / Technical details understood |
| Required Privilege Level | Low (project:viewer) |
| Impact | Integrity Loss, Denial of Service (Testing Pipelines) |
The software performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly obtain the results of the check or does not associate the results with the correct actor, leading to a bypass of the intended restrictions.
CVE-2026-58263 is a high-severity Mutation Cross-Site Scripting (mXSS) vulnerability affecting Jodit Editor prior to version 4.12.28. The flaw exists in Jodit's built-in clean-html sanitizer plugin, which fails to securely parse and sanitize nested elements containing foreign namespaces like MathML and SVG. Attackers can bypass sanitization by smuggling malicious payload elements inside rawtext container tags like style inside a MathML node, leading to DOM mutation and unauthenticated arbitrary script execution in the context of the user's browser session.
Jodit Editor versions prior to 4.13.6 are vulnerable to client-side Cross-Site Scripting (XSS). The clean-html plugin's sanitization routine performs case-sensitive lookups against uppercase-only element blacklists. When processing XML-based foreign namespaces such as SVG or MathML, DOM engines preserve the lowercase format of tags. Because Jodit's denyTags check fails to normalize tag casing, malicious script blocks nested inside foreign namespace elements completely bypass validation and serialize directly into the editor output.
A critical code injection vulnerability exists in Savon, a widely used SOAP client library for Ruby, prior to version 2.17.2. The vulnerability resides within the Savon::Model.all_operations module, where operation names fetched from a target Web Services Description Language (WSDL) document are dynamically evaluated via module_eval without sanitization. An attacker capable of manipulating the target WSDL document (e.g., through Man-in-the-Middle attacks, DNS hijacking, or Server-Side Request Forgery) can execute arbitrary Ruby code in the context of the parent application process.
An integer conversion overflow vulnerability exists in the XCF decoder of ImageMagick before version 6.9.13-51 and 7.1.2-26. The issue arises from mixed-type arithmetic that promotes calculation results to floating-point representations, causing an undefined cast back to integer. Under optimizing compilers, this undefined behavior results in bounds checks being bypassed, allowing out-of-bounds heap reads.
An authenticated file upload validation bypass vulnerability exists in the REDAXO CMS Mediapool addon in versions 5.18.2 through 5.21.0. Under permissive web server configurations, this allows authenticated users with media upload privileges to achieve remote code execution via multi-segment extension file uploads.
A critical SQL injection vulnerability exists in the @nocobase/plugin-notification-in-app-message plugin of NocoBase prior to version 2.0.61. The flaw is caused by direct string interpolation of user-controlled input into a Sequelize.literal() query, allowing authenticated users to execute stacked PostgreSQL queries and achieve remote code execution on the underlying database server.