CVE-2026-77425
Unleash: A project member can reorder activation strategies belonging to any other project / environment (cross-project integrity write), bypassing project RBAC and the audit log
Unleash is an open-source feature management platform. Prior to 8.0.3, POST /api/admin/projects/:projectId/features/:featureName/environments/:environment/strategies/set-sort-order passes attacker-controlled strategy IDs to unprotectedUpdateStrategiesSortOrder and updateSortOrder without verifying that the IDs belong to the project, feature, and environment authorized by the URL. In a multi-project Pro or Enterprise deployment, an authenticated user with UPDATE_FEATURE_STRATEGY in one project who knows another project's strategy IDs can reorder those strategies, changing feature evaluation precedence while the operation is attributed to the attacker's URL context rather than the affected project. The single-project OSS edition lacks the cross-project dimension, although the missing context binding still permits unauthorized reordering across features or environments in the default project. The endpoint changes only sort_order and does not modify strategy parameters, constraints, or segments. This issue is fixed in version 8.0.3.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
4.3
Unleash: A project member can reorder activation strategies belonging to any other project / environment (cross-project integrity write), bypassing project RBAC and the audit log
Unleash is an open-source feature management platform. Prior to 8.0.3, POST /api/admin/projects/:projectId/features/:featureName/environments/:environment/strategies/set-sort-order passes attacker-controlled strategy IDs to unprotectedUpdateStrategiesSortOrder and updateSortOrder without verifying that the IDs belong to the project, feature, and environment authorized by the URL. In a multi-project Pro or Enterprise deployment, an authenticated user with UPDATE_FEATURE_STRATEGY in one project who knows another project's strategy IDs can reorder those strategies, changing feature evaluation precedence while the operation is attributed to the attacker's URL context rather than the affected project. The single-project OSS edition lacks the cross-project dimension, although the missing context binding still permits unauthorized reordering across features or environments in the default project. The endpoint changes only sort_order and does not modify strategy parameters, constraints, or segments. This issue is fixed in version 8.0.3.
- Record
CVE-2026-77425- CVSS 3.1
- 4.3 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-639, CWE-863
- Updated
- 2026-11-02
EUVDEUVD-2026-84865
4.3
Unleash is an open-source feature management platform. Prior to 8.0.3, POST /api/admin/projects/:projectId/features/:featureName/environments/:environment/strategies/set-sort-order passes attacker-controlled strategy IDs to unprotectedUpdateStrategiesSortOrder and updateSortOrder without verifying that the IDs belong to the project, feature, and environment authorized by the URL. In a multi-project Pro or Enterprise deployment, an authenticated user with UPDATE_FEATURE_STRATEGY in one project who knows another project's strategy IDs can reorder those strategies, changing feature evaluation precedence while the operation is attributed to the attacker's URL context rather than the affected project. The single-project OSS edition lacks the cross-project dimension, although the missing context binding still permits unauthorized reordering across features or environments in the default project. The endpoint changes only sort_order and does not modify strategy parameters, constraints, or segments. This issue is fixed in version 8.0.3.
- Record
EUVD-2026-84865- CVSS 3.1
- 4.3 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-5ffh-6f9q-5hhr
4.3
Unleash: A project member can reorder activation strategies belonging to any other project / environment (cross-project integrity write), bypassing project RBAC and the audit log
Summary
Unleash scopes write permissions per project and per environment: a user with the UPDATE_FEATURE_STRATEGY permission on project A is supposed to be able to mutate activation strategies only within project A. The endpoint POST /api/admin/projects/:projectId/features/:featureName/environments/:environment/strategies/set-sort-order violates this. The RBAC middleware authorizes the request against the :projectId taken from the URL, but the handler then writes the strategy IDs supplied in the request body directly to the database by primary key, without ever verifying that those strategy IDs actually belong to the URL's project / feature / environment. A low-privilege member of any one project can therefore reorder the activation strategies of features in any other project and environment — including projects they have no role on at all — by putting their own project in the URL (to satisfy RBAC) and the victim project's strategy IDs in the body.
The sibling write paths in the same service (updateStrategy, patchStrategy, deleteStrategy) all call validateUpdatedProperties(), which rejects a strategy whose stored projectId/featureName does not match the URL context. The set-sort-order handler is the one sibling that omits this check — an asymmetric, incomplete enforcement. Activation-strategy ordering is security-relevant: the first matching strategy determines a flag's rollout/variant outcome, so an attacker can flip which strategy "wins" for another team's feature flag in production. As a secondary effect, the operation that mutates the victim's strategies is recorded (if at all) under the attacker's project/feature context, so the tampering does not appear in the victim project's audit trail.
Affected code (v8.0.0)
The route is registered with the project-scoped permission UPDATE_FEATURE_STRATEGY (correct), and the handler forwards the URL params as the "context" plus the raw request body:
src/lib/features/feature-toggle/feature-toggle-controller.ts
{
method: 'post',
path: `${PATH_STRATEGIES}/set-sort-order`,
handler: this.setStrategiesSortOrder,
permission: UPDATE_FEATURE_STRATEGY,
// ...
}
async setStrategiesSortOrder(req, res): Promise<void> {
const { featureName, projectId, environment } = req.params;
await this.transactionalFeatureToggleService.transactional((service) =>
service.updateStrategiesSortOrder(
{ featureName, environment, projectId }, // URL context only
req.body, // attacker-controlled [{id, sortOrder}]
req.audit,
),
);
res.status(200).send();
}
The service writes each body-supplied id directly. It reads the URL-context strategies only to build the audit-event payload (existingOrder/newOrder); it never validates that the IDs in sortOrders belong to that context:
src/lib/features/feature-toggle/feature-toggle-service.ts
async unprotectedUpdateStrategiesSortOrder(context, sortOrders, auditUser): Promise<Saved<any>> {
const { featureName, environment, projectId: project } = context;
const existingOrder = (await this.getStrategiesForEnvironment(project, featureName, environment))
.sort(sortStrategies).map((s) => s.id);
// ...
await Promise.all(
sortOrders.map(({ id, sortOrder }) =>
this.featureStrategiesStore.updateSortOrder(id, sortOrder), // NO project/feature/env check
),
);
// ...event built from the URL context, not from the strategies actually mutated...
}
The store updates by primary key with no scoping predicate:
src/lib/features/feature-toggle/feature-toggle-strategies-store.ts
async updateSortOrder(id: string, sortOrder: number): Promise<void> {
await this.db<IFeatureStrategiesTable>(T.featureStrategies)
.where({ id })
.update({ sort_order: sortOrder });
}
Contrast the sibling mutators, which DO…
- Record
GHSA-5ffh-6f9q-5hhr- CVSS 3.1
- 4.3 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-639, CWE-863
- Updated
- 2026-11-02
NVD
4.3
Unleash is an open-source feature management platform. Prior to 8.0.3, POST /api/admin/projects/:projectId/features/:featureName/environments/:environment/strategies/set-sort-order passes attacker-controlled strategy IDs to unprotectedUpdateStrategiesSortOrder and updateSortOrder without verifying that the IDs belong to the project, feature, and environment authorized by the URL. In a multi-project Pro or Enterprise deployment, an authenticated user with UPDATE_FEATURE_STRATEGY in one project who knows another project's strategy IDs can reorder those strategies, changing feature evaluation precedence while the operation is attributed to the attacker's URL context rather than the affected project. The single-project OSS edition lacks the cross-project dimension, although the missing context binding still permits unauthorized reordering across features or environments in the default project. The endpoint changes only sort_order and does not modify strategy parameters, constraints, or segments. This issue is fixed in version 8.0.3.
- Record
CVE-2026-77425- CVSS 3.1
- 4.3 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-639, CWE-863
- Updated
- 2026-11-02
OSV
4.3
Unleash: A project member can reorder activation strategies belonging to any other project / environment (cross-project integrity write), bypassing project RBAC and the audit log
Unleash is an open-source feature management platform. Prior to 8.0.3, POST /api/admin/projects/:projectId/features/:featureName/environments/:environment/strategies/set-sort-order passes attacker-controlled strategy IDs to unprotectedUpdateStrategiesSortOrder and updateSortOrder without verifying that the IDs belong to the project, feature, and environment authorized by the URL. In a multi-project Pro or Enterprise deployment, an authenticated user with UPDATE_FEATURE_STRATEGY in one project who knows another project's strategy IDs can reorder those strategies, changing feature evaluation precedence while the operation is attributed to the attacker's URL context rather than the affected project. The single-project OSS edition lacks the cross-project dimension, although the missing context binding still permits unauthorized reordering across features or environments in the default project. The endpoint changes only sort_order and does not modify strategy parameters, constraints, or segments. This issue is fixed in version 8.0.3.
- Record
CVE-2026-77425- CVSS 3.1
- 4.3 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-639, CWE-863
- Updated
- 2026-11-02
OSVGHSA-5ffh-6f9q-5hhr
4.3
Unleash: A project member can reorder activation strategies belonging to any other project / environment (cross-project integrity write), bypassing project RBAC and the audit log
Summary
Unleash scopes write permissions per project and per environment: a user with the UPDATE_FEATURE_STRATEGY permission on project A is supposed to be able to mutate activation strategies only within project A. The endpoint POST /api/admin/projects/:projectId/features/:featureName/environments/:environment/strategies/set-sort-order violates this. The RBAC middleware authorizes the request against the :projectId taken from the URL, but the handler then writes the strategy IDs supplied in the request body directly to the database by primary key, without ever verifying that those strategy IDs actually belong to the URL's project / feature / environment. A low-privilege member of any one project can therefore reorder the activation strategies of features in any other project and environment — including projects they have no role on at all — by putting their own project in the URL (to satisfy RBAC) and the victim project's strategy IDs in the body.
The sibling write paths in the same service (updateStrategy, patchStrategy, deleteStrategy) all call validateUpdatedProperties(), which rejects a strategy whose stored projectId/featureName does not match the URL context. The set-sort-order handler is the one sibling that omits this check — an asymmetric, incomplete enforcement. Activation-strategy ordering is security-relevant: the first matching strategy determines a flag's rollout/variant outcome, so an attacker can flip which strategy "wins" for another team's feature flag in production. As a secondary effect, the operation that mutates the victim's strategies is recorded (if at all) under the attacker's project/feature context, so the tampering does not appear in the victim project's audit trail.
Affected code (v8.0.0)
The route is registered with the project-scoped permission UPDATE_FEATURE_STRATEGY (correct), and the handler forwards the URL params as the "context" plus the raw request body:
src/lib/features/feature-toggle/feature-toggle-controller.ts
{
method: 'post',
path: `${PATH_STRATEGIES}/set-sort-order`,
handler: this.setStrategiesSortOrder,
permission: UPDATE_FEATURE_STRATEGY,
// ...
}
async setStrategiesSortOrder(req, res): Promise<void> {
const { featureName, projectId, environment } = req.params;
await this.transactionalFeatureToggleService.transactional((service) =>
service.updateStrategiesSortOrder(
{ featureName, environment, projectId }, // URL context only
req.body, // attacker-controlled [{id, sortOrder}]
req.audit,
),
);
res.status(200).send();
}
The service writes each body-supplied id directly. It reads the URL-context strategies only to build the audit-event payload (existingOrder/newOrder); it never validates that the IDs in sortOrders belong to that context:
src/lib/features/feature-toggle/feature-toggle-service.ts
async unprotectedUpdateStrategiesSortOrder(context, sortOrders, auditUser): Promise<Saved<any>> {
const { featureName, environment, projectId: project } = context;
const existingOrder = (await this.getStrategiesForEnvironment(project, featureName, environment))
.sort(sortStrategies).map((s) => s.id);
// ...
await Promise.all(
sortOrders.map(({ id, sortOrder }) =>
this.featureStrategiesStore.updateSortOrder(id, sortOrder), // NO project/feature/env check
),
);
// ...event built from the URL context, not from the strategies actually mutated...
}
The store updates by primary key with no scoping predicate:
src/lib/features/feature-toggle/feature-toggle-strategies-store.ts
async updateSortOrder(id: string, sortOrder: number): Promise<void> {
await this.db<IFeatureStrategiesTable>(T.featureStrategies)
.where({ id })
.update({ sort_order: sortOrder });
}
Contrast the sibling mutators, which DO…
- Record
GHSA-5ffh-6f9q-5hhr- CVSS 3.1
- 4.3 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-639, CWE-863
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
unleash-servernpm |
before 8.0.3 | 8.0.3 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-77425 is a medium vulnerability (CVSS 4.3) in Unleash, published September 22, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.33%, the 25th percentile. Fixed in unleash-server 8.0.3.
References
github.com/Unleash/unleash/security/advisories/GHSA-5ffh-6f9q-5hhr
github.com/Unleash/unleash/commit/43e8db37b846921c8a94db58b44935ecbd15d9d1
github.com/Unleash/unleash/releases/tag/v8.0.3
github.com/advisories/GHSA-5ffh-6f9q-5hhr
github.com/CVEProject/cvelistV5/tree/main/cves/2026/77xxx/CVE-2026-77425.json
nvd.nist.gov/vuln/detail/CVE-2026-77425
github.com/Unleash/unleash
Left out here: the rest of 2 source descriptions. The JSON record has them.