CWE-915
AllowedImproperly Controlled Modification of Dynamically-Determined Object Attributes
Abstraction: Base · Status: Incomplete
The product receives input from an upstream component that specifies multiple attributes, properties, or fields that are to be initialized or updated in an object, but it does not properly control which attributes can be modified.
276 vulnerabilities reference this CWE, most recent first.
GHSA-78PR-C5X5-JGGC
Vulnerability from github – Published: 2026-05-14 16:19 – Updated: 2026-06-12 19:31Summary
Type: Mass assignment via Object.assign(entity, body) -> client-controlled workspaceId (and on create, id) overwritten on the Assistant entity -> cross-workspace data takeover and IDOR.
File: packages/server/src/services/assistants/index.ts
Root cause: The Assistant controller/service constructs a new Assistant() and copies the request body into it via Object.assign(...) without an explicit field allowlist. The request body therefore can include workspaceId, id, createdDate, updatedDate. The server only rebinds some of these after the assign (e.g. on create, it overwrites workspaceId but not id; on update, it overwrites id but not workspaceId). The remaining client-controlled values land directly on the persisted row, breaking workspace isolation. Same root pattern as the assistant entity's sibling controllers and as DocumentStore before it was patched in commit 840d2ae.
Affected Code
File: packages/server/src/services/assistants/index.ts
// create (line 303) and update (line 381)
Object.assign(newAssistant, requestBody) // <-- BUG: requestBody.id, requestBody.workspaceId accepted
Why it's wrong: Object.assign(target, source) copies every own enumerable property of source onto target. The TypeORM/SQL persistence layer below it does not strip ownership-bearing columns, so workspaceId set in the request body lands as the new workspaceId of the persisted row. The DocumentStore patch (commit 840d2ae) demonstrated the intended fix shape (explicit field-by-field allowlist) but it has not been applied to this entity.
Exploit Chain
- Attacker is an authenticated member of workspace A. They have a session cookie / JWT for the Flowise web UI. State at this point: attacker can read and write entities scoped to workspace A.
- Attacker creates a assistant in workspace A via the documented API (or reuses an existing one they own). They note its entity
id. - Attacker issues a
PUT /api/v1/assistants/<id>(or equivalent endpoint) with a JSON body that includes"workspaceId": "<workspace-B-id>"(an arbitrary other workspace's UUID). State at this point: the request reaches the controller as a workspace-A authenticated request. - The controller calls
Object.assign(updateEntity, body). The body'sworkspaceIdoverwrites the entity'sworkspaceIdfield. The persistence layer commits the row. - Final state: the assistant row is now owned by workspace B. Workspace B members can see it, modify it, and use it. Workspace A loses access (it no longer satisfies their workspace filter). The original creator's workspace audit shows nothing because the operation looked like a normal update.
Security Impact
Severity: High. Cross-workspace boundary violation by any authenticated workspace member.
Attacker capability: Any authenticated user with permission to update a assistant can move it to any workspace whose UUID they can guess or enumerate (workspace UUIDs are exposed in many API responses, so enumeration is trivial). Assistants encapsulate LLM configuration, instructions, attached tools, and credentials. Cross-workspace movement via workspaceId overwrite exposes the assistant (including its system prompt and tool list) to the destination workspace.
Preconditions: Authenticated session with edit permission for the source assistant. No second factor required. Workspace UUIDs are exposed via the /api/v1/workspaces listing or via any cross-referenced object's workspaceId field, so target enumeration is trivial.
Differential: PoC-verified by source inspection of the original GHSA-q4pr-4r26-c69r. Patched build (with the suggested fix below) refuses the workspaceId field; vulnerable build accepts it and persists it.
Suggested Fix
Already fixed in PR https://github.com/FlowiseAI/Flowise/pull/6128 (allowlist pattern applied).
// Allowlist pattern (matches commit 840d2ae for DocumentStore):
const updatedAssistant = new Assistant()
if (body.<allowed_field_1> !== undefined) updatedAssistant.<allowed_field_1> = body.<allowed_field_1>
if (body.<allowed_field_2> !== undefined) updatedAssistant.<allowed_field_2> = body.<allowed_field_2>
// ...whitelist only the documented fields. Never copy id, workspaceId, createdDate, updatedDate from the client.
Regression tests should assert that a request body containing workspaceId, id, createdDate, or updatedDate is rejected (or at minimum: does not change those columns on the persisted row) for both create and update paths.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.1.1"
},
"package": {
"ecosystem": "npm",
"name": "flowise"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.1.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-46475"
],
"database_specific": {
"cwe_ids": [
"CWE-915"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-14T16:19:28Z",
"nvd_published_at": "2026-06-08T16:16:41Z",
"severity": "HIGH"
},
"details": "## Summary\n\n**Type:** Mass assignment via `Object.assign(entity, body)` -\u003e client-controlled `workspaceId` (and on create, `id`) overwritten on the Assistant entity -\u003e cross-workspace data takeover and IDOR.\n**File:** `packages/server/src/services/assistants/index.ts`\n**Root cause:** The Assistant controller/service constructs a `new Assistant()` and copies the request body into it via `Object.assign(...)` without an explicit field allowlist. The request body therefore can include `workspaceId`, `id`, `createdDate`, `updatedDate`. The server only rebinds *some* of these after the assign (e.g. on create, it overwrites `workspaceId` but not `id`; on update, it overwrites `id` but not `workspaceId`). The remaining client-controlled values land directly on the persisted row, breaking workspace isolation. Same root pattern as the assistant entity\u0027s sibling controllers and as `DocumentStore` before it was patched in commit 840d2ae.\n\n## Affected Code\n\n**File:** `packages/server/src/services/assistants/index.ts`\n\n```ts\n// create (line 303) and update (line 381)\nObject.assign(newAssistant, requestBody) // \u003c-- BUG: requestBody.id, requestBody.workspaceId accepted\n```\n\n**Why it\u0027s wrong:** `Object.assign(target, source)` copies every own enumerable property of `source` onto `target`. The TypeORM/SQL persistence layer below it does not strip ownership-bearing columns, so `workspaceId` set in the request body lands as the new `workspaceId` of the persisted row. The DocumentStore patch (commit 840d2ae) demonstrated the intended fix shape (explicit field-by-field allowlist) but it has not been applied to this entity.\n\n## Exploit Chain\n\n1. Attacker is an authenticated member of workspace A. They have a session cookie / JWT for the Flowise web UI. State at this point: attacker can read and write entities scoped to workspace A.\n2. Attacker creates a assistant in workspace A via the documented API (or reuses an existing one they own). They note its entity `id`.\n3. Attacker issues a `PUT /api/v1/assistants/\u003cid\u003e` (or equivalent endpoint) with a JSON body that includes `\"workspaceId\": \"\u003cworkspace-B-id\u003e\"` (an arbitrary other workspace\u0027s UUID). State at this point: the request reaches the controller as a workspace-A authenticated request.\n4. The controller calls `Object.assign(updateEntity, body)`. The body\u0027s `workspaceId` overwrites the entity\u0027s `workspaceId` field. The persistence layer commits the row.\n5. Final state: the assistant row is now owned by workspace B. Workspace B members can see it, modify it, and use it. Workspace A loses access (it no longer satisfies their workspace filter). The original creator\u0027s workspace audit shows nothing because the operation looked like a normal update.\n\n## Security Impact\n\n**Severity:** High. Cross-workspace boundary violation by any authenticated workspace member.\n**Attacker capability:** Any authenticated user with permission to update a assistant can move it to any workspace whose UUID they can guess or enumerate (workspace UUIDs are exposed in many API responses, so enumeration is trivial). Assistants encapsulate LLM configuration, instructions, attached tools, and credentials. Cross-workspace movement via `workspaceId` overwrite exposes the assistant (including its system prompt and tool list) to the destination workspace.\n**Preconditions:** Authenticated session with edit permission for the source assistant. No second factor required. Workspace UUIDs are exposed via the `/api/v1/workspaces` listing or via any cross-referenced object\u0027s `workspaceId` field, so target enumeration is trivial.\n**Differential:** PoC-verified by source inspection of the original GHSA-q4pr-4r26-c69r. Patched build (with the suggested fix below) refuses the `workspaceId` field; vulnerable build accepts it and persists it.\n\n## Suggested Fix\n\nAlready fixed in PR https://github.com/FlowiseAI/Flowise/pull/6128 (allowlist pattern applied).\n\n```ts\n// Allowlist pattern (matches commit 840d2ae for DocumentStore):\nconst updatedAssistant = new Assistant()\nif (body.\u003callowed_field_1\u003e !== undefined) updatedAssistant.\u003callowed_field_1\u003e = body.\u003callowed_field_1\u003e\nif (body.\u003callowed_field_2\u003e !== undefined) updatedAssistant.\u003callowed_field_2\u003e = body.\u003callowed_field_2\u003e\n// ...whitelist only the documented fields. Never copy id, workspaceId, createdDate, updatedDate from the client.\n```\n\nRegression tests should assert that a request body containing `workspaceId`, `id`, `createdDate`, or `updatedDate` is rejected (or at minimum: does not change those columns on the persisted row) for both create and update paths.",
"id": "GHSA-78pr-c5x5-jggc",
"modified": "2026-06-12T19:31:03Z",
"published": "2026-05-14T16:19:28Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-78pr-c5x5-jggc"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-46475"
},
{
"type": "WEB",
"url": "https://github.com/FlowiseAI/Flowise/pull/6128"
},
{
"type": "WEB",
"url": "https://github.com/FlowiseAI/Flowise/commit/1cf247eab35c7c3d4db381d23e4dca682fba527b"
},
{
"type": "PACKAGE",
"url": "https://github.com/FlowiseAI/Flowise"
},
{
"type": "WEB",
"url": "https://github.com/FlowiseAI/Flowise/releases/tag/flowise%403.1.2"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "FlowiseAI: Assistant create+update mass-assignment allows cross-workspace assistant takeover"
}
GHSA-7CJH-FC62-8RRG
Vulnerability from github – Published: 2026-07-11 00:31 – Updated: 2026-07-13 18:30Improperly Controlled Modification of Dynamically-Determined Object Attributes vulnerability in Drupal Tealium iQ Tag Management allows Object Injection. This issue affects Tealium iQ Tag Management versions: from 0.0.0 to 2.4.0.
{
"affected": [],
"aliases": [
"CVE-2026-13244"
],
"database_specific": {
"cwe_ids": [
"CWE-915"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-07-10T22:16:40Z",
"severity": "HIGH"
},
"details": "Improperly Controlled Modification of Dynamically-Determined Object Attributes vulnerability in Drupal Tealium iQ Tag Management allows Object Injection. This issue affects Tealium iQ Tag Management versions: from 0.0.0 to 2.4.0.",
"id": "GHSA-7cjh-fc62-8rrg",
"modified": "2026-07-13T18:30:34Z",
"published": "2026-07-11T00:31:47Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-13244"
},
{
"type": "WEB",
"url": "https://www.drupal.org/sa-contrib-2026-064"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-7H4C-W76P-J34C
Vulnerability from github – Published: 2026-07-11 00:31 – Updated: 2026-07-13 21:31Improperly Controlled Modification of Dynamically-Determined Object Attributes vulnerability in Drupal ECA: Event - Condition - Action allows Object Injection. This issue affects ECA: Event - Condition - Action versions: from 0.0.0 to 2.1.20, from 3.0.0 to 3.0.12, from 3.1.0 to 3.1.4.
{
"affected": [],
"aliases": [
"CVE-2026-15083"
],
"database_specific": {
"cwe_ids": [
"CWE-915"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-07-10T22:16:41Z",
"severity": "MODERATE"
},
"details": "Improperly Controlled Modification of Dynamically-Determined Object Attributes vulnerability in Drupal ECA: Event - Condition - Action allows Object Injection. This issue affects ECA: Event - Condition - Action versions: from 0.0.0 to 2.1.20, from 3.0.0 to 3.0.12, from 3.1.0 to 3.1.4.",
"id": "GHSA-7h4c-w76p-j34c",
"modified": "2026-07-13T21:31:18Z",
"published": "2026-07-11T00:31:48Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-15083"
},
{
"type": "WEB",
"url": "https://www.drupal.org/sa-contrib-2026-074"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-7J65-65CR-6644
Vulnerability from github – Published: 2026-05-14 16:19 – Updated: 2026-07-07 13:34Summary
Type: Mass assignment via Object.assign(entity, body) -> client-controlled workspaceId (and on create, id) overwritten on the DatasetRow entity -> cross-workspace data takeover and IDOR.
File: packages/server/src/services/dataset/index.ts
Root cause: The DatasetRow controller/service constructs a new DatasetRow() and copies the request body into it via Object.assign(...) without an explicit field allowlist. The request body therefore can include workspaceId, id, createdDate, updatedDate. The server only rebinds some of these after the assign (e.g. on create, it overwrites workspaceId but not id; on update, it overwrites id but not workspaceId). The remaining client-controlled values land directly on the persisted row, breaking workspace isolation. Same root pattern as the datasetrow entity's sibling controllers and as DocumentStore before it was patched in commit 840d2ae.
Affected Code
File: packages/server/src/services/dataset/index.ts
// create (line 274) and update (line 315)
Object.assign(newRow, rowBody) // <-- BUG: rowBody.id, rowBody.datasetId accepted
Why it's wrong: Object.assign(target, source) copies every own enumerable property of source onto target. The TypeORM/SQL persistence layer below it does not strip ownership-bearing columns, so workspaceId set in the request body lands as the new workspaceId of the persisted row. The DocumentStore patch (commit 840d2ae) demonstrated the intended fix shape (explicit field-by-field allowlist) but it has not been applied to this entity.
Exploit Chain
- Attacker is an authenticated member of workspace A. They have a session cookie / JWT for the Flowise web UI. State at this point: attacker can read and write entities scoped to workspace A.
- Attacker creates a datasetrow in workspace A via the documented API (or reuses an existing one they own). They note its entity
id. - Attacker issues a
PUT /api/v1/datasetrows/<id>(or equivalent endpoint) with a JSON body that includes"workspaceId": "<workspace-B-id>"(an arbitrary other workspace's UUID). State at this point: the request reaches the controller as a workspace-A authenticated request. - The controller calls
Object.assign(updateEntity, body). The body'sworkspaceIdoverwrites the entity'sworkspaceIdfield. The persistence layer commits the row. - Final state: the datasetrow row is now owned by workspace B. Workspace B members can see it, modify it, and use it. Workspace A loses access (it no longer satisfies their workspace filter). The original creator's workspace audit shows nothing because the operation looked like a normal update.
Security Impact
Severity: High. Cross-workspace boundary violation by any authenticated workspace member.
Attacker capability: Any authenticated user with permission to update a datasetrow can move it to any workspace whose UUID they can guess or enumerate (workspace UUIDs are exposed in many API responses, so enumeration is trivial). DatasetRows hold individual training/evaluation records. The mass assignment lets a member rebind a row to a Dataset in another workspace via datasetId, exposing the row content to the destination workspace.
Preconditions: Authenticated session with edit permission for the source datasetrow. No second factor required. Workspace UUIDs are exposed via the /api/v1/workspaces listing or via any cross-referenced object's workspaceId field, so target enumeration is trivial.
Differential: PoC-verified by source inspection of the original GHSA-q4pr-4r26-c69r. Patched build (with the suggested fix below) refuses the workspaceId field; vulnerable build accepts it and persists it.
Suggested Fix
Already fixed in PR https://github.com/FlowiseAI/Flowise/pull/6051 (allowlist pattern applied).
// Allowlist pattern (matches commit 840d2ae for DocumentStore):
const updatedDatasetRow = new DatasetRow()
if (body.<allowed_field_1> !== undefined) updatedDatasetRow.<allowed_field_1> = body.<allowed_field_1>
if (body.<allowed_field_2> !== undefined) updatedDatasetRow.<allowed_field_2> = body.<allowed_field_2>
// ...whitelist only the documented fields. Never copy id, workspaceId, createdDate, updatedDate from the client.
Regression tests should assert that a request body containing workspaceId, id, createdDate, or updatedDate is rejected (or at minimum: does not change those columns on the persisted row) for both create and update paths.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.1.1"
},
"package": {
"ecosystem": "npm",
"name": "flowise"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.1.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-46478"
],
"database_specific": {
"cwe_ids": [
"CWE-915"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-14T16:19:44Z",
"nvd_published_at": "2026-06-08T16:16:42Z",
"severity": "HIGH"
},
"details": "## Summary\n\n**Type:** Mass assignment via `Object.assign(entity, body)` -\u003e client-controlled `workspaceId` (and on create, `id`) overwritten on the DatasetRow entity -\u003e cross-workspace data takeover and IDOR.\n**File:** `packages/server/src/services/dataset/index.ts`\n**Root cause:** The DatasetRow controller/service constructs a `new DatasetRow()` and copies the request body into it via `Object.assign(...)` without an explicit field allowlist. The request body therefore can include `workspaceId`, `id`, `createdDate`, `updatedDate`. The server only rebinds *some* of these after the assign (e.g. on create, it overwrites `workspaceId` but not `id`; on update, it overwrites `id` but not `workspaceId`). The remaining client-controlled values land directly on the persisted row, breaking workspace isolation. Same root pattern as the datasetrow entity\u0027s sibling controllers and as `DocumentStore` before it was patched in commit 840d2ae.\n\n## Affected Code\n\n**File:** `packages/server/src/services/dataset/index.ts`\n\n```ts\n// create (line 274) and update (line 315)\nObject.assign(newRow, rowBody) // \u003c-- BUG: rowBody.id, rowBody.datasetId accepted\n```\n\n**Why it\u0027s wrong:** `Object.assign(target, source)` copies every own enumerable property of `source` onto `target`. The TypeORM/SQL persistence layer below it does not strip ownership-bearing columns, so `workspaceId` set in the request body lands as the new `workspaceId` of the persisted row. The DocumentStore patch (commit 840d2ae) demonstrated the intended fix shape (explicit field-by-field allowlist) but it has not been applied to this entity.\n\n## Exploit Chain\n\n1. Attacker is an authenticated member of workspace A. They have a session cookie / JWT for the Flowise web UI. State at this point: attacker can read and write entities scoped to workspace A.\n2. Attacker creates a datasetrow in workspace A via the documented API (or reuses an existing one they own). They note its entity `id`.\n3. Attacker issues a `PUT /api/v1/datasetrows/\u003cid\u003e` (or equivalent endpoint) with a JSON body that includes `\"workspaceId\": \"\u003cworkspace-B-id\u003e\"` (an arbitrary other workspace\u0027s UUID). State at this point: the request reaches the controller as a workspace-A authenticated request.\n4. The controller calls `Object.assign(updateEntity, body)`. The body\u0027s `workspaceId` overwrites the entity\u0027s `workspaceId` field. The persistence layer commits the row.\n5. Final state: the datasetrow row is now owned by workspace B. Workspace B members can see it, modify it, and use it. Workspace A loses access (it no longer satisfies their workspace filter). The original creator\u0027s workspace audit shows nothing because the operation looked like a normal update.\n\n## Security Impact\n\n**Severity:** High. Cross-workspace boundary violation by any authenticated workspace member.\n**Attacker capability:** Any authenticated user with permission to update a datasetrow can move it to any workspace whose UUID they can guess or enumerate (workspace UUIDs are exposed in many API responses, so enumeration is trivial). DatasetRows hold individual training/evaluation records. The mass assignment lets a member rebind a row to a Dataset in another workspace via `datasetId`, exposing the row content to the destination workspace.\n**Preconditions:** Authenticated session with edit permission for the source datasetrow. No second factor required. Workspace UUIDs are exposed via the `/api/v1/workspaces` listing or via any cross-referenced object\u0027s `workspaceId` field, so target enumeration is trivial.\n**Differential:** PoC-verified by source inspection of the original GHSA-q4pr-4r26-c69r. Patched build (with the suggested fix below) refuses the `workspaceId` field; vulnerable build accepts it and persists it.\n\n## Suggested Fix\n\nAlready fixed in PR https://github.com/FlowiseAI/Flowise/pull/6051 (allowlist pattern applied).\n\n```ts\n// Allowlist pattern (matches commit 840d2ae for DocumentStore):\nconst updatedDatasetRow = new DatasetRow()\nif (body.\u003callowed_field_1\u003e !== undefined) updatedDatasetRow.\u003callowed_field_1\u003e = body.\u003callowed_field_1\u003e\nif (body.\u003callowed_field_2\u003e !== undefined) updatedDatasetRow.\u003callowed_field_2\u003e = body.\u003callowed_field_2\u003e\n// ...whitelist only the documented fields. Never copy id, workspaceId, createdDate, updatedDate from the client.\n```\n\nRegression tests should assert that a request body containing `workspaceId`, `id`, `createdDate`, or `updatedDate` is rejected (or at minimum: does not change those columns on the persisted row) for both create and update paths.",
"id": "GHSA-7j65-65cr-6644",
"modified": "2026-07-07T13:34:17Z",
"published": "2026-05-14T16:19:44Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-7j65-65cr-6644"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-46478"
},
{
"type": "WEB",
"url": "https://github.com/FlowiseAI/Flowise/pull/6051"
},
{
"type": "WEB",
"url": "https://github.com/FlowiseAI/Flowise/commit/49a2259bf2a6b4f3d4b50813cb5161cee0d40040"
},
{
"type": "PACKAGE",
"url": "https://github.com/FlowiseAI/Flowise"
},
{
"type": "WEB",
"url": "https://github.com/FlowiseAI/Flowise/releases/tag/flowise%403.1.2"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "FlowiseAI: DatasetRow create+update mass-assignment allows cross-workspace row takeover"
}
GHSA-7JVP-HJ45-2F2M
Vulnerability from github – Published: 2026-07-06 17:30 – Updated: 2026-07-06 17:30Description
When a host pushes a CLR object into a Scriban TemplateContext via the standard, documented pattern —
var so = new ScriptObject();
so["user"] = currentUser; // direct CLR reference
context.PushGlobal(so);
— TypedObjectAccessor exposes every public-getter property for both reading and writing, and writes land on the live host object and persist after Render() returns. The write path performs no CanWrite and no setter-visibility check, producing two related but distinct weaknesses:
(A) Mass assignment of public setters — CWE-915 (originally F-002). Any { get; set; } property is writable from template code ({{ user.is_admin = true }}, {{ order.total_price = 0 }}). This is "surprising but technically consistent with the setter being public" — and crucially, Scriban offers no way to expose such a property read-only, because MemberFilter is read/write-symmetric.
(B) Access-modifier bypass — CWE-284 (originally F-007). Properties the developer deliberately restricted are also writable, because reflection ignores C# accessibility:
| Declaration | Developer intent | Actual behavior |
|---|---|---|
| { get; set; } | writable | writable (mass assignment — A) |
| { get; private set; } | only the owning class writes | template writes freely |
| { get; internal set; } | only the declaring assembly writes | template writes freely |
| { get; init; } | immutable after construction (C# 9 language guarantee) | template writes freely post-construction |
The init-only post-construction write — the highest false-positive risk — was explicitly confirmed against the shipped 7.2.1 package.
Affected Versions
All releases that ship TypedObjectAccessor (<= 7.2.1). PrepareMembers has used the getter-only filter since the accessor was introduced, and TrySetValue has never checked the setter. The init bypass applies on .NET 5+; private set / internal set apply on every supported runtime. No patched version exists.
Steps to Reproduce
Copy-paste. Run from the engagement root (the folder containing both
scriban/andreports/).
Prereqs:
test -d scriban || { echo "scriban source missing"; exit 1; }
( command -v dotnet >/dev/null && dotnet --list-sdks | grep -q '^10\.' ) \
|| ( "$HOME/.dotnet/dotnet" --list-sdks | grep -q '^10\.' ) \
|| { echo ".NET 10 SDK missing"; exit 1; }
export PATH="$HOME/.dotnet:$PATH"
Run both PoCs (native):
( cd reports/f002/poc && dotnet run -c Release ) # (A) public-setter mass assignment
( cd reports/f007/poc && dotnet run -c Release ) # (B) private/internal/init bypass
Docker fallback (no native SDK required):
docker run --rm -v "$PWD":/work -w /work/reports/f007/poc \
mcr.microsoft.com/dotnet/sdk:10.0 bash -lc "dotnet run -c Release"
Confirm the published package is affected (not just master): swap the ProjectReference in reports/f007/poc/poc.csproj for <PackageReference Include="Scriban" Version="7.2.1" /> and re-run — the four bypasses still succeed.
Each PoC prints [1] original CLR values, [2] template output (reads originals → writes → reads back), and [3] the C#-side read after Render() proving the live host object was permanently altered.
Remediation
Fixes are listed flat. Note that (B) has a clean, clearly-correct code fix; (A) requires a new control because public-setter writes are otherwise by-design.
- Fix 1 — block restricted setters in
TrySetValue(TypedObjectAccessor.csL108–L123). Fixes (B). Before the L120SetValue, require a public, non-initsetter:
A plainvar setM = propertyAccessor.GetSetMethod(nonPublic: false); if (setM is null) return false; // private / internal / protected setters if (setM.ReturnParameter.GetRequiredCustomModifiers() .Any(m => m.FullName == "System.Runtime.CompilerServices.IsExternalInit")) return false; // init-only: setter IS public, so the IsExternalInit check is REQUIREDGetSetMethod(nonPublic:false) != nullcheck is not sufficient forinit— the init setter is public; only theIsExternalInitmodreq distinguishes it. - Fix 2 — give hosts a read/write distinction (addresses (A)). Add a
MemberWriteFilteronTemplateContext(separate fromMemberFilter) and/or a[ScriptMemberReadOnly]attribute, and split_membersinto_readableMembers/_writableMembersinPrepareMembers(L126–L186). Public-settable mass assignment cannot be blocked without one of these, becauseMemberFilteris read/write-symmetric today. - Fix 3 — restore read-only-by-default on
ScriptObject.Import(ScriptObjectExtensions.csL320–L324). Gate the Liquid-compatibility relaxation behind an explicit opt-in instead of removing write protection globally. - Fix 4 — documentation (
site/docs/runtime/safe-runtime.md). State explicitly that templates can write CLR properties via reflection (includingprivate/internal/initsetters), and thatMemberFilterdoes not separate read from write. - Fix 5 — regression tests (
src/Scriban.Tests/). Assertprivate set/internal set/initare non-writable from templates, thatMemberWriteFilter/[ScriptMemberReadOnly]gate writes, and that only publicsetis writable.
References
- Vulnerable write path (no setter check):
scriban/src/Scriban/Runtime/Accessors/TypedObjectAccessor.csL108–L123 (TrySetValue), sink at L120propertyAccessor.SetValue(target, context.ToObject(span, value, propertyAccessor.PropertyType)); - Getter-only member filter:
TypedObjectAccessor.csL126–L186 (PrepareMembers), enumeration at L150, gate at L156; same_membersconsumed byTryGetValue(L66–L83) - Member-assignment dispatch:
scriban/src/Scriban/ScribanAsync.generated.cs:2297(accessor.TrySetValue(...)) and the synchronous evaluator - No read/write separation:
MemberFilterdeclaredTemplateContext.cs:286, appliedTemplateContext.cs:1026;ScriptObject.Importread-only removalScriptObjectExtensions.cs:320–324 - .NET reflection bypasses access modifiers: https://learn.microsoft.com/dotnet/api/system.reflection.propertyinfo.setvalue
initaccessors (C# 9): https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-9.0/init- CWE-915 — https://cwe.mitre.org/data/definitions/915.html
- CWE-284 — https://cwe.mitre.org/data/definitions/284.html
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 7.2.1"
},
"package": {
"ecosystem": "NuGet",
"name": "Scriban"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "7.2.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-284",
"CWE-915"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-06T17:30:17Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "\u003c!-- obsidian --\u003e\u003ch2 data-heading=\"Description\"\u003eDescription\u003c/h2\u003e\n\u003cp\u003eWhen a host pushes a CLR object into a Scriban \u003ccode\u003eTemplateContext\u003c/code\u003e via the standard, documented pattern \u2014\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-csharp\"\u003evar so = new ScriptObject();\nso[\"user\"] = currentUser; // direct CLR reference\ncontext.PushGlobal(so);\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u2014 \u003ccode\u003eTypedObjectAccessor\u003c/code\u003e exposes every public-getter property for \u003cstrong\u003eboth reading and writing\u003c/strong\u003e, and writes land on the live host object and \u003cstrong\u003epersist after \u003ccode\u003eRender()\u003c/code\u003e returns\u003c/strong\u003e. The write path performs no \u003ccode\u003eCanWrite\u003c/code\u003e and no setter-visibility check, producing two related but distinct weaknesses:\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e(A) Mass assignment of public setters \u2014 CWE-915 (originally F-002).\u003c/strong\u003e Any \u003ccode\u003e{ get; set; }\u003c/code\u003e property is writable from template code (\u003ccode\u003e{{ user.is_admin = true }}\u003c/code\u003e, \u003ccode\u003e{{ order.total_price = 0 }}\u003c/code\u003e). This is \"surprising but technically consistent with the setter being public\" \u2014 and crucially, Scriban offers \u003cstrong\u003eno way to expose such a property read-only\u003c/strong\u003e, because \u003ccode\u003eMemberFilter\u003c/code\u003e is read/write-symmetric.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e(B) Access-modifier bypass \u2014 CWE-284 (originally F-007).\u003c/strong\u003e Properties the developer \u003cstrong\u003edeliberately\u003c/strong\u003e restricted are also writable, because reflection ignores C# accessibility:\u003c/p\u003e\n\nDeclaration | Developer intent | Actual behavior\n-- | -- | --\n{ get; set; } | writable | writable (mass assignment \u2014 A)\n{ get; private set; } | only the owning class writes | template writes freely\n{ get; internal set; } | only the declaring assembly writes | template writes freely\n{ get; init; } | immutable after construction (C# 9 language guarantee) | template writes freely post-construction\n\n\n\u003cp\u003eThe \u003ccode\u003einit\u003c/code\u003e-only post-construction write \u2014 the highest false-positive risk \u2014 was explicitly confirmed against the shipped 7.2.1 package.\u003c/p\u003e\n\u003ch2 data-heading=\"Affected Versions\"\u003eAffected Versions\u003c/h2\u003e\n\u003cp\u003eAll releases that ship \u003ccode\u003eTypedObjectAccessor\u003c/code\u003e (\u003ccode\u003e\u0026#x3C;= 7.2.1\u003c/code\u003e). \u003ccode\u003ePrepareMembers\u003c/code\u003e has used the getter-only filter since the accessor was introduced, and \u003ccode\u003eTrySetValue\u003c/code\u003e has never checked the setter. The \u003ccode\u003einit\u003c/code\u003e bypass applies on .NET 5+; \u003ccode\u003eprivate set\u003c/code\u003e / \u003ccode\u003einternal set\u003c/code\u003e apply on every supported runtime. No patched version exists.\u003c/p\u003e\n\u003ch2 data-heading=\"Steps to Reproduce\"\u003eSteps to Reproduce\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003eCopy-paste. Run from the engagement root (the folder containing both \u003ccode\u003escriban/\u003c/code\u003e and \u003ccode\u003ereports/\u003c/code\u003e).\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e\u003cstrong\u003ePrereqs:\u003c/strong\u003e\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-bash\"\u003etest -d scriban || { echo \"scriban source missing\"; exit 1; }\n( command -v dotnet \u003e/dev/null \u0026#x26;\u0026#x26; dotnet --list-sdks | grep -q \u0027^10\\.\u0027 ) \\\n || ( \"$HOME/.dotnet/dotnet\" --list-sdks | grep -q \u0027^10\\.\u0027 ) \\\n || { echo \".NET 10 SDK missing\"; exit 1; }\nexport PATH=\"$HOME/.dotnet:$PATH\"\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cstrong\u003eRun both PoCs (native):\u003c/strong\u003e\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-bash\"\u003e( cd reports/f002/poc \u0026#x26;\u0026#x26; dotnet run -c Release ) # (A) public-setter mass assignment\n( cd reports/f007/poc \u0026#x26;\u0026#x26; dotnet run -c Release ) # (B) private/internal/init bypass\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cstrong\u003eDocker fallback (no native SDK required):\u003c/strong\u003e\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-bash\"\u003edocker run --rm -v \"$PWD\":/work -w /work/reports/f007/poc \\\n mcr.microsoft.com/dotnet/sdk:10.0 bash -lc \"dotnet run -c Release\"\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cstrong\u003eConfirm the published package is affected (not just master):\u003c/strong\u003e swap the \u003ccode\u003eProjectReference\u003c/code\u003e in \u003ccode\u003ereports/f007/poc/poc.csproj\u003c/code\u003e for \u003ccode\u003e\u0026#x3C;PackageReference Include=\"Scriban\" Version=\"7.2.1\" /\u003e\u003c/code\u003e and re-run \u2014 the four bypasses still succeed.\u003c/p\u003e\n\u003cp\u003eEach PoC prints \u003ccode\u003e[1]\u003c/code\u003e original CLR values, \u003ccode\u003e[2]\u003c/code\u003e template output (reads originals \u2192 writes \u2192 reads back), and \u003ccode\u003e[3]\u003c/code\u003e the \u003cstrong\u003eC#-side\u003c/strong\u003e read after \u003ccode\u003eRender()\u003c/code\u003e proving the live host object was permanently altered.\u003c/p\u003e\n\u003ch2 data-heading=\"Remediation\"\u003eRemediation\u003c/h2\u003e\n\u003cp\u003eFixes are listed flat. Note that (B) has a clean, clearly-correct code fix; (A) requires a \u003cem\u003enew control\u003c/em\u003e because public-setter writes are otherwise by-design.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eFix 1 \u2014 block restricted setters in \u003ccode\u003eTrySetValue\u003c/code\u003e (\u003ccode\u003eTypedObjectAccessor.cs\u003c/code\u003e L108\u2013L123). Fixes (B).\u003c/strong\u003e Before the L120 \u003ccode\u003eSetValue\u003c/code\u003e, require a public, non-\u003ccode\u003einit\u003c/code\u003e setter:\n\u003cpre\u003e\u003ccode class=\"language-csharp\"\u003evar setM = propertyAccessor.GetSetMethod(nonPublic: false);\nif (setM is null) return false; // private / internal / protected setters\nif (setM.ReturnParameter.GetRequiredCustomModifiers()\n .Any(m =\u003e m.FullName == \"System.Runtime.CompilerServices.IsExternalInit\"))\n return false; // init-only: setter IS public, so the IsExternalInit check is REQUIRED\n\u003c/code\u003e\u003c/pre\u003e\nA plain \u003ccode\u003eGetSetMethod(nonPublic:false) != null\u003c/code\u003e check is \u003cstrong\u003enot\u003c/strong\u003e sufficient for \u003ccode\u003einit\u003c/code\u003e \u2014 the init setter is public; only the \u003ccode\u003eIsExternalInit\u003c/code\u003e modreq distinguishes it.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFix 2 \u2014 give hosts a read/write distinction (addresses (A)).\u003c/strong\u003e Add a \u003ccode\u003eMemberWriteFilter\u003c/code\u003e on \u003ccode\u003eTemplateContext\u003c/code\u003e (separate from \u003ccode\u003eMemberFilter\u003c/code\u003e) and/or a \u003ccode\u003e[ScriptMemberReadOnly]\u003c/code\u003e attribute, and split \u003ccode\u003e_members\u003c/code\u003e into \u003ccode\u003e_readableMembers\u003c/code\u003e / \u003ccode\u003e_writableMembers\u003c/code\u003e in \u003ccode\u003ePrepareMembers\u003c/code\u003e (L126\u2013L186). Public-settable mass assignment cannot be blocked without one of these, because \u003ccode\u003eMemberFilter\u003c/code\u003e is read/write-symmetric today.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFix 3 \u2014 restore read-only-by-default on \u003ccode\u003eScriptObject.Import\u003c/code\u003e (\u003ccode\u003eScriptObjectExtensions.cs\u003c/code\u003e L320\u2013L324).\u003c/strong\u003e Gate the Liquid-compatibility relaxation behind an explicit opt-in instead of removing write protection globally.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFix 4 \u2014 documentation (\u003ccode\u003esite/docs/runtime/safe-runtime.md\u003c/code\u003e).\u003c/strong\u003e State explicitly that templates can write CLR properties via reflection (including \u003ccode\u003eprivate\u003c/code\u003e/\u003ccode\u003einternal\u003c/code\u003e/\u003ccode\u003einit\u003c/code\u003e setters), and that \u003ccode\u003eMemberFilter\u003c/code\u003e does not separate read from write.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFix 5 \u2014 regression tests (\u003ccode\u003esrc/Scriban.Tests/\u003c/code\u003e).\u003c/strong\u003e Assert \u003ccode\u003eprivate set\u003c/code\u003e / \u003ccode\u003einternal set\u003c/code\u003e / \u003ccode\u003einit\u003c/code\u003e are non-writable from templates, that \u003ccode\u003eMemberWriteFilter\u003c/code\u003e / \u003ccode\u003e[ScriptMemberReadOnly]\u003c/code\u003e gate writes, and that only public \u003ccode\u003eset\u003c/code\u003e is writable.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 data-heading=\"References\"\u003eReferences\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eVulnerable write path (no setter check): \u003ccode\u003escriban/src/Scriban/Runtime/Accessors/TypedObjectAccessor.cs\u003c/code\u003e L108\u2013L123 (\u003ccode\u003eTrySetValue\u003c/code\u003e), sink at L120 \u003ccode\u003epropertyAccessor.SetValue(target, context.ToObject(span, value, propertyAccessor.PropertyType));\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eGetter-only member filter: \u003ccode\u003eTypedObjectAccessor.cs\u003c/code\u003e L126\u2013L186 (\u003ccode\u003ePrepareMembers\u003c/code\u003e), enumeration at L150, gate at L156; same \u003ccode\u003e_members\u003c/code\u003e consumed by \u003ccode\u003eTryGetValue\u003c/code\u003e (L66\u2013L83)\u003c/li\u003e\n\u003cli\u003eMember-assignment dispatch: \u003ccode\u003escriban/src/Scriban/ScribanAsync.generated.cs:2297\u003c/code\u003e (\u003ccode\u003eaccessor.TrySetValue(...)\u003c/code\u003e) and the synchronous evaluator\u003c/li\u003e\n\u003cli\u003eNo read/write separation: \u003ccode\u003eMemberFilter\u003c/code\u003e declared \u003ccode\u003eTemplateContext.cs:286\u003c/code\u003e, applied \u003ccode\u003eTemplateContext.cs:1026\u003c/code\u003e; \u003ccode\u003eScriptObject.Import\u003c/code\u003e read-only removal \u003ccode\u003eScriptObjectExtensions.cs:320\u2013324\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e.NET reflection bypasses access modifiers: \u003ca href=\"https://learn.microsoft.com/dotnet/api/system.reflection.propertyinfo.setvalue\" class=\"external-link\" target=\"_blank\" rel=\"noopener nofollow\"\u003ehttps://learn.microsoft.com/dotnet/api/system.reflection.propertyinfo.setvalue\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003einit\u003c/code\u003e accessors (C# 9): \u003ca href=\"https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-9.0/init\" class=\"external-link\" target=\"_blank\" rel=\"noopener nofollow\"\u003ehttps://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-9.0/init\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eCWE-915 \u2014 \u003ca href=\"https://cwe.mitre.org/data/definitions/915.html\" class=\"external-link\" target=\"_blank\" rel=\"noopener nofollow\"\u003ehttps://cwe.mitre.org/data/definitions/915.html\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eCWE-284 \u2014 \u003ca href=\"https://cwe.mitre.org/data/definitions/284.html\" class=\"external-link\" target=\"_blank\" rel=\"noopener nofollow\"\u003ehttps://cwe.mitre.org/data/definitions/284.html\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e",
"id": "GHSA-7jvp-hj45-2f2m",
"modified": "2026-07-06T17:30:17Z",
"published": "2026-07-06T17:30:17Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/scriban/scriban/security/advisories/GHSA-7jvp-hj45-2f2m"
},
{
"type": "PACKAGE",
"url": "https://github.com/scriban/scriban"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:P",
"type": "CVSS_V4"
}
],
"summary": "Scriban: Template Writes to Arbitrary CLR Properties via `TypedObjectAccessor` (Mass Assignment + `private` / `init` / `internal` Setter Bypass)"
}
GHSA-7QM6-9V49-38M9
Vulnerability from github – Published: 2021-12-10 18:55 – Updated: 2023-09-11 18:40All versions of package record-like-deep-assign are vulnerable to Prototype Pollution via the main functionality.
PoC
const deepAssign = require('record-like-deep-assign');
let obj = {};
console.log("Before being polluted: " + obj.polluted);
EVIL_JSON = JSON.parse('{"__proto__":{"polluted":true}}');
deepAssign({}, EVIL_JSON);
console.log("After being polluted: " + obj.polluted);
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "record-like-deep-assign"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "1.0.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-23402"
],
"database_specific": {
"cwe_ids": [
"CWE-1321",
"CWE-915"
],
"github_reviewed": true,
"github_reviewed_at": "2021-07-06T14:32:33Z",
"nvd_published_at": "2021-07-02T16:15:00Z",
"severity": "HIGH"
},
"details": "All versions of package record-like-deep-assign are vulnerable to Prototype Pollution via the main functionality.\n\n### PoC\n```js\nconst deepAssign = require(\u0027record-like-deep-assign\u0027);\nlet obj = {};\nconsole.log(\"Before being polluted: \" + obj.polluted);\nEVIL_JSON = JSON.parse(\u0027{\"__proto__\":{\"polluted\":true}}\u0027);\ndeepAssign({}, EVIL_JSON);\nconsole.log(\"After being polluted: \" + obj.polluted);\n```",
"id": "GHSA-7qm6-9v49-38m9",
"modified": "2023-09-11T18:40:49Z",
"published": "2021-12-10T18:55:39Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-23402"
},
{
"type": "PACKAGE",
"url": "https://github.com/kripod/record-like-deep-assign"
},
{
"type": "WEB",
"url": "https://github.com/kripod/record-like-deep-assign/blob/v1.0.1/src/mod.ts%23L17-L35"
},
{
"type": "WEB",
"url": "https://snyk.io/vuln/SNYK-JS-RECORDLIKEDEEPASSIGN-1311024"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
}
],
"summary": "Prototype Pollution in record-like-deep-assign"
}
GHSA-7W3C-JGH7-CWJW
Vulnerability from github – Published: 2022-05-24 17:43 – Updated: 2024-04-24 18:06A PHP object injection bug in profile.php in qcubed (all versions including 3.1.1) unserializes the untrusted data of the POST-variable "strProfileData" and allows an unauthenticated attacker to execute code via a crafted POST request.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.1.1"
},
"package": {
"ecosystem": "Packagist",
"name": "qcubed/qcubed"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2020-24914"
],
"database_specific": {
"cwe_ids": [
"CWE-915"
],
"github_reviewed": true,
"github_reviewed_at": "2024-04-24T18:06:20Z",
"nvd_published_at": "2021-03-04T13:15:00Z",
"severity": "CRITICAL"
},
"details": "A PHP object injection bug in profile.php in qcubed (all versions including 3.1.1) unserializes the untrusted data of the POST-variable \"strProfileData\" and allows an unauthenticated attacker to execute code via a crafted POST request.",
"id": "GHSA-7w3c-jgh7-cwjw",
"modified": "2024-04-24T18:06:20Z",
"published": "2022-05-24T17:43:37Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-24914"
},
{
"type": "WEB",
"url": "https://github.com/qcubed/qcubed/pull/1320/files"
},
{
"type": "PACKAGE",
"url": "https://github.com/qcubed/qcubed"
},
{
"type": "WEB",
"url": "https://tech.feedyourhead.at/content/QCubed-PHP-Object-Injection-CVE-2020-24914"
},
{
"type": "WEB",
"url": "https://www.ait.ac.at/themen/cyber-security/pentesting/security-advisories/ait-sa-20210215-01"
},
{
"type": "WEB",
"url": "http://qcubed.com"
},
{
"type": "WEB",
"url": "http://seclists.org/fulldisclosure/2021/Mar/28"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "qcubed PHP object injection"
}
GHSA-7W4P-72J7-V7C2
Vulnerability from github – Published: 2020-03-05 22:08 – Updated: 2021-08-19 19:57PHPMailer versions prior to 6.0.6 and 5.2.27 are vulnerable to an object injection attack by passing phar:// paths into addAttachment() and other functions that may receive unfiltered local paths, possibly leading to RCE. See this article for more info on this type of vulnerability. Mitigated by blocking the use of paths containing URL-protocol style prefixes such as phar://. Reported by Sehun Oh of cyberone.kr.
Impact
Object injection, possible remote code execution
Patches
Fixed in 6.0.6 and 5.2.27
Workarounds
Validate and sanitise user input before using.
References
https://nvd.nist.gov/vuln/detail/CVE-2018-19296
For more information
If you have any questions or comments about this advisory: * Open a private issue in the PHPMailer project
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "phpmailer/phpmailer"
},
"ranges": [
{
"events": [
{
"introduced": "5.0.0"
},
{
"fixed": "5.2.27"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "phpmailer/phpmailer"
},
"ranges": [
{
"events": [
{
"introduced": "6.0.0"
},
{
"fixed": "6.0.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2018-19296"
],
"database_specific": {
"cwe_ids": [
"CWE-1321",
"CWE-502",
"CWE-915"
],
"github_reviewed": true,
"github_reviewed_at": "2020-03-05T22:08:10Z",
"nvd_published_at": "2018-11-16T09:29:00Z",
"severity": "HIGH"
},
"details": "PHPMailer versions prior to 6.0.6 and 5.2.27 are vulnerable to an object injection attack by passing phar:// paths into `addAttachment()` and other functions that may receive unfiltered local paths, possibly leading to RCE. See [this article](https://knasmueller.net/5-answers-about-php-phar-exploitation) for more info on this type of vulnerability. Mitigated by blocking the use of paths containing URL-protocol style prefixes such as `phar://`. Reported by Sehun Oh of cyberone.kr.\n\n### Impact\nObject injection, possible remote code execution\n\n### Patches\nFixed in 6.0.6 and 5.2.27\n\n### Workarounds\nValidate and sanitise user input before using.\n\n### References\nhttps://nvd.nist.gov/vuln/detail/CVE-2018-19296\n\n### For more information\nIf you have any questions or comments about this advisory:\n* Open a private issue in [the PHPMailer project](https://github.com/PHPMailer/PHPMailer)",
"id": "GHSA-7w4p-72j7-v7c2",
"modified": "2021-08-19T19:57:58Z",
"published": "2020-03-05T22:08:55Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/PHPMailer/PHPMailer/security/advisories/GHSA-7w4p-72j7-v7c2"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-19296"
},
{
"type": "WEB",
"url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/phpmailer/phpmailer/CVE-2018-19296.yaml"
},
{
"type": "WEB",
"url": "https://github.com/PHPMailer/PHPMailer/releases/tag/v5.2.27"
},
{
"type": "WEB",
"url": "https://github.com/PHPMailer/PHPMailer/releases/tag/v6.0.6"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2018/12/msg00020.html"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/3B5WDPGUFNPG4NAZ6G4BZX43BKLAVA5B"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/KPU66INRFY5BQ3ESVPRUXJR4DXQAFJVT"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/3B5WDPGUFNPG4NAZ6G4BZX43BKLAVA5B"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/KPU66INRFY5BQ3ESVPRUXJR4DXQAFJVT"
},
{
"type": "WEB",
"url": "https://www.debian.org/security/2018/dsa-4351"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Phar object injection in PHPMailer"
}
GHSA-7WPW-2HJM-89GP
Vulnerability from github – Published: 2021-05-04 20:18 – Updated: 2024-02-13 22:31All versions of package merge <2.1.1 are vulnerable to Prototype Pollution via _recursiveMerge .
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "merge"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.1.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2020-28499"
],
"database_specific": {
"cwe_ids": [
"CWE-915"
],
"github_reviewed": true,
"github_reviewed_at": "2021-03-18T22:54:25Z",
"nvd_published_at": "2021-02-18T16:15:00Z",
"severity": "HIGH"
},
"details": "All versions of package merge \u003c2.1.1 are vulnerable to Prototype Pollution via _recursiveMerge .",
"id": "GHSA-7wpw-2hjm-89gp",
"modified": "2024-02-13T22:31:44Z",
"published": "2021-05-04T20:18:47Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-28499"
},
{
"type": "WEB",
"url": "https://github.com/yeikos/js.merge/commit/7b0ddc2701d813f2ba289b32d6a4b9d4cc235fb4"
},
{
"type": "WEB",
"url": "https://github.com/yeikos/js.merge/blob/56ca75b2dd0f2820f1e08a49f62f04bbfb8c5f8f/src/index.ts#L64"
},
{
"type": "WEB",
"url": "https://github.com/yeikos/js.merge/blob/master/src/index.ts#L64"
},
{
"type": "WEB",
"url": "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-1071049"
},
{
"type": "WEB",
"url": "https://snyk.io/vuln/SNYK-JS-MERGE-1042987"
},
{
"type": "WEB",
"url": "https://vuldb.com/?id.170146"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
}
],
"summary": "Prototype Pollution in merge"
}
GHSA-826J-8WP2-4X6Q
Vulnerability from github – Published: 2023-08-25 18:42 – Updated: 2023-08-25 18:42Impact
A Mass assignment vulnerability was found allowing a non-admin user to escalate privileges to admin user.
Patches
Issue is patched in 0.17.1, and fixed in 0.18.6+.
If Users are using 0.17.1, they should run "docker pull gravitl/netmaker:v0.17.1" and "docker-compose up -d". This will switch them to the patched users
If users are using v0.18.0-0.18.5, they should upgrade to v0.18.6 or later.
Workarounds
If using 0.17.1, can just pull the latest docker image of backend and restart server.
References
Credit to Project Discovery, and in particular https://github.com/rootxharsh , https://github.com/iamnoooob, and https://github.com/projectdiscovery
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/gravitl/netmaker"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.17.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/gravitl/netmaker"
},
"ranges": [
{
"events": [
{
"introduced": "0.18.0"
},
{
"fixed": "0.18.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2023-32079"
],
"database_specific": {
"cwe_ids": [
"CWE-915"
],
"github_reviewed": true,
"github_reviewed_at": "2023-08-25T18:42:53Z",
"nvd_published_at": "2023-08-24T23:15:08Z",
"severity": "HIGH"
},
"details": "### Impact\nA Mass assignment vulnerability was found allowing a non-admin user to escalate privileges to admin user.\n\n### Patches\nIssue is patched in 0.17.1, and fixed in 0.18.6+.\n\nIf Users are using 0.17.1, they should run \"docker pull gravitl/netmaker:v0.17.1\" and \"docker-compose up -d\". This will switch them to the patched users\n\nIf users are using v0.18.0-0.18.5, they should upgrade to v0.18.6 or later.\n\n### Workarounds\nIf using 0.17.1, can just pull the latest docker image of backend and restart server.\n\n### References\nCredit to Project Discovery, and in particular https://github.com/rootxharsh , https://github.com/iamnoooob, and https://github.com/projectdiscovery",
"id": "GHSA-826j-8wp2-4x6q",
"modified": "2023-08-25T18:42:53Z",
"published": "2023-08-25T18:42:53Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gravitl/netmaker/security/advisories/GHSA-826j-8wp2-4x6q"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-32079"
},
{
"type": "PACKAGE",
"url": "https://github.com/gravitl/netmaker"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Netmaker Vulnerable to Privilege Escalation From Non Admin To Admin User"
}
Mitigation
- If available, use features of the language or framework that allow specification of allowlists of attributes or fields that are allowed to be modified. If possible, prefer allowlists over denylists.
- For applications written with Ruby on Rails, use the attr_accessible (allowlist) or attr_protected (denylist) macros in each class that may be used in mass assignment.
Mitigation
If available, use the signing/sealing features of the programming language to assure that deserialized data has not been tainted. For example, a hash-based message authentication code (HMAC) could be used to ensure that data has not been modified.
Mitigation
Strategy: Input Validation
For any externally-influenced input, check the input against an allowlist of internal object attributes or fields that are allowed to be modified.
Mitigation
Strategy: Refactoring
Refactor the code so that object attributes or fields do not need to be dynamically identified, and only expose getter/setter functionality for the intended attributes.
No CAPEC attack patterns related to this CWE.