Common Weakness Enumeration

CWE-863

Allowed-with-Review

Incorrect Authorization

Abstraction: Class · Status: Incomplete

The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check.

7160 vulnerabilities reference this CWE, most recent first.

GHSA-RX28-R23P-2QC3

Vulnerability from github – Published: 2023-06-19 22:47 – Updated: 2023-06-20 18:06
VLAI
Summary
AWS CDK EKS overly permissive trust policies
Details

If you are using the eks.Cluster or eks.FargateCluster construct we need you to take action. Other users are not affected and can stop reading.

Impact

The AWS Cloud Development Kit (CDK) allows for the definition of Amazon Elastic Container Service for Kubernetes (EKS) clusters. eks.Cluster and eks.FargateCluster constructs create two roles that have an overly permissive trust policy.

The first, referred to as the CreationRole, is used by lambda handlers to create the cluster and deploy Kubernetes resources (e.g KubernetesManifest, HelmChart, ...) onto it. Users with CDK version higher or equal to 1.62.0 (including v2 users) will be affected.

The second, referred to as the default MastersRole, is provisioned only if the mastersRole property isn't provided and has permissions to execute kubectl commands on the cluster. Users with CDK version higher or equal to 1.57.0 (including v2 users) will be affected.

Both these roles use the account root principal in their trust policy, which allows any identity in the account with the appropriate sts:AssumeRolepermissions to assume it. For example, this can happen if another role in your account has sts:AssumeRole permissions on Resource: "*".

CreationRole

Users with CDK version higher or equal to 1.62.0 (including v2 users). The role in question can be located in the IAM console. It will have the following name pattern:

*-ClusterCreationRole-* 

MastersRole

Users with CDK version higher or equal to 1.57.0 (including v2 users) that are not specifying the mastersRole property. The role in question can be located in the IAM console. It will have the following name pattern:

*-MastersRole-*

Patches

The issue has been fixed in versions v1.202.0, v2.80.0. We recommend you upgrade to a fixed version as soon as possible. See Managing Dependencies in the CDK Developer Guide for instructions on how to do this.

The new versions no longer use the account root principal. Instead, they restrict the trust policy to the specific roles of lambda handlers that need it. This introduces some breaking changes that might require you to perform code changes. Refer to https://github.com/aws/aws-cdk/issues/25674 for a detailed discussion of options.

Workarounds

CreationRole

There is no workaround available for CreationRole.

MastersRole

To avoid creating the default MastersRole, use the mastersRole property to explicitly provide a role. For example:

new eks.Cluster(this, 'Cluster', { 
  ... 
  mastersRole: iam.Role.fromRoleArn(this, 'Admin', 'arn:aws:iam::xxx:role/Admin') 
}); 

References

https://github.com/aws/aws-cdk/issues/25674

If you have any questions or comments about this advisory we ask that you contact AWS/Amazon Security via our vulnerability reporting page or directly via email to aws-security@amazon.com. Please do not create a public GitHub issue.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "aws-cdk-lib"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.0.0"
            },
            {
              "fixed": "2.80.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "@aws-cdk/aws-eks"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.57.0"
            },
            {
              "fixed": "1.202.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2023-35165"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-266",
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2023-06-19T22:47:26Z",
    "nvd_published_at": "2023-06-23T21:15:09Z",
    "severity": "MODERATE"
  },
  "details": "If you are using the `eks.Cluster` or `eks.FargateCluster` construct we need you to take action. Other users are not affected and can stop reading.\n\n### Impact \n\nThe AWS Cloud Development Kit (CDK) allows for the definition of Amazon Elastic Container Service for Kubernetes (EKS) clusters. `eks.Cluster` and `eks.FargateCluster` constructs create two roles that have an overly permissive trust policy. \n \nThe first, referred to as the _CreationRole_, is used by lambda handlers to create the cluster and deploy Kubernetes resources (e.g `KubernetesManifest`, `HelmChart`, ...) onto it. Users with CDK version higher or equal to  [1.62.0](https://github.com/aws/aws-cdk/releases/tag/v1.62.0) (including v2 users) will be affected.\n \nThe second, referred to as the _default MastersRole_, is provisioned only if the `mastersRole` property isn\u0027t provided and has permissions to execute `kubectl` commands on the cluster. Users with CDK version higher or equal to [1.57.0](https://github.com/aws/aws-cdk/releases/tag/v1.57.0) (including v2 users) will be affected.\n \nBoth these roles use the account root principal in their trust policy, which allows any identity in the account with the appropriate `sts:AssumeRole `permissions to assume it. For example, this can happen if another role in your account has `sts:AssumeRole` permissions on `Resource: \"*\"`.\n\n#### CreationRole \n\nUsers with CDK version higher or equal to [1.62.0](https://github.com/aws/aws-cdk/releases/tag/v1.62.0) (including v2 users). The role in question can be located in the IAM console. It will have the following name pattern: \n\n```console \n*-ClusterCreationRole-* \n```\n\n#### MastersRole \n\nUsers with CDK version higher or equal to [1.57.0](https://github.com/aws/aws-cdk/releases/tag/v1.57.0) (including v2 users) that are not specifying the `mastersRole` property. The role in question can be located in the IAM console. It will have the following name pattern: \n\n```console\n*-MastersRole-*\n```\n\n### Patches \n\nThe issue has been fixed in versions [v1.202.0](https://github.com/aws/aws-cdk/releases/tag/v1.202.0), [v2.80.0](https://github.com/aws/aws-cdk/releases/tag/v2.80.0). We recommend you upgrade to a fixed version as soon as possible. See [Managing Dependencies](https://docs.aws.amazon.com/cdk/v2/guide/manage-dependencies.html) in the CDK Developer Guide for instructions on how to do this.  \n \nThe new versions no longer use the account root principal. Instead, they restrict the trust policy to the specific roles of lambda handlers that need it. This introduces some breaking changes that might require you to perform code changes. Refer to https://github.com/aws/aws-cdk/issues/25674 for a detailed discussion of options. \n\n### Workarounds \n\n#### CreationRole \n\nThere is no workaround available for CreationRole. \n\n#### MastersRole \n\nTo avoid creating the _default MastersRole_, use the `mastersRole` property to explicitly provide a role. For example: \n\n```ts \nnew eks.Cluster(this, \u0027Cluster\u0027, { \n  ... \n  mastersRole: iam.Role.fromRoleArn(this, \u0027Admin\u0027, \u0027arn:aws:iam::xxx:role/Admin\u0027) \n}); \n```\n\n### References\n\n[https://github.com/aws/aws-cdk/issues/25674](https://github.com/aws/aws-cdk/issues/25674)\n\nIf you have any questions or comments about this advisory we ask that you contact AWS/Amazon Security via our [vulnerability reporting page](https://aws.amazon.com/security/vulnerability-reporting) or directly via email to [aws-security@amazon.com](mailto:aws-security@amazon.com). Please do not create a public GitHub issue.",
  "id": "GHSA-rx28-r23p-2qc3",
  "modified": "2023-06-20T18:06:03Z",
  "published": "2023-06-19T22:47:26Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/aws/aws-cdk/security/advisories/GHSA-rx28-r23p-2qc3"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-35165"
    },
    {
      "type": "WEB",
      "url": "https://github.com/aws/aws-cdk/issues/25674"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/aws/aws-cdk"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "AWS CDK EKS overly permissive trust policies"
}

GHSA-RX2M-34RG-7763

Vulnerability from github – Published: 2022-05-13 01:34 – Updated: 2022-05-13 01:34
VLAI
Details

Dell EMC iDRAC7/iDRAC8 versions prior to 2.61.60.60 and iDRAC9 versions prior to 3.20.21.20, 3.21.24.22, 3.21.26.22, and 3.23.23.23 contain a privilege escalation vulnerability. An authenticated malicious iDRAC user with operator privileges could potentially exploit a permissions check flaw in the Redfish interface to gain administrator access.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2018-15774"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2018-12-13T22:29:00Z",
    "severity": "HIGH"
  },
  "details": "Dell EMC iDRAC7/iDRAC8 versions prior to 2.61.60.60 and iDRAC9 versions prior to 3.20.21.20, 3.21.24.22, 3.21.26.22, and 3.23.23.23 contain a privilege escalation vulnerability. An authenticated malicious iDRAC user with operator privileges could potentially exploit a permissions check flaw in the Redfish interface to gain administrator access.",
  "id": "GHSA-rx2m-34rg-7763",
  "modified": "2022-05-13T01:34:08Z",
  "published": "2022-05-13T01:34:08Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-15774"
    },
    {
      "type": "WEB",
      "url": "https://www.dell.com/support/article/us/en/19/sln315190/dell-emc-idrac-multiple-vulnerabilities-cve-2018-15774-and-cve-2018-15776-?lang=en"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/106233"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-RX46-HFPW-4QH6

Vulnerability from github – Published: 2022-05-24 19:20 – Updated: 2022-05-24 19:20
VLAI
Details

Possible denial of service scenario can occur due to lack of length check on Channel Switch Announcement IE in beacon or probe response frame in Snapdragon Auto, Snapdragon Compute, Snapdragon Connectivity, Snapdragon Consumer Electronics Connectivity, Snapdragon Consumer IOT, Snapdragon Industrial IOT, Snapdragon Mobile, Snapdragon Voice & Music, Snapdragon Wired Infrastructure and Networking

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-1903"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-11-12T07:15:00Z",
    "severity": "MODERATE"
  },
  "details": "Possible denial of service scenario can occur due to lack of length check on Channel Switch Announcement IE in beacon or probe response frame in Snapdragon Auto, Snapdragon Compute, Snapdragon Connectivity, Snapdragon Consumer Electronics Connectivity, Snapdragon Consumer IOT, Snapdragon Industrial IOT, Snapdragon Mobile, Snapdragon Voice \u0026 Music, Snapdragon Wired Infrastructure and Networking",
  "id": "GHSA-rx46-hfpw-4qh6",
  "modified": "2022-05-24T19:20:35Z",
  "published": "2022-05-24T19:20:35Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-1903"
    },
    {
      "type": "WEB",
      "url": "https://www.qualcomm.com/company/product-security/bulletins/november-2021-bulletin"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-RX5V-PG4M-7R6R

Vulnerability from github – Published: 2026-09-17 15:32 – Updated: 2026-09-17 15:32
VLAI
Details

A flaw was found in the foreman_remote_execution plugin's template invocations controller. The show_template_invocation_by_host action resolves the job invocation by ID without evaluating the caller's view_job_invocations permission filter against the record. An authenticated user whose job invocation visibility is restricted by a permission filter can enumerate job invocation IDs and read the live output, rendered script, and input values for other users' job invocations within their own organizations.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-92904"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-17T13:17:00Z",
    "severity": "MODERATE"
  },
  "details": "A flaw was found in the foreman_remote_execution plugin\u0027s template invocations controller. The show_template_invocation_by_host action resolves the job invocation by ID without evaluating the caller\u0027s view_job_invocations permission filter against the record. An authenticated user whose job invocation visibility is restricted by a permission filter can enumerate job invocation IDs and read the live output, rendered script, and input values for other users\u0027 job invocations within their own organizations.",
  "id": "GHSA-rx5v-pg4m-7r6r",
  "modified": "2026-09-17T15:32:12Z",
  "published": "2026-09-17T15:32:12Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-92904"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/security/cve/CVE-2026-92904"
    },
    {
      "type": "WEB",
      "url": "https://bugzilla.redhat.com/show_bug.cgi?id=2535942"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-RX9X-86VG-H4CR

Vulnerability from github – Published: 2022-01-19 00:00 – Updated: 2022-07-13 00:01
VLAI
Details

An issue was discovered in Delta RM 1.2. The /risque/risque/workflow/reset endpoint is lacking access controls, and it is possible for an unprivileged user to reopen a risk with a POST request, using the risqueID parameter to identify the risk to be re-opened.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-44836"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-01-18T20:15:00Z",
    "severity": "MODERATE"
  },
  "details": "An issue was discovered in Delta RM 1.2. The /risque/risque/workflow/reset endpoint is lacking access controls, and it is possible for an unprivileged user to reopen a risk with a POST request, using the risqueID parameter to identify the risk to be re-opened.",
  "id": "GHSA-rx9x-86vg-h4cr",
  "modified": "2022-07-13T00:01:49Z",
  "published": "2022-01-19T00:00:53Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44836"
    },
    {
      "type": "WEB",
      "url": "https://gist.github.com/rntcruz23/01af412813c63d6e0cc41c26f52893be"
    },
    {
      "type": "WEB",
      "url": "https://www.deltarm.com"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-RXF6-WJH4-JFJ6

Vulnerability from github – Published: 2026-05-23 00:08 – Updated: 2026-06-26 21:28
VLAI
Summary
Nezha Monitoring: RoleMember can fire other users' cron tasks via AlertRule.FailTriggerTasks (no ownership check)
Details

Summary

createAlertRule and createService (and their update* siblings) accept FailTriggerTasks []uint64 and RecoverTriggerTasks []uint64 — IDs of cron tasks to fire when the alert/service trips. The validation function only validates the alert's Rules.Ignore server map; it never checks that the cron task IDs in FailTriggerTasks / RecoverTriggerTasks belong to the caller.

When the alert fires, singleton.CronShared.SendTriggerTasks(taskIDs, triggerServer) (service/singleton/crontask.go:113-127) looks up those task IDs in the global cron registry and executes them via CronTrigger. For non-AlertTrigger cover modes, CronTrigger fans the command out to every server in ServerShared.Range with no ownership check.

Net effect: a RoleMember can attach their alert rule (or service monitor) to another user's cron task ID — including admin's crons. When the alert trips, the admin's cron command runs across every server (or every server in its allow/deny list).

This is the same fanout/auth-bypass class as NEZHA-002 (cron creation), but reachable by a different code path: even if /cron writes are restricted to admin, this /alert-rule and /service writes are member-reachable and let a member invoke pre-existing admin crons.

Affected versions

Commit 50dc8e660326b9f22990898142c58b7a5312b42a and earlier on master.

Reachability chain

  1. POST /api/v1/alert-rule (or POST /api/v1/service) is commonHandler-gated — any authenticated user.
  2. createAlertRule / createService accepts FailTriggerTasks and RecoverTriggerTasks from the request body without validating ownership.
  3. validateRule (cmd/dashboard/controller/alertrule.go:169-196) only checks rule.Ignore server IDs — not the trigger task IDs.
  4. validateServers (cmd/dashboard/controller/service.go:543-549) only checks the service's SkipServers map — not the trigger task IDs.
  5. When the alert/service trips: service/singleton/alertsentinel.go:170, 180 and service/singleton/servicesentinel.go:747, 750 call CronShared.SendTriggerTasks(...).
  6. SendTriggerTasks (service/singleton/crontask.go:113-127) iterates the requested task IDs against c.list and calls CronTrigger(c, triggerServer)() for each — no ownership check.
  7. CronTrigger then fans the cron's Command to every connected agent (per Cover rules).

Code locations

// cmd/dashboard/controller/alertrule.go:47-77
func createAlertRule(c *gin.Context) (uint64, error) {
    var arf model.AlertRuleForm
    var r model.AlertRule
    if err := c.ShouldBindJSON(&arf); err != nil { return 0, err }
    uid := getUid(c)
    r.UserID = uid
    r.Name = arf.Name
    r.Rules = arf.Rules
    r.FailTriggerTasks = arf.FailTriggerTasks       // <-- attacker-controlled task IDs
    r.RecoverTriggerTasks = arf.RecoverTriggerTasks // <-- ditto
    r.NotificationGroupID = arf.NotificationGroupID
    enable := arf.Enable
    r.TriggerMode = arf.TriggerMode
    r.Enable = &enable

    if err := validateRule(c, &r); err != nil { return 0, err }   // only checks rule.Ignore servers
    ...
}
// cmd/dashboard/controller/alertrule.go:169-196
func validateRule(c *gin.Context, r *model.AlertRule) error {
    if len(r.Rules) > 0 {
        for _, rule := range r.Rules {
            if !singleton.ServerShared.CheckPermission(c, maps.Keys(rule.Ignore)) {
                return singleton.Localizer.ErrorT("permission denied")
            }
            // ... duration/cycle validation only
        }
    }
    // BUG: no check on r.FailTriggerTasks or r.RecoverTriggerTasks ownership.
    return nil
}
// service/singleton/crontask.go:113-127
func (c *CronClass) SendTriggerTasks(taskIDs []uint64, triggerServer uint64) {
    c.listMu.RLock()
    var cronLists []*model.Cron
    for _, taskID := range taskIDs {
        if c, ok := c.list[taskID]; ok {                 // <-- looks up ANY cron in global state
            cronLists = append(cronLists, c)
        }
    }
    c.listMu.RUnlock()
    // BUG: no ownership check between alert.UserID and cron.UserID before invoking.
    for _, c := range cronLists {
        go CronTrigger(c, triggerServer)()
    }
}
// service/singleton/crontask.go:138-181 — CronTrigger
return func() {
    if cr.Cover == model.CronCoverAlertTrigger {
        // alert-only: only sends to triggerServer (the member's server, when alert was triggered by it)
        if s, ok := ServerShared.Get(triggerServer[0]); ok && s.TaskStream != nil {
            s.TaskStream.Send(&pb.Task{Id: cr.ID, Data: cr.Command, Type: model.TaskTypeCommand})
        }
        return
    }
    // For Cover=CronCoverAll or CronCoverIgnoreAll: fan out to every server.
    for _, s := range ServerShared.Range {
        if cr.Cover == model.CronCoverAll && crIgnoreMap[s.ID] { continue }
        if cr.Cover == model.CronCoverIgnoreAll && !crIgnoreMap[s.ID] { continue }
        if s.TaskStream != nil {
            s.TaskStream.Send(&pb.Task{Id: cr.ID, Data: cr.Command, Type: model.TaskTypeCommand})
        }
    }
}

PoC

Pre-conditions: attacker has RoleMember credentials. Admin has at least one pre-existing cron with Cover=CronCoverAll or Cover=CronCoverIgnoreAll (i.e., a "run on all servers" maintenance cron — common in monitoring deployments).

Step 1: Enumerate admin cron IDs by ID-guessing. Try IDs 1..N; create AlertRule referencing each, see if the alert handler accepts.

Step 2: Create an alert rule referencing the admin's cron and pointed at an offline-trigger condition on the member's own server.

TOKEN=$(curl -sX POST -H 'Content-Type: application/json' \
    -d '{"username":"member","password":"hunter2"}' \
    http://nezha.example.com/api/v1/login | jq -r .token)

curl -sX POST -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
    -d '{"name":"trip","rules":[{"type":"offline","duration":3,"min":1.0,"cover":"member-server-id"}],"fail_trigger_tasks":[1,2,3,4,5],"recover_trigger_tasks":[],"notification_group_id":0,"trigger_mode":0,"enable":true}' \
    http://nezha.example.com/api/v1/alert-rule

Step 3: Stop the agent on the member's own server (or unplug it). The alert trips after duration seconds. SendTriggerTasks([1,2,3,4,5], member-server-id) runs.

Step 4: For each cron ID in the list, if that cron exists in the global registry and has Cover=CronCoverAll/IgnoreAll, its Command runs on every server.

The same chain works via POST /api/v1/service (service-monitor with fail_trigger_tasks).

Composability with NEZHA-002

If NEZHA-002 is unfixed, this chain is redundant — the member already has direct cron-create access. With NEZHA-002 fixed, this still gives the member a means to invoke any pre-existing admin cron with the member's chosen trigger condition. The fix surface is also independent (alertrule/service write paths, not /cron writes).

Suggested fix

In validateRule (and validateServers):

if !singleton.CronShared.CheckPermission(c, slices.Values(r.FailTriggerTasks)) {
    return singleton.Localizer.ErrorT("permission denied")
}
if !singleton.CronShared.CheckPermission(c, slices.Values(r.RecoverTriggerTasks)) {
    return singleton.Localizer.ErrorT("permission denied")
}

Defense-in-depth in SendTriggerTasks: enforce that task.UserID == alert.UserID || alertOwnerIsAdmin || taskOwnerIsAdmin.

Severity

  • PR:L because RoleMember credentials needed.
  • AC:H because attacker has to ID-guess admin cron IDs and have an alert-trip vector. (For a deployment where the attacker has visibility into max cron ID via UI hints or the id-query echo, AC drops to L.)
  • S:C because the cron command runs on every connected agent (different trust zone).
  • Auth: authenticated RoleMember.

Reproduction environment

  • Tested against: nezhahq/nezha master @ 50dc8e660326b9f22990898142c58b7a5312b42a.
  • Code locations:
  • cmd/dashboard/controller/alertrule.go:47-77 (createAlertRule), 91-131 (updateAlertRule), 169-196 (validateRule)
  • cmd/dashboard/controller/service.go:404-445 (createService), 459-509 (updateService), 543-549 (validateServers)
  • service/singleton/crontask.go:113-127 (SendTriggerTasks), 133-181 (CronTrigger)
  • service/singleton/alertsentinel.go:170, 180 (alert-fire callsite)
  • service/singleton/servicesentinel.go:742-750 (service-fire callsite)

Reporter

Eddie Ran. Filed via reporter API. Companion to NEZHA-001/002 — same auth-bypass class but a different write path.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/nezhahq/nezha"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.4.0"
            },
            {
              "fixed": "1.14.15-0.20260517022419-d7526351cf97"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-47120"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-862",
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-23T00:08:45Z",
    "nvd_published_at": "2026-06-12T22:16:51Z",
    "severity": "MODERATE"
  },
  "details": "## Summary\n\n`createAlertRule` and `createService` (and their `update*` siblings) accept `FailTriggerTasks []uint64` and `RecoverTriggerTasks []uint64` \u2014 IDs of cron tasks to fire when the alert/service trips. The validation function only validates the alert\u0027s `Rules.Ignore` server map; it never checks that the cron task IDs in `FailTriggerTasks` / `RecoverTriggerTasks` belong to the caller.\n\nWhen the alert fires, `singleton.CronShared.SendTriggerTasks(taskIDs, triggerServer)` (`service/singleton/crontask.go:113-127`) looks up those task IDs in the global cron registry and executes them via `CronTrigger`. For non-`AlertTrigger` cover modes, `CronTrigger` fans the command out to every server in `ServerShared.Range` with no ownership check.\n\nNet effect: a `RoleMember` can attach their alert rule (or service monitor) to **another user\u0027s** cron task ID \u2014 including admin\u0027s crons. When the alert trips, the admin\u0027s cron command runs across every server (or every server in its allow/deny list).\n\nThis is the same fanout/auth-bypass class as `NEZHA-002` (cron creation), but reachable by a different code path: even if `/cron` writes are restricted to admin, this `/alert-rule` and `/service` writes are member-reachable and let a member invoke pre-existing admin crons.\n\n## Affected versions\n\nCommit `50dc8e660326b9f22990898142c58b7a5312b42a` and earlier on `master`.\n\n## Reachability chain\n\n1. `POST /api/v1/alert-rule` (or `POST /api/v1/service`) is `commonHandler`-gated \u2014 any authenticated user.\n2. `createAlertRule` / `createService` accepts `FailTriggerTasks` and `RecoverTriggerTasks` from the request body without validating ownership.\n3. `validateRule` (`cmd/dashboard/controller/alertrule.go:169-196`) only checks `rule.Ignore` server IDs \u2014 not the trigger task IDs.\n4. `validateServers` (`cmd/dashboard/controller/service.go:543-549`) only checks the service\u0027s `SkipServers` map \u2014 not the trigger task IDs.\n5. When the alert/service trips: `service/singleton/alertsentinel.go:170, 180` and `service/singleton/servicesentinel.go:747, 750` call `CronShared.SendTriggerTasks(...)`.\n6. `SendTriggerTasks` (`service/singleton/crontask.go:113-127`) iterates the requested task IDs against `c.list` and calls `CronTrigger(c, triggerServer)()` for each \u2014 no ownership check.\n7. `CronTrigger` then fans the cron\u0027s `Command` to every connected agent (per `Cover` rules).\n\n## Code locations\n\n```go\n// cmd/dashboard/controller/alertrule.go:47-77\nfunc createAlertRule(c *gin.Context) (uint64, error) {\n    var arf model.AlertRuleForm\n    var r model.AlertRule\n    if err := c.ShouldBindJSON(\u0026arf); err != nil { return 0, err }\n    uid := getUid(c)\n    r.UserID = uid\n    r.Name = arf.Name\n    r.Rules = arf.Rules\n    r.FailTriggerTasks = arf.FailTriggerTasks       // \u003c-- attacker-controlled task IDs\n    r.RecoverTriggerTasks = arf.RecoverTriggerTasks // \u003c-- ditto\n    r.NotificationGroupID = arf.NotificationGroupID\n    enable := arf.Enable\n    r.TriggerMode = arf.TriggerMode\n    r.Enable = \u0026enable\n\n    if err := validateRule(c, \u0026r); err != nil { return 0, err }   // only checks rule.Ignore servers\n    ...\n}\n```\n\n```go\n// cmd/dashboard/controller/alertrule.go:169-196\nfunc validateRule(c *gin.Context, r *model.AlertRule) error {\n    if len(r.Rules) \u003e 0 {\n        for _, rule := range r.Rules {\n            if !singleton.ServerShared.CheckPermission(c, maps.Keys(rule.Ignore)) {\n                return singleton.Localizer.ErrorT(\"permission denied\")\n            }\n            // ... duration/cycle validation only\n        }\n    }\n    // BUG: no check on r.FailTriggerTasks or r.RecoverTriggerTasks ownership.\n    return nil\n}\n```\n\n```go\n// service/singleton/crontask.go:113-127\nfunc (c *CronClass) SendTriggerTasks(taskIDs []uint64, triggerServer uint64) {\n    c.listMu.RLock()\n    var cronLists []*model.Cron\n    for _, taskID := range taskIDs {\n        if c, ok := c.list[taskID]; ok {                 // \u003c-- looks up ANY cron in global state\n            cronLists = append(cronLists, c)\n        }\n    }\n    c.listMu.RUnlock()\n    // BUG: no ownership check between alert.UserID and cron.UserID before invoking.\n    for _, c := range cronLists {\n        go CronTrigger(c, triggerServer)()\n    }\n}\n```\n\n```go\n// service/singleton/crontask.go:138-181 \u2014 CronTrigger\nreturn func() {\n    if cr.Cover == model.CronCoverAlertTrigger {\n        // alert-only: only sends to triggerServer (the member\u0027s server, when alert was triggered by it)\n        if s, ok := ServerShared.Get(triggerServer[0]); ok \u0026\u0026 s.TaskStream != nil {\n            s.TaskStream.Send(\u0026pb.Task{Id: cr.ID, Data: cr.Command, Type: model.TaskTypeCommand})\n        }\n        return\n    }\n    // For Cover=CronCoverAll or CronCoverIgnoreAll: fan out to every server.\n    for _, s := range ServerShared.Range {\n        if cr.Cover == model.CronCoverAll \u0026\u0026 crIgnoreMap[s.ID] { continue }\n        if cr.Cover == model.CronCoverIgnoreAll \u0026\u0026 !crIgnoreMap[s.ID] { continue }\n        if s.TaskStream != nil {\n            s.TaskStream.Send(\u0026pb.Task{Id: cr.ID, Data: cr.Command, Type: model.TaskTypeCommand})\n        }\n    }\n}\n```\n\n## PoC\n\nPre-conditions: attacker has `RoleMember` credentials. Admin has at least one pre-existing cron with `Cover=CronCoverAll` or `Cover=CronCoverIgnoreAll` (i.e., a \"run on all servers\" maintenance cron \u2014 common in monitoring deployments).\n\nStep 1: Enumerate admin cron IDs by ID-guessing. Try IDs 1..N; create AlertRule referencing each, see if the alert handler accepts.\n\nStep 2: Create an alert rule referencing the admin\u0027s cron and pointed at an offline-trigger condition on the member\u0027s own server.\n\n```bash\nTOKEN=$(curl -sX POST -H \u0027Content-Type: application/json\u0027 \\\n    -d \u0027{\"username\":\"member\",\"password\":\"hunter2\"}\u0027 \\\n    http://nezha.example.com/api/v1/login | jq -r .token)\n\ncurl -sX POST -H \"Authorization: Bearer $TOKEN\" -H \u0027Content-Type: application/json\u0027 \\\n    -d \u0027{\"name\":\"trip\",\"rules\":[{\"type\":\"offline\",\"duration\":3,\"min\":1.0,\"cover\":\"member-server-id\"}],\"fail_trigger_tasks\":[1,2,3,4,5],\"recover_trigger_tasks\":[],\"notification_group_id\":0,\"trigger_mode\":0,\"enable\":true}\u0027 \\\n    http://nezha.example.com/api/v1/alert-rule\n```\n\nStep 3: Stop the agent on the member\u0027s own server (or unplug it). The alert trips after `duration` seconds. `SendTriggerTasks([1,2,3,4,5], member-server-id)` runs.\n\nStep 4: For each cron ID in the list, if that cron exists in the global registry and has `Cover=CronCoverAll/IgnoreAll`, its `Command` runs on every server.\n\nThe same chain works via `POST /api/v1/service` (service-monitor with `fail_trigger_tasks`).\n\n## Composability with NEZHA-002\n\nIf `NEZHA-002` is unfixed, this chain is redundant \u2014 the member already has direct cron-create access. With `NEZHA-002` fixed, this still gives the member a means to invoke any **pre-existing** admin cron with the member\u0027s chosen trigger condition. The fix surface is also independent (alertrule/service write paths, not /cron writes).\n\n## Suggested fix\n\nIn `validateRule` (and `validateServers`):\n\n```go\nif !singleton.CronShared.CheckPermission(c, slices.Values(r.FailTriggerTasks)) {\n    return singleton.Localizer.ErrorT(\"permission denied\")\n}\nif !singleton.CronShared.CheckPermission(c, slices.Values(r.RecoverTriggerTasks)) {\n    return singleton.Localizer.ErrorT(\"permission denied\")\n}\n```\n\nDefense-in-depth in `SendTriggerTasks`: enforce that `task.UserID == alert.UserID || alertOwnerIsAdmin || taskOwnerIsAdmin`.\n\n## Severity\n\n  - PR:L because RoleMember credentials needed.\n  - AC:H because attacker has to ID-guess admin cron IDs and have an alert-trip vector. (For a deployment where the attacker has visibility into max cron ID via UI hints or the `id`-query echo, AC drops to L.)\n  - S:C because the cron command runs on every connected agent (different trust zone).\n- **Auth:** authenticated `RoleMember`.\n\n## Reproduction environment\n\n- Tested against: `nezhahq/nezha` master @ `50dc8e660326b9f22990898142c58b7a5312b42a`.\n- Code locations:\n  - `cmd/dashboard/controller/alertrule.go:47-77` (createAlertRule), 91-131 (updateAlertRule), 169-196 (validateRule)\n  - `cmd/dashboard/controller/service.go:404-445` (createService), 459-509 (updateService), 543-549 (validateServers)\n  - `service/singleton/crontask.go:113-127` (SendTriggerTasks), 133-181 (CronTrigger)\n  - `service/singleton/alertsentinel.go:170, 180` (alert-fire callsite)\n  - `service/singleton/servicesentinel.go:742-750` (service-fire callsite)\n\n## Reporter\n\nEddie Ran. Filed via reporter API. Companion to NEZHA-001/002 \u2014 same auth-bypass class but a different write path.",
  "id": "GHSA-rxf6-wjh4-jfj6",
  "modified": "2026-06-26T21:28:31Z",
  "published": "2026-05-23T00:08:45Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/nezhahq/nezha/security/advisories/GHSA-rxf6-wjh4-jfj6"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-47120"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/nezhahq/nezha"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Nezha Monitoring: RoleMember can fire other users\u0027 cron tasks via AlertRule.FailTriggerTasks (no ownership check)"
}

GHSA-RXFG-J664-GQPP

Vulnerability from github – Published: 2026-08-04 00:34 – Updated: 2026-08-04 00:34
VLAI
Details

Adobe Campaign Classic (ACC) is affected by an Incorrect Authorization vulnerability that could result in privilege escalation. An attacker could exploit this vulnerability to gain elevated privileges. Exploitation of this issue does not require user interaction.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-48333"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-08-03T23:16:46Z",
    "severity": "CRITICAL"
  },
  "details": "Adobe Campaign Classic (ACC) is affected by an Incorrect Authorization vulnerability that could result in privilege escalation. An attacker could exploit this vulnerability to gain elevated privileges. Exploitation of this issue does not require user interaction.",
  "id": "GHSA-rxfg-j664-gqpp",
  "modified": "2026-08-04T00:34:54Z",
  "published": "2026-08-04T00:34:54Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-48333"
    },
    {
      "type": "WEB",
      "url": "https://helpx.adobe.com/security/products/campaign/apsb26-120.html"
    }
  ],
  "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"
    }
  ]
}

GHSA-RXFW-G454-GJ22

Vulnerability from github – Published: 2026-09-23 06:31 – Updated: 2026-09-23 12:31
VLAI
Details

The Paid Membership Subscriptions WordPress plugin before 3.1.0 does not bind one of its unauthenticated payment actions to the requesting user, allowing someone who holds another member's in-flight payment identifier to delete that member's checkout state.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-90951"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-23T06:17:05Z",
    "severity": "LOW"
  },
  "details": "The Paid Membership Subscriptions  WordPress plugin before 3.1.0 does not bind one of its unauthenticated payment actions to the requesting user, allowing someone who holds another member\u0027s in-flight payment identifier to delete that member\u0027s checkout state.",
  "id": "GHSA-rxfw-g454-gj22",
  "modified": "2026-09-23T12:31:11Z",
  "published": "2026-09-23T06:31:04Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-90951"
    },
    {
      "type": "WEB",
      "url": "https://wpscan.com/vulnerability/bf740af6-3674-461e-83f0-22bd5c5b3378"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-RXG8-8WFH-HR43

Vulnerability from github – Published: 2026-09-09 03:30 – Updated: 2026-09-10 18:31
VLAI
Details

Incorrect authorization in Network in Google Chrome prior to 153.0.8010.36 allowed a remote attacker who had compromised the renderer process to bypass site isolation via a crafted HTML page. (Chromium security severity: High)

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-87499"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-09T01:17:06Z",
    "severity": "HIGH"
  },
  "details": "Incorrect authorization in Network in Google Chrome prior to 153.0.8010.36 allowed a remote attacker who had compromised the renderer process to bypass site isolation via a crafted HTML page. (Chromium security severity: High)",
  "id": "GHSA-rxg8-8wfh-hr43",
  "modified": "2026-09-10T18:31:38Z",
  "published": "2026-09-09T03:30:39Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-87499"
    },
    {
      "type": "WEB",
      "url": "https://chromereleases.googleblog.com/2026/09/stable-channel-update-for-desktop_0808145027.html"
    },
    {
      "type": "WEB",
      "url": "https://issues.chromium.org/issues/553118043"
    }
  ],
  "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:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-RXHM-9GMQ-9482

Vulnerability from github – Published: 2024-12-04 12:31 – Updated: 2024-12-04 12:31
VLAI
Details

Incorrect authorization vulnerability in Alert.Setting webapi component in Synology Surveillance Station before 9.2.0-11289 and 9.2.0-9289 allows remote authenticated users to to perform limited actions on the alerting function via unspecified vectors.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-52943"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-12-04T07:15:04Z",
    "severity": "MODERATE"
  },
  "details": "Incorrect authorization vulnerability in Alert.Setting webapi component in Synology Surveillance Station before 9.2.0-11289 and 9.2.0-9289 allows remote authenticated users to to perform limited actions on the alerting function via unspecified vectors.",
  "id": "GHSA-rxhm-9gmq-9482",
  "modified": "2024-12-04T12:31:44Z",
  "published": "2024-12-04T12:31:44Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-52943"
    },
    {
      "type": "WEB",
      "url": "https://www.synology.com/en-global/security/advisory/Synology_SA_24_04"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

Mitigation
Architecture and Design
  • Divide the product into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully mapping roles with data and functionality. Use role-based access control (RBAC) [REF-229] to enforce the roles at the appropriate boundaries.
  • Note that this approach may not protect against horizontal authorization, i.e., it will not protect a user from attacking others with the same role.
Mitigation
Architecture and Design

Ensure that access control checks are performed related to the business logic. These checks may be different than the access control checks that are applied to more generic resources such as files, connections, processes, memory, and database records. For example, a database may restrict access for medical records to a specific database user, but each record might only be intended to be accessible to the patient and the patient's doctor [REF-7].

Mitigation MIT-4.4
Architecture and Design

Strategy: Libraries or Frameworks

  • Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.
  • For example, consider using authorization frameworks such as the JAAS Authorization Framework [REF-233] and the OWASP ESAPI Access Control feature [REF-45].
Mitigation
Architecture and Design
  • For web applications, make sure that the access control mechanism is enforced correctly at the server side on every page. Users should not be able to access any unauthorized functionality or information by simply requesting direct access to that page.
  • One way to do this is to ensure that all pages containing sensitive information are not cached, and that all such pages restrict access to requests that are accompanied by an active and authenticated session token associated with a user who has the required permissions to access that page.
Mitigation
System Configuration Installation

Use the access control capabilities of your operating system and server environment and define your access control lists accordingly. Use a "default deny" policy when defining these ACLs.

No CAPEC attack patterns related to this CWE.