CWE-639
AllowedAuthorization Bypass Through User-Controlled Key
Abstraction: Base · Status: Incomplete
The system's authorization functionality does not prevent one user from gaining access to another user's data or record by modifying the key value identifying the data.
4730 vulnerabilities reference this CWE, most recent first.
GHSA-QWXF-2M7M-2M3X
Vulnerability from github – Published: 2026-06-17 18:07 – Updated: 2026-07-20 21:10Summary
A cross-tenant authorization flaw in Daytona's notification WebSocket gateway allowed any authenticated user to subscribe to another organization's realtime notification channel and passively receive that organization's events.
Impact
The notification gateway's JWT handshake joined a client-supplied organization identifier to the corresponding notification room without verifying that the authenticated user was a member of that organization. As a result, an authenticated user could receive another organization's realtime sandbox, snapshot, volume, and runner events, including data carried in those events. This is a cross-tenant confidentiality break. It required a valid account and knowledge of the target organization id (a non-secret UUID); no elevated privileges were needed. The API-key authentication path was not affected.
The affected component is the Daytona API service (the apps/api NestJS application). It is distributed through Daytona's repository releases and container images for self-hosted deployments; it is not published as a Go or npm package, so the advisory will not surface through go get or npm dependency tooling.
Affected Versions
= 0.101.0, <= 0.184.0
Patched Versions
0.185.0
Credit
@vnth4nhnt from CyStack
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.184.0"
},
"package": {
"ecosystem": "Go",
"name": "github.com/daytonaio/daytona"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.185.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54324"
],
"database_specific": {
"cwe_ids": [
"CWE-639",
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-17T18:07:30Z",
"nvd_published_at": "2026-06-23T18:18:09Z",
"severity": "MODERATE"
},
"details": "### Summary\nA cross-tenant authorization flaw in Daytona\u0027s notification WebSocket gateway allowed any authenticated user to subscribe to another organization\u0027s realtime notification channel and passively receive that organization\u0027s events.\n\n### Impact\nThe notification gateway\u0027s JWT handshake joined a client-supplied organization identifier to the corresponding notification room without verifying that the authenticated user was a member of that organization. As a result, an authenticated user could receive another organization\u0027s realtime sandbox, snapshot, volume, and runner events, including data carried in those events. This is a cross-tenant confidentiality break. It required a valid account and knowledge of the target organization id (a non-secret UUID); no elevated privileges were needed. The API-key authentication path was not affected.\n\nThe affected component is the Daytona API service (the `apps/api` NestJS application). It is distributed through Daytona\u0027s repository releases and container images for self-hosted deployments; it is not published as a Go or npm package, so the advisory will not surface through `go get` or npm dependency tooling.\n\n### Affected Versions\n\u003e= 0.101.0, \u003c= 0.184.0\n\n### Patched Versions\n0.185.0\n\n### Credit\n@vnth4nhnt from CyStack",
"id": "GHSA-qwxf-2m7m-2m3x",
"modified": "2026-07-20T21:10:57Z",
"published": "2026-06-17T18:07:30Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/daytonaio/daytona/security/advisories/GHSA-qwxf-2m7m-2m3x"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-54324"
},
{
"type": "PACKAGE",
"url": "https://github.com/daytonaio/daytona"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Daytona: Cross-tenant data leak in notification WebSocket gateway via unverified organizationId join"
}
GHSA-QX86-G93J-M25R
Vulnerability from github – Published: 2026-04-23 15:38 – Updated: 2026-04-23 15:38An API design flaw in WebKitGTK and WPE WebKit allows untrusted web content to unexpectedly perform IP connections, DNS lookups, and HTTP requests. Applications expect to use the WebPage::send-request signal handler to approve or reject all network requests. However, certain types of HTTP requests bypass this signal handler.
{
"affected": [],
"aliases": [
"CVE-2025-66286"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-04-23T13:16:11Z",
"severity": "MODERATE"
},
"details": "An API design flaw in WebKitGTK and WPE WebKit allows untrusted web content to unexpectedly perform IP connections, DNS lookups, and HTTP requests. Applications expect to use the\nWebPage::send-request signal handler to approve or reject all network requests. However, certain types of HTTP requests bypass this signal handler.",
"id": "GHSA-qx86-g93j-m25r",
"modified": "2026-04-23T15:38:56Z",
"published": "2026-04-23T15:38:56Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-66286"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2025-66286"
},
{
"type": "WEB",
"url": "https://bugs.webkit.org/show_bug.cgi?id=259787"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2424652"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-QXM8-6XVG-W483
Vulnerability from github – Published: 2025-07-18 15:31 – Updated: 2026-06-01 15:30Authorization Bypass Through User-Controlled Key vulnerability in Vidco Software VOC TESTER allows Forceful Browsing.This issue affects VOC TESTER: before 12.41.0.
{
"affected": [],
"aliases": [
"CVE-2024-13175"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-07-18T14:15:23Z",
"severity": "MODERATE"
},
"details": "Authorization Bypass Through User-Controlled Key vulnerability in Vidco Software VOC TESTER allows Forceful Browsing.This issue affects VOC TESTER: before 12.41.0.",
"id": "GHSA-qxm8-6xvg-w483",
"modified": "2026-06-01T15:30:32Z",
"published": "2025-07-18T15:31:56Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-13175"
},
{
"type": "WEB",
"url": "https://siberguvenlik.gov.tr/guvenlik-bildirimleri/detay/tr-25-0159"
},
{
"type": "WEB",
"url": "https://www.usom.gov.tr/bildirim/tr-25-0159"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-QXPP-QJG8-X4JV
Vulnerability from github – Published: 2026-10-02 19:31 – Updated: 2026-10-02 19:31Summary
The dashboard replay action authorizes the source run (it must belong to the caller's org), but the target environment for the replayed run is taken verbatim from the request body and is never checked for org or project membership. The environment lookup used by the replay path filters by id only. As a result, an authenticated user can replay one of their own runs into another organization's or project's environment, creating a task run there that consumes the victim tenant's queue and compute and pollutes their run history.
Details
The replay action member-scopes the source run correctly (apps/webapp/app/routes/resources.taskruns.$runParam.replay.ts, the findFirst on taskRun filtered by project.organization.members.some.userId), but passes the target environment straight from the submitted form, resources.taskruns.$runParam.replay.ts:344-346:
const replayRunService = new ReplayTaskRunService();
const newRun = await replayRunService.call(taskRun, {
environmentId: submission.value.environment, // attacker-controlled, unvalidated
payload: submission.value.payload,
...
});
submission.value.environment comes from ReplayRunData (apps/webapp/app/v3/replayTask.ts: environment: z.string().optional()), so it is fully client-controlled.
ReplayTaskRunService resolves it with no ownership check, apps/webapp/app/v3/services/replayTaskRun.server.ts:26-28:
const authenticatedEnvironment = await findEnvironmentById(
overrideOptions.environmentId ?? existingTaskRun.runtimeEnvironmentId
);
findEnvironmentById, apps/webapp/app/models/runtimeEnvironment.server.ts:197-211:
export async function findEnvironmentById(id) {
const environment = await $replica.runtimeEnvironment.findFirst({
where: { id }, // no membership / org / project filter
include: authIncludeWithParent,
});
if (!environment || environment.project.deletedAt !== null) return null;
return toAuthenticated(environment);
}
The resolved environment is then handed to TriggerTaskService.call (apps/webapp/app/v3/services/triggerTask.server.ts), which trusts the passed authenticatedEnvironment and performs no further authorization. The replay loader does constrain the environment picker to the run's own project (replay.ts around 178-184), but the action does not re-impose that constraint, so the server-side control is missing (UI-gated only).
PoC
As an authenticated user who owns a run in their own org (run param runParam), and who knows a target environment id belonging to another org or project (a CUID, obtained or guessed):
POST /resources/taskruns/<own runParam>/replay
Content-Type: application/x-www-form-urlencoded
environment=<environment id of the victim org/project>&failedRedirect=/...
The replay resolves the victim environment with no membership check and calls TriggerTaskService against it, creating a run in the victim tenant.
Live-validated: a Postgres database was seeded with two tenants (orgA with env_A, orgB with env_B_victim) and the verbatim findEnvironmentById lookup (findFirst joining the environment to its project, WHERE id = $1, the exact query the replay path runs) was executed with the victim env id as an orgA attacker. Captured:
[002 replay findEnvironmentById] attacker(orgA) supplied env_B_victim -> {"id":"env_B_victim","organization_id":"orgB","project_id":"proj_B","deleted_at":null}
CROSS-TENANT: CONFIRMED (resolved another org's env with no membership check -> replay would run there)
The lookup returned another organization's environment with no membership filter. That the replay action passes the client-supplied environmentId straight into this lookup (and TriggerTaskService trusts the returned env) is verified at source.
Impact
An authenticated user can create task runs in another tenant's environment (including production), consuming that tenant's queue concurrency and compute and inserting entries into their run history. Practical exploitation requires knowing a target environment id (not enumerable) and, for the injected run to actually execute rather than error, a task identifier that exists in the target environment; this bounds reliability but not the unauthorized cross-tenant write itself.
Remediation
In the replay action (or in ReplayTaskRunService), require the resolved target environment to belong to the source run's project/organization, for example assert environment.projectId === existingTaskRun.projectId, or re-validate the supplied environment id against the caller's membership (findEnvironmentBySlug with the validated projectId, or a members.some.userId filter), mirroring the constraint the loader already applies to the picker.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "trigger.dev"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.5.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-02T19:31:17Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\nThe dashboard replay action authorizes the source run (it must belong to the caller\u0027s org), but the target environment for the replayed run is taken verbatim from the request body and is never checked for org or project membership. The environment lookup used by the replay path filters by id only. As a result, an authenticated user can replay one of their own runs into another organization\u0027s or project\u0027s environment, creating a task run there that consumes the victim tenant\u0027s queue and compute and pollutes their run history.\n\n### Details\nThe replay action member-scopes the source run correctly (apps/webapp/app/routes/resources.taskruns.$runParam.replay.ts, the findFirst on taskRun filtered by `project.organization.members.some.userId`), but passes the target environment straight from the submitted form, resources.taskruns.$runParam.replay.ts:344-346:\n```js\nconst replayRunService = new ReplayTaskRunService();\nconst newRun = await replayRunService.call(taskRun, {\n environmentId: submission.value.environment, // attacker-controlled, unvalidated\n payload: submission.value.payload,\n ...\n});\n```\n`submission.value.environment` comes from ReplayRunData (apps/webapp/app/v3/replayTask.ts: `environment: z.string().optional()`), so it is fully client-controlled.\n\nReplayTaskRunService resolves it with no ownership check, apps/webapp/app/v3/services/replayTaskRun.server.ts:26-28:\n```js\nconst authenticatedEnvironment = await findEnvironmentById(\n overrideOptions.environmentId ?? existingTaskRun.runtimeEnvironmentId\n);\n```\nfindEnvironmentById, apps/webapp/app/models/runtimeEnvironment.server.ts:197-211:\n```js\nexport async function findEnvironmentById(id) {\n const environment = await $replica.runtimeEnvironment.findFirst({\n where: { id }, // no membership / org / project filter\n include: authIncludeWithParent,\n });\n if (!environment || environment.project.deletedAt !== null) return null;\n return toAuthenticated(environment);\n}\n```\nThe resolved environment is then handed to TriggerTaskService.call (apps/webapp/app/v3/services/triggerTask.server.ts), which trusts the passed authenticatedEnvironment and performs no further authorization. The replay loader does constrain the environment picker to the run\u0027s own project (replay.ts around 178-184), but the action does not re-impose that constraint, so the server-side control is missing (UI-gated only).\n\n### PoC\nAs an authenticated user who owns a run in their own org (run param runParam), and who knows a target environment id belonging to another org or project (a CUID, obtained or guessed):\n```http\nPOST /resources/taskruns/\u003cown runParam\u003e/replay\nContent-Type: application/x-www-form-urlencoded\n\nenvironment=\u003cenvironment id of the victim org/project\u003e\u0026failedRedirect=/...\n```\nThe replay resolves the victim environment with no membership check and calls TriggerTaskService against it, creating a run in the victim tenant.\n\nLive-validated: a Postgres database was seeded with two tenants (orgA with env_A, orgB with env_B_victim) and the verbatim findEnvironmentById lookup (findFirst joining the environment to its project, `WHERE id = $1`, the exact query the replay path runs) was executed with the victim env id as an orgA attacker. Captured:\n```\n[002 replay findEnvironmentById] attacker(orgA) supplied env_B_victim -\u003e {\"id\":\"env_B_victim\",\"organization_id\":\"orgB\",\"project_id\":\"proj_B\",\"deleted_at\":null}\nCROSS-TENANT: CONFIRMED (resolved another org\u0027s env with no membership check -\u003e replay would run there)\n```\nThe lookup returned another organization\u0027s environment with no membership filter. That the replay action passes the client-supplied environmentId straight into this lookup (and TriggerTaskService trusts the returned env) is verified at source.\n\n### Impact\nAn authenticated user can create task runs in another tenant\u0027s environment (including production), consuming that tenant\u0027s queue concurrency and compute and inserting entries into their run history. Practical exploitation requires knowing a target environment id (not enumerable) and, for the injected run to actually execute rather than error, a task identifier that exists in the target environment; this bounds reliability but not the unauthorized cross-tenant write itself.\n\n### Remediation\nIn the replay action (or in ReplayTaskRunService), require the resolved target environment to belong to the source run\u0027s project/organization, for example assert `environment.projectId === existingTaskRun.projectId`, or re-validate the supplied environment id against the caller\u0027s membership (findEnvironmentBySlug with the validated projectId, or a members.some.userId filter), mirroring the constraint the loader already applies to the picker.",
"id": "GHSA-qxpp-qjg8-x4jv",
"modified": "2026-10-02T19:31:17Z",
"published": "2026-10-02T19:31:17Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/triggerdotdev/trigger.dev/security/advisories/GHSA-qxpp-qjg8-x4jv"
},
{
"type": "WEB",
"url": "https://github.com/triggerdotdev/trigger.dev/pull/4199"
},
{
"type": "WEB",
"url": "https://github.com/triggerdotdev/trigger.dev/commit/34b1a181c2a1d33a53ebab88f84b05f81fea4254"
},
{
"type": "PACKAGE",
"url": "https://github.com/triggerdotdev/trigger.dev"
},
{
"type": "WEB",
"url": "https://github.com/triggerdotdev/trigger.dev/releases/tag/v4.5.2"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L",
"type": "CVSS_V3"
}
],
"summary": "Trigger.dev: Run replay injects a task run into an attacker-chosen environment (cross-tenant write)"
}
GHSA-QXQC-G59M-CQX4
Vulnerability from github – Published: 2026-02-03 09:30 – Updated: 2026-02-03 09:30The Tutor LMS – eLearning and online course solution plugin for WordPress is vulnerable to Insecure Direct Object References (IDOR) in all versions up to, and including, 3.9.5. This is due to missing object-level authorization checks in the course_list_bulk_action(), bulk_delete_course(), and update_course_status() functions. This makes it possible for authenticated attackers, with Tutor Instructor-level access and above, to modify or delete arbitrary courses they do not own by manipulating course IDs in bulk action requests.
{
"affected": [],
"aliases": [
"CVE-2026-1375"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-02-03T08:16:14Z",
"severity": "HIGH"
},
"details": "The Tutor LMS \u2013 eLearning and online course solution plugin for WordPress is vulnerable to Insecure Direct Object References (IDOR) in all versions up to, and including, 3.9.5. This is due to missing object-level authorization checks in the `course_list_bulk_action()`, `bulk_delete_course()`, and `update_course_status()` functions. This makes it possible for authenticated attackers, with Tutor Instructor-level access and above, to modify or delete arbitrary courses they do not own by manipulating course IDs in bulk action requests.",
"id": "GHSA-qxqc-g59m-cqx4",
"modified": "2026-02-03T09:30:28Z",
"published": "2026-02-03T09:30:28Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-1375"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/tutor/tags/3.9.5/classes/Course_List.php#L289"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/tutor/tags/3.9.5/classes/Course_List.php#L437"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/tutor/tags/3.9.5/classes/Course_List.php#L463"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset/3448615/tutor/trunk/classes/Course_List.php?contextall=1\u0026old=3339576\u0026old_path=%2Ftutor%2Ftrunk%2Fclasses%2FCourse_List.php"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/4e95b32b-c050-41eb-8fce-461257420eb6?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-QXVH-QPPG-J3PV
Vulnerability from github – Published: 2026-06-23 18:31 – Updated: 2026-06-23 18:31Pega Platform versions 8.3.0 through Infinity 25.1.2 are affected by an authorization weakness that may allow authenticated users to access certain additional data via crafted URLs.
{
"affected": [],
"aliases": [
"CVE-2025-62180"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-06-23T16:16:58Z",
"severity": "HIGH"
},
"details": "Pega Platform versions 8.3.0 through Infinity 25.1.2 are affected by an authorization weakness that may allow authenticated users to access certain additional data via crafted URLs.",
"id": "GHSA-qxvh-qppg-j3pv",
"modified": "2026-06-23T18:31:37Z",
"published": "2026-06-23T18:31:37Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-62180"
},
{
"type": "WEB",
"url": "https://support.pega.com/support-doc/pega-security-advisory-h26-vulnerability-remediation-note"
},
{
"type": "WEB",
"url": "https://support.pega.com/support-doc/pega-security-advisory-i25-vulnerability-remediation-note"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-QXVM-PCFM-QC39
Vulnerability from github – Published: 2026-06-16 21:30 – Updated: 2026-07-20 21:15Summary
Daytona's organization role update and delete endpoints authorized the caller as an owner of the organization named in the request path, but resolved and mutated the target role by its identifier alone, without verifying the role belonged to that organization. An authenticated user who owns any organization (organizations are self-service) could therefore modify the permissions of, or delete, a role belonging to a different organization, given that role's identifier.
Impact
This is a cross-tenant broken access control (IDOR) issue affecting multi-tenant deployments, including the managed Daytona platform. Using a target role's identifier, an attacker with owner rights over their own organization could:
- Overwrite the target role's name and permission set, escalating or stripping privileges for every member and API key in the victim organization that holds that role.
- Delete the target role, removing the associated permissions from its holders.
- Observe the victim role's current permission set returned in the update response (limited information disclosure).
Exploitation requires knowledge of the target role's identifier, which is not enumerable across organizations and is not exposed to non-members through the API.
Affected versions
All versions up to and including 0.184.0.
Patches
Fixed in 0.185.0. The role update, delete, and role-assignment lookups are now scoped to the caller's organization, so a role belonging to another organization resolves to "not found" before any read or mutation. The managed Daytona platform was updated on release of 0.185.0.
Workarounds
None. Upgrade to 0.185.0. Single-organization self-hosted deployments are not exploitable, as the issue requires a second organization to target.
Credit
Reported by @vnth4nhnt.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.184.0"
},
"package": {
"ecosystem": "Go",
"name": "github.com/daytonaio/daytona"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.185.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54322"
],
"database_specific": {
"cwe_ids": [
"CWE-639",
"CWE-862"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-16T21:30:08Z",
"nvd_published_at": "2026-06-23T19:17:08Z",
"severity": "HIGH"
},
"details": "### Summary\nDaytona\u0027s organization role update and delete endpoints authorized the caller as an owner of the organization named in the request path, but resolved and mutated the target role by its identifier alone, without verifying the role belonged to that organization. An authenticated user who owns any organization (organizations are self-service) could therefore modify the permissions of, or delete, a role belonging to a different organization, given that role\u0027s identifier.\n\n### Impact\nThis is a cross-tenant broken access control (IDOR) issue affecting multi-tenant deployments, including the managed Daytona platform. Using a target role\u0027s identifier, an attacker with owner rights over their own organization could:\n\n- Overwrite the target role\u0027s name and permission set, escalating or stripping privileges for every member and API key in the victim organization that holds that role.\n- Delete the target role, removing the associated permissions from its holders.\n- Observe the victim role\u0027s current permission set returned in the update response (limited information disclosure).\n\nExploitation requires knowledge of the target role\u0027s identifier, which is not enumerable across organizations and is not exposed to non-members through the API.\n\n### Affected versions\nAll versions up to and including 0.184.0.\n\n### Patches\nFixed in 0.185.0. The role update, delete, and role-assignment lookups are now scoped to the caller\u0027s organization, so a role belonging to another organization resolves to \"not found\" before any read or mutation. The managed Daytona platform was updated on release of 0.185.0.\n\n### Workarounds\nNone. Upgrade to 0.185.0. Single-organization self-hosted deployments are not exploitable, as the issue requires a second organization to target.\n\n### Credit\nReported by @vnth4nhnt.",
"id": "GHSA-qxvm-pcfm-qc39",
"modified": "2026-07-20T21:15:04Z",
"published": "2026-06-16T21:30:08Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/daytonaio/daytona/security/advisories/GHSA-qxvm-pcfm-qc39"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-54322"
},
{
"type": "PACKAGE",
"url": "https://github.com/daytonaio/daytona"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:L",
"type": "CVSS_V3"
}
],
"summary": "Daytona: Cross-org IDOR in organization role update/delete \u2014 any org owner can rewrite or destroy another org\u0027s roles"
}
GHSA-QXVM-R42F-5P8J
Vulnerability from github – Published: 2026-05-15 18:17 – Updated: 2026-05-15 18:17Summary
Type: Authorization-bypass via user-controlled identifier. The Meet plugin's recorded-video upload endpoint (plugin/Meet/uploadRecordedVideo.json.php) authenticates the caller using a single shared Authorization: Bearer <secret> against $objM->secret. Once that check passes, the endpoint reads the target user identifier from the uploaded file's name field, instantiates a User object with that ID, and calls $userObject->login(true, true) — the no-password / encoded-password login path — committing a session for that user and emitting Set-Cookie headers to the caller. There is no check that the caller actually owns the requested users_id.
File: plugin/Meet/uploadRecordedVideo.json.php, lines 56-65; secondary in objects/user.php User::login() (no-password branch at lines 1276-1310).
Root cause: the upload handler's identity model is "service-to-service" (a Meet/Jitsi recorder posts a finished recording back to AVideo with the shared secret) but the users_id to credit the upload to is parsed from the FILENAME the same caller controls — $users_id = explode('-', $_FILES['upl']['name'])[0];. There is no signed claim, no separate proof-of-identity, no allowlist. The subsequent $userObject->login(true, true) call invokes the no-password login path which sets $_SESSION['user'], calls setUserCookie(...), and _session_regenerate_id() — exactly the operations a normal login performs. The response carries the new PHPSESSID back to the caller, who can then reuse it on every subsequent request to act as the targeted user. The Meet shared secret is md5($global['systemRootPath'] . $global['salt'] . "meet") (Meet.php:73), so any attacker who can read videos/configuration.php (e.g., via a path-traversal CVE such as GHSA-83xq-8jxj-4rxm or GHSA-4wmm-6qxj-fpj4 that the project has already addressed in this surface area) can compute the Meet secret deterministically and pivot to full account takeover.
Affected Code
File: plugin/Meet/uploadRecordedVideo.json.php, lines 33-73.
if (empty($token)) {
forbiddenPage('Token not found');
}
$objM = AVideoPlugin::getObjectDataIfEnabled("Meet");
if (empty($objM)) {
forbiddenPage('Plugin disabled');
}
if ($objM->secret != $token) { // <-- shared-secret auth, no per-user proof
forbiddenPage('Token does not match');
}
if (empty($_FILES['upl'])) {
forbiddenPage('videoFile not found');
}
$users_id = explode('-', $_FILES['upl']['name'])[0]; // <-- BUG: target users_id parsed from attacker-controlled filename
$userObject = new User($users_id);
$userObject->login(true, true); // <-- BUG: passwordless login as the chosen user; sets $_SESSION + Set-Cookie
$tmpFile = getTmpDir() . uniqid();
if (move_uploaded_file($_FILES['upl']['tmp_name'], $tmpFile)) {
$_FILES['upl']['tmp_name'] = $tmpFile;
require $global['systemRootPath'] . 'objects/aVideoQueueEncoder.json.php';
}
File: objects/user.php, lines 1249-1329 (User::login() no-password branch).
public function login($noPass = false, $encodedPass = false, $ignoreEmailVerification = false)
{
// ...
if ($noPass) {
$user = $this->find($this->user, false, true); // <-- no password check
}
// ...
} elseif ($user) {
$_SESSION['user'] = $user; // <-- session set for the impersonated user
$this->setLastLogin($_SESSION['user']['id']);
// ...
self::setUserCookie($rememberme, $user['id'], $user['user'], $passhash, $expires);
AVideoPlugin::onUserSignIn($_SESSION['user']['id']);
$_SESSION['loginAttempts'] = 0;
_session_regenerate_id(); // <-- new SID committed in Set-Cookie response
_session_write_close();
return self::USER_LOGGED;
}
}
Why it's wrong: the endpoint conflates two distinct authentication concerns. The shared-secret check answers "is this request coming from a trusted Meet recorder?" but the filename parse answers "which user does this recording belong to?" — and the second answer is taken from the same untrusted caller. Once User->login(true, true) runs, the server has no way to distinguish a legitimate Meet integration from an attacker who happens to know the same secret. The decision to expose this as a session (cookie + _session_regenerate_id) rather than as a one-shot in-process credit makes the impact larger than it needs to be: even if the Meet integration only needed to credit the recording to a user, the implementation gives the caller a fully-authenticated session as that user.
Exploit Chain
- Attacker obtains the Meet shared secret. Two plausible paths:
- Path A (computational): the secret is
md5($global['systemRootPath'] . $global['salt'] . "meet")(plugin/Meet/Meet.php:73). Both inputs sit invideos/configuration.php. AVideo's history of LFI/path-traversal CVEs in this surface (e.g., theimport.json.phpandlistFiles.json.phpadvisories already accepted on this program) means the salt is a realistic disclosure target. - Path B (timing oracle):
plugin/Meet/checkToken.json.phpline 26 doesif ($objM->secret === $_GET['secret'])with no constant-time comparison and a clear yes/no response body. PHP's===for strings short-circuits on first byte mismatch, so an attacker on the same network segment can recover the 32-hex secret byte-by-byte over the network with timing analysis. Slower than path A but doesn't depend on a separate vulnerability. - Attacker prepares an HTTP POST to
/plugin/Meet/uploadRecordedVideo.json.php: Authorization: Bearer <Meet secret>- Multipart body with one file field named
upl. The filename is set to1-anything.mp4(where1is theusers_idof the admin or any target user — the format is<users_id>-<arbitrary>). The file body itself can be anything that survives the surrounding aVideoQueueEncoder pipeline (an empty file is enough to reach the login call before the encoder rejects). - Server flow:
- Line 33: token present, ok.
- Line 46:
$objM->secret != $token→ false (matches), passes. - Line 51:
$_FILES['upl']present, ok. - Line 56:
$users_id = explode('-', '1-anything.mp4')[0]→'1'. - Line 59-60:
$userObject = new User(1); $userObject->login(true, true);— passwordless login as user 1 (admin).$_SESSION['user']is set,setUserCookieruns,_session_regenerate_idissues a new session ID, and the response carriesSet-Cookie: PHPSESSID=<new-sid>; .... - Subsequent code runs the encoder pipeline as admin — but the attacker's primary goal was already achieved when the session was established.
- Attacker captures the
Set-Cookie: PHPSESSID=...header from the response and uses that cookie on all subsequent requests. Server treats them as user 1 (admin) — full UI access, all admin endpoints, all video management, plugin configuration, user impersonation, etc. - Final state: admin account takeover. The original Meet recorder's flow (legitimate uploads with
users_id= the user who scheduled the meeting) is indistinguishable on the wire from the attack flow (users_id= whoever the attacker wants to be).
Security Impact
Severity: sec-high. End state is full account takeover of any user (including admin), reachable from a single HTTP POST once the secret is known. The shared-secret precondition raises AC to High but does not eliminate it as a credible threat — the secret is computable from any leak of videos/configuration.php, and AVideo's CVE history in that surface area is non-trivial.
Attacker capability: session hijack as any users_id the attacker cares to name. The attacker chooses the target by setting the filename's leading digits before the first -. No bound on which user IDs are reachable; admin (1 on a default install) is the obvious target. Once the session is captured, the attacker has full admin UI/API access for the session lifetime (hours-to-days depending on rememberme flag).
Preconditions: Meet plugin enabled (default-off but commonly enabled by deployments using AVideo for video-conferencing recording). Knowledge of the Meet shared secret (computable from the salt; obtainable via timing attack on checkToken.json.php).
Differential: source-inspection-verified end-to-end. The two relevant code blocks are quoted verbatim in §Affected Code; both lines are reachable on every successful POST to the endpoint. The patched build (with the suggested fix below) either rejects the upload as 'cannot derive identity from filename' or constrains the users_id to one bound by an additional signed claim from the Meet recorder.
Suggested Fix
Three changes, in order of importance:
--- a/plugin/Meet/uploadRecordedVideo.json.php
+++ b/plugin/Meet/uploadRecordedVideo.json.php
@@ -53,17 +53,28 @@ if (empty($_FILES['upl'])) {
forbiddenPage('videoFile not found');
}
-$users_id = explode('-', $_FILES['upl']['name'])[0];
+// The users_id MUST come from a signed claim (e.g., a JWT issued by AVideo
+// when the meeting was scheduled), not from a filename the caller controls.
+// Verify a recording-upload token here that was minted at meeting-create
+// time and bound to (meet_schedule_id, users_id) with an HMAC.
+$claim = MeetUploadClaim::verifyFromHeaders($headers);
+if (!$claim) {
+ forbiddenPage('Missing or invalid recording upload claim');
+}
+$users_id = (int) $claim->users_id;
+if (!$users_id || !User::idExists($users_id)) {
+ forbiddenPage('Recording upload claim references unknown user');
+}
-$userObject = new User($users_id);
-$userObject->login(true, true);
+// Credit the upload to $users_id WITHOUT establishing a session. The encoder
+// pipeline can be parameterised to record ownership directly; there is no
+// reason for a service-to-service upload endpoint to mint a user session.
+$queueOwnerUsersId = $users_id;
$tmpFile = getTmpDir() . uniqid();
if (move_uploaded_file($_FILES['upl']['tmp_name'], $tmpFile)) {
$_FILES['upl']['tmp_name'] = $tmpFile;
- require $global['systemRootPath'] . 'objects/aVideoQueueEncoder.json.php';
+ aVideoQueueEncoder::encodeOnBehalfOf($queueOwnerUsersId, $_FILES['upl']);
}
Additionally:
- Use
hash_equalsfor the secret comparison in both this endpoint andcheckToken.json.php(if (!hash_equals($objM->secret, $token))). The current==/===is vulnerable to byte-by-byte timing analysis. - Remove
checkToken.json.phpentirely, or at least gate it behindUser::isAdmin(). A network-reachable endpoint that confirms whether a guess matches the server-side secret is exactly the wrong shape for a high-value secret like this one.
Optional defense-in-depth (separate change): rotate the Meet secret to use a random 256-bit value (not derived from salt), so a videos/configuration.php disclosure does not also yield the Meet secret. Store the random secret as a per-deployment row in the Meet plugin's configuration table, generated at first-run.
Add a regression test: call uploadRecordedVideo.json.php with the correct secret but a filename of 1-x.mp4; assert the response does NOT include a Set-Cookie: PHPSESSID= header.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "WWBN/AVideo"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "29.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-1390",
"CWE-287",
"CWE-639"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-15T18:17:19Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\n**Type:** Authorization-bypass via user-controlled identifier. The Meet plugin\u0027s recorded-video upload endpoint (`plugin/Meet/uploadRecordedVideo.json.php`) authenticates the caller using a single shared `Authorization: Bearer \u003csecret\u003e` against `$objM-\u003esecret`. Once that check passes, the endpoint reads the *target user identifier* from the uploaded file\u0027s `name` field, instantiates a `User` object with that ID, and calls `$userObject-\u003elogin(true, true)` \u2014 the no-password / encoded-password login path \u2014 committing a session for that user and emitting `Set-Cookie` headers to the caller. There is no check that the caller actually owns the requested `users_id`.\n**File:** `plugin/Meet/uploadRecordedVideo.json.php`, lines 56-65; secondary in `objects/user.php` `User::login()` (no-password branch at lines 1276-1310).\n**Root cause:** the upload handler\u0027s identity model is \"service-to-service\" (a Meet/Jitsi recorder posts a finished recording back to AVideo with the shared secret) but the `users_id` to credit the upload to is parsed from the FILENAME the same caller controls \u2014 `$users_id = explode(\u0027-\u0027, $_FILES[\u0027upl\u0027][\u0027name\u0027])[0];`. There is no signed claim, no separate proof-of-identity, no allowlist. The subsequent `$userObject-\u003elogin(true, true)` call invokes the no-password login path which sets `$_SESSION[\u0027user\u0027]`, calls `setUserCookie(...)`, and `_session_regenerate_id()` \u2014 exactly the operations a normal login performs. The response carries the new `PHPSESSID` back to the caller, who can then reuse it on every subsequent request to act as the targeted user. The Meet shared secret is `md5($global[\u0027systemRootPath\u0027] . $global[\u0027salt\u0027] . \"meet\")` (`Meet.php:73`), so any attacker who can read `videos/configuration.php` (e.g., via a path-traversal CVE such as `GHSA-83xq-8jxj-4rxm` or `GHSA-4wmm-6qxj-fpj4` that the project has already addressed in this surface area) can compute the Meet secret deterministically and pivot to full account takeover.\n\n## Affected Code\n\n**File:** `plugin/Meet/uploadRecordedVideo.json.php`, lines 33-73.\n\n```php\nif (empty($token)) {\n forbiddenPage(\u0027Token not found\u0027);\n}\n\n$objM = AVideoPlugin::getObjectDataIfEnabled(\"Meet\");\nif (empty($objM)) {\n forbiddenPage(\u0027Plugin disabled\u0027);\n}\n\nif ($objM-\u003esecret != $token) { // \u003c-- shared-secret auth, no per-user proof\n forbiddenPage(\u0027Token does not match\u0027);\n}\n\nif (empty($_FILES[\u0027upl\u0027])) {\n forbiddenPage(\u0027videoFile not found\u0027);\n}\n\n$users_id = explode(\u0027-\u0027, $_FILES[\u0027upl\u0027][\u0027name\u0027])[0]; // \u003c-- BUG: target users_id parsed from attacker-controlled filename\n\n$userObject = new User($users_id);\n$userObject-\u003elogin(true, true); // \u003c-- BUG: passwordless login as the chosen user; sets $_SESSION + Set-Cookie\n$tmpFile = getTmpDir() . uniqid();\n\nif (move_uploaded_file($_FILES[\u0027upl\u0027][\u0027tmp_name\u0027], $tmpFile)) {\n $_FILES[\u0027upl\u0027][\u0027tmp_name\u0027] = $tmpFile;\n require $global[\u0027systemRootPath\u0027] . \u0027objects/aVideoQueueEncoder.json.php\u0027;\n}\n```\n\n**File:** `objects/user.php`, lines 1249-1329 (`User::login()` no-password branch).\n\n```php\npublic function login($noPass = false, $encodedPass = false, $ignoreEmailVerification = false)\n{\n // ...\n if ($noPass) {\n $user = $this-\u003efind($this-\u003euser, false, true); // \u003c-- no password check\n }\n // ...\n } elseif ($user) {\n $_SESSION[\u0027user\u0027] = $user; // \u003c-- session set for the impersonated user\n $this-\u003esetLastLogin($_SESSION[\u0027user\u0027][\u0027id\u0027]);\n // ...\n self::setUserCookie($rememberme, $user[\u0027id\u0027], $user[\u0027user\u0027], $passhash, $expires);\n AVideoPlugin::onUserSignIn($_SESSION[\u0027user\u0027][\u0027id\u0027]);\n $_SESSION[\u0027loginAttempts\u0027] = 0;\n _session_regenerate_id(); // \u003c-- new SID committed in Set-Cookie response\n _session_write_close();\n return self::USER_LOGGED;\n }\n}\n```\n\n**Why it\u0027s wrong:** the endpoint conflates two distinct authentication concerns. The shared-secret check answers \"is this request coming from a trusted Meet recorder?\" but the filename parse answers \"which user does this recording belong to?\" \u2014 and the second answer is taken from the same untrusted caller. Once `User-\u003elogin(true, true)` runs, the server has no way to distinguish a legitimate Meet integration from an attacker who happens to know the same secret. The decision to expose this as a session (cookie + `_session_regenerate_id`) rather than as a one-shot in-process credit makes the impact larger than it needs to be: even if the Meet integration only needed to *credit* the recording to a user, the implementation gives the caller a fully-authenticated session as that user.\n\n## Exploit Chain\n\n1. Attacker obtains the Meet shared secret. Two plausible paths:\n - **Path A** (computational): the secret is `md5($global[\u0027systemRootPath\u0027] . $global[\u0027salt\u0027] . \"meet\")` (`plugin/Meet/Meet.php:73`). Both inputs sit in `videos/configuration.php`. AVideo\u0027s history of LFI/path-traversal CVEs in this surface (e.g., the `import.json.php` and `listFiles.json.php` advisories already accepted on this program) means the salt is a realistic disclosure target.\n - **Path B** (timing oracle): `plugin/Meet/checkToken.json.php` line 26 does `if ($objM-\u003esecret === $_GET[\u0027secret\u0027])` with no constant-time comparison and a clear yes/no response body. PHP\u0027s `===` for strings short-circuits on first byte mismatch, so an attacker on the same network segment can recover the 32-hex secret byte-by-byte over the network with timing analysis. Slower than path A but doesn\u0027t depend on a separate vulnerability.\n2. Attacker prepares an HTTP POST to `/plugin/Meet/uploadRecordedVideo.json.php`:\n - `Authorization: Bearer \u003cMeet secret\u003e`\n - Multipart body with one file field named `upl`. The filename is set to `1-anything.mp4` (where `1` is the `users_id` of the admin or any target user \u2014 the format is `\u003cusers_id\u003e-\u003carbitrary\u003e`). The file body itself can be anything that survives the surrounding aVideoQueueEncoder pipeline (an empty file is enough to reach the login call before the encoder rejects).\n3. Server flow:\n - Line 33: token present, ok.\n - Line 46: `$objM-\u003esecret != $token` \u2192 false (matches), passes.\n - Line 51: `$_FILES[\u0027upl\u0027]` present, ok.\n - Line 56: `$users_id = explode(\u0027-\u0027, \u00271-anything.mp4\u0027)[0]` \u2192 `\u00271\u0027`.\n - Line 59-60: `$userObject = new User(1); $userObject-\u003elogin(true, true);` \u2014 passwordless login as user 1 (admin). `$_SESSION[\u0027user\u0027]` is set, `setUserCookie` runs, `_session_regenerate_id` issues a new session ID, and the response carries `Set-Cookie: PHPSESSID=\u003cnew-sid\u003e; ...`.\n - Subsequent code runs the encoder pipeline as admin \u2014 but the attacker\u0027s primary goal was already achieved when the session was established.\n4. Attacker captures the `Set-Cookie: PHPSESSID=...` header from the response and uses that cookie on all subsequent requests. Server treats them as user 1 (admin) \u2014 full UI access, all admin endpoints, all video management, plugin configuration, user impersonation, etc.\n5. Final state: admin account takeover. The original Meet recorder\u0027s flow (legitimate uploads with `users_id` = the user who scheduled the meeting) is indistinguishable on the wire from the attack flow (`users_id` = whoever the attacker wants to be).\n\n## Security Impact\n\n**Severity:** sec-high. End state is full account takeover of any user (including admin), reachable from a single HTTP POST once the secret is known. The shared-secret precondition raises AC to High but does not eliminate it as a credible threat \u2014 the secret is computable from any leak of `videos/configuration.php`, and AVideo\u0027s CVE history in that surface area is non-trivial.\n**Attacker capability:** session hijack as any `users_id` the attacker cares to name. The attacker chooses the target by setting the filename\u0027s leading digits before the first `-`. No bound on which user IDs are reachable; admin (`1` on a default install) is the obvious target. Once the session is captured, the attacker has full admin UI/API access for the session lifetime (hours-to-days depending on `rememberme` flag).\n**Preconditions:** Meet plugin enabled (default-off but commonly enabled by deployments using AVideo for video-conferencing recording). Knowledge of the Meet shared secret (computable from the salt; obtainable via timing attack on `checkToken.json.php`).\n**Differential:** source-inspection-verified end-to-end. The two relevant code blocks are quoted verbatim in \u00a7Affected Code; both lines are reachable on every successful POST to the endpoint. The patched build (with the suggested fix below) either rejects the upload as `\u0027cannot derive identity from filename\u0027` or constrains the `users_id` to one bound by an additional signed claim from the Meet recorder.\n\n## Suggested Fix\n\nThree changes, in order of importance:\n\n```diff\n--- a/plugin/Meet/uploadRecordedVideo.json.php\n+++ b/plugin/Meet/uploadRecordedVideo.json.php\n@@ -53,17 +53,28 @@ if (empty($_FILES[\u0027upl\u0027])) {\n forbiddenPage(\u0027videoFile not found\u0027);\n }\n\n-$users_id = explode(\u0027-\u0027, $_FILES[\u0027upl\u0027][\u0027name\u0027])[0];\n+// The users_id MUST come from a signed claim (e.g., a JWT issued by AVideo\n+// when the meeting was scheduled), not from a filename the caller controls.\n+// Verify a recording-upload token here that was minted at meeting-create\n+// time and bound to (meet_schedule_id, users_id) with an HMAC.\n+$claim = MeetUploadClaim::verifyFromHeaders($headers);\n+if (!$claim) {\n+ forbiddenPage(\u0027Missing or invalid recording upload claim\u0027);\n+}\n+$users_id = (int) $claim-\u003eusers_id;\n+if (!$users_id || !User::idExists($users_id)) {\n+ forbiddenPage(\u0027Recording upload claim references unknown user\u0027);\n+}\n\n-$userObject = new User($users_id);\n-$userObject-\u003elogin(true, true);\n+// Credit the upload to $users_id WITHOUT establishing a session. The encoder\n+// pipeline can be parameterised to record ownership directly; there is no\n+// reason for a service-to-service upload endpoint to mint a user session.\n+$queueOwnerUsersId = $users_id;\n $tmpFile = getTmpDir() . uniqid();\n\n if (move_uploaded_file($_FILES[\u0027upl\u0027][\u0027tmp_name\u0027], $tmpFile)) {\n $_FILES[\u0027upl\u0027][\u0027tmp_name\u0027] = $tmpFile;\n- require $global[\u0027systemRootPath\u0027] . \u0027objects/aVideoQueueEncoder.json.php\u0027;\n+ aVideoQueueEncoder::encodeOnBehalfOf($queueOwnerUsersId, $_FILES[\u0027upl\u0027]);\n }\n```\n\nAdditionally:\n\n1. **Use `hash_equals` for the secret comparison** in both this endpoint and `checkToken.json.php` (`if (!hash_equals($objM-\u003esecret, $token))`). The current `==`/`===` is vulnerable to byte-by-byte timing analysis.\n2. **Remove `checkToken.json.php` entirely**, or at least gate it behind `User::isAdmin()`. A network-reachable endpoint that confirms whether a guess matches the server-side secret is exactly the wrong shape for a high-value secret like this one.\n\nOptional defense-in-depth (separate change): rotate the Meet secret to use a random 256-bit value (not derived from `salt`), so a `videos/configuration.php` disclosure does not also yield the Meet secret. Store the random secret as a per-deployment row in the Meet plugin\u0027s configuration table, generated at first-run.\n\nAdd a regression test: call `uploadRecordedVideo.json.php` with the correct secret but a filename of `1-x.mp4`; assert the response does NOT include a `Set-Cookie: PHPSESSID=` header.",
"id": "GHSA-qxvm-r42f-5p8j",
"modified": "2026-05-15T18:17:19Z",
"published": "2026-05-15T18:17:19Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/WWBN/AVideo/security/advisories/GHSA-qxvm-r42f-5p8j"
},
{
"type": "PACKAGE",
"url": "https://github.com/WWBN/AVideo"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "AVideo\u0027s Meet plugin: `uploadRecordedVideo.json.php` derives `users_id` from the uploaded filename and calls passwordless `User-\u003elogin()`, allowing any caller with the Meet shared secret to obtain a session as arbitrary users including admin"
}
GHSA-R223-2773-WQ4W
Vulnerability from github – Published: 2026-10-06 21:32 – Updated: 2026-10-06 21:32Authorization bypass through a user-controlled key in the optional Amazon Q Business Lambda hook sample ( q-business-lambda-hook https://github.com/aws-solutions-library-samples/qnabot-on-aws/blob/main/source/docs/lambda_hooks/README.md ), available with QnABot on AWS versions 7.0.0 through 7.4.5, might allow an authenticated remote user to read arbitrary Amazon S3 objects in the deploying AWS account. This sample solution provides an example Lambda hook and requires separate, manual deployment and additional setup. It is not deployed automatically with QnABot. Customers who have not deployed this optional sample hook are not affected and do not need to take action.
To remediate this issue, affected customers should update the QnABot on AWS stack to version 7.4.6 or later and then redeploy the Amazon Q Business Lambda hook sample stack. Updating the QnABot on AWS stack alone does not deliver the fix.
{
"affected": [],
"aliases": [
"CVE-2026-105811"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-10-06T21:17:04Z",
"severity": "HIGH"
},
"details": "Authorization bypass through a user-controlled key in the optional Amazon Q Business Lambda hook sample ( q-business-lambda-hook https://github.com/aws-solutions-library-samples/qnabot-on-aws/blob/main/source/docs/lambda_hooks/README.md ), available with QnABot on AWS versions 7.0.0 through 7.4.5, might allow an authenticated remote user to read arbitrary Amazon S3 objects in the deploying AWS account. This sample solution provides an example Lambda hook and requires separate, manual deployment and additional setup. It is not deployed automatically with QnABot. Customers who have not deployed this optional sample hook are not affected and do not need to take action. \n\n\n\nTo remediate this issue, affected customers should update the QnABot on AWS stack to version 7.4.6 or later and then redeploy the Amazon Q Business Lambda hook sample stack. Updating the QnABot on AWS stack alone does not deliver the fix.",
"id": "GHSA-r223-2773-wq4w",
"modified": "2026-10-06T21:32:03Z",
"published": "2026-10-06T21:32:03Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-105811"
},
{
"type": "WEB",
"url": "https://github.com/aws-solutions-library-samples/qnabot-on-aws/releases/tag/v7.4.6"
},
{
"type": "WEB",
"url": "https://staging.prod.website.marketing.aws.dev/security/security-bulletins/2026-126-aws"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-R29W-MCFC-R8CC
Vulnerability from github – Published: 2024-09-06 09:32 – Updated: 2024-09-06 09:32The WP-Recall – Registration, Profile, Commerce & More plugin for WordPress is vulnerable to privilege escalation/account takeover in all versions up to, and including, 16.26.8. This is due to to plugin not properly verifying a user's identity during new order creation. This makes it possible for unauthenticated attackers to supply any email through the user_email field and update the password for that user during new order creation. This requires the commerce addon to be enabled in order to exploit.
{
"affected": [],
"aliases": [
"CVE-2024-8292"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-09-06T07:15:03Z",
"severity": "CRITICAL"
},
"details": "The WP-Recall \u2013 Registration, Profile, Commerce \u0026 More plugin for WordPress is vulnerable to privilege escalation/account takeover in all versions up to, and including, 16.26.8. This is due to to plugin not properly verifying a user\u0027s identity during new order creation. This makes it possible for unauthenticated attackers to supply any email through the user_email field and update the password for that user during new order creation. This requires the commerce addon to be enabled in order to exploit.",
"id": "GHSA-r29w-mcfc-r8cc",
"modified": "2024-09-06T09:32:30Z",
"published": "2024-09-06T09:32:30Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-8292"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/wp-recall/tags/16.26.8/add-on/commerce/classes/class-rcl-create-order.php#L127"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/wp-recall/tags/16.26.8/add-on/commerce/functions-frontend.php#L113"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/wp-recall/tags/16.26.8/rcl-functions.php#L1339"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset/3145798/wp-recall/trunk/add-on/commerce/classes/class-rcl-create-order.php"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/8fa4b5df-dc71-49de-880b-895eb1d9cdca?source=cve"
}
],
"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"
}
]
}
Mitigation
For each and every data access, ensure that the user has sufficient privilege to access the record that is being requested.
Mitigation
Make sure that the key that is used in the lookup of a specific user's record is not controllable externally by the user or that any tampering can be detected.
Mitigation
Use encryption in order to make it more difficult to guess other legitimate values of the key or associate a digital signature with the key so that the server can verify that there has been no tampering.
No CAPEC attack patterns related to this CWE.