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.

5641 vulnerabilities reference this CWE, most recent first.

GHSA-98MX-4VV7-3PQ6

Vulnerability from github – Published: 2023-01-31 12:30 – Updated: 2023-02-08 03:30
VLAI
Details

Incorrect Authorization vulnerability in Apache Software Foundation Apache IoTDB.This issue affects the iotdb-web-workbench component from 0.13.0 before 0.13.3. iotdb-web-workbench is an optional component of IoTDB, providing a web console of the database. This problem is fixed from version 0.13.3 of iotdb-web-workbench onwards.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-24829"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-01-31T10:15:00Z",
    "severity": "HIGH"
  },
  "details": "Incorrect Authorization vulnerability in Apache Software Foundation Apache IoTDB.This issue affects the iotdb-web-workbench component from 0.13.0 before 0.13.3. iotdb-web-workbench is an optional component of IoTDB, providing a web console of the database. This problem is fixed from version 0.13.3 of iotdb-web-workbench onwards.",
  "id": "GHSA-98mx-4vv7-3pq6",
  "modified": "2023-02-08T03:30:25Z",
  "published": "2023-01-31T12:30:23Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-24829"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread/l0b59hh046tyn4gqot0bdrpg8gxlksmo"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-98PX-6486-J7QC

Vulnerability from github – Published: 2023-06-06 16:41 – Updated: 2024-09-30 20:34
VLAI
Summary
Synapse has URL deny list bypass via oEmbed and image URLs when generating previews
Details

Impact

A discovered oEmbed or image URL can bypass the url_preview_url_blacklist setting potentially allowing server side request forgery or bypassing network policies. Impact is limited to IP addresses allowed by the url_preview_ip_range_blacklist setting (by default this only allows public IPs) and by the limited information returned to the client:

  • For discovered oEmbed URLs, any non-JSON response or a JSON response which includes non-oEmbed information is discarded.
  • For discovered image URLs, any non-image response is discarded.

Systems which have URL preview disabled (via the url_preview_enabled setting) or have not configured a url_preview_url_blacklist are not affected.

Because of the uncommon configuration required, the limited information a malicious user, and the amount of guesses/time the attack would need; the severity is rated as low.

Patches

The issue is fixed by #15601.

Workarounds

The default configuration of the url_preview_ip_range_blacklist should protect against requests being made to internal infrastructure, URL previews of public URLs is expected.

Alternately URL previews could be disabled using the url_preview_enabled setting.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "matrix-synapse"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.85.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2023-32683"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2023-06-06T16:41:34Z",
    "nvd_published_at": "2023-06-06T19:15:11Z",
    "severity": "MODERATE"
  },
  "details": "### Impact\nA discovered oEmbed or image URL can bypass the `url_preview_url_blacklist` setting potentially allowing server side request forgery or bypassing network policies. Impact is limited to IP addresses allowed by the `url_preview_ip_range_blacklist` setting (by default this only allows public IPs) and by the limited information returned to the client:\n\n* For discovered oEmbed URLs, any non-JSON response or a JSON response which includes non-oEmbed information is discarded.\n* For discovered image URLs, any non-image response is discarded.\n\nSystems which have URL preview disabled (via the `url_preview_enabled` setting) or have not configured a `url_preview_url_blacklist` are not affected.\n\nBecause of the uncommon configuration required, the limited information a malicious user, and the amount of guesses/time the attack would need; the severity is rated as low.\n\n### Patches\n\nThe issue is fixed by #15601.\n\n### Workarounds\n\nThe default configuration of the `url_preview_ip_range_blacklist` should protect against requests being made to internal infrastructure, URL previews of public URLs is expected.\n\nAlternately URL previews could be disabled using the `url_preview_enabled` setting.",
  "id": "GHSA-98px-6486-j7qc",
  "modified": "2024-09-30T20:34:41Z",
  "published": "2023-06-06T16:41:34Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/matrix-org/synapse/security/advisories/GHSA-98px-6486-j7qc"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-32683"
    },
    {
      "type": "WEB",
      "url": "https://github.com/matrix-org/synapse/pull/15601"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/matrix-org/synapse"
    },
    {
      "type": "WEB",
      "url": "https://github.com/matrix-org/synapse/releases/tag/v1.85.0"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pypa/advisory-database/tree/main/vulns/matrix-synapse/PYSEC-2023-85.yaml"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/X6DH5A5YEB5LRIPP32OUW25FCGZFCZU2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Synapse has URL deny list bypass via oEmbed and image URLs when generating previews"
}

GHSA-98Q5-67C3-CPJC

Vulnerability from github – Published: 2022-11-02 12:00 – Updated: 2022-11-03 12:00
VLAI
Details

A permissions issue existed. This issue was addressed with improved permission validation. This issue is fixed in macOS Ventura 13. A malicious application may be able to read sensitive location information.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-42788"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-732",
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-11-01T20:15:00Z",
    "severity": "MODERATE"
  },
  "details": "A permissions issue existed. This issue was addressed with improved permission validation. This issue is fixed in macOS Ventura 13. A malicious application may be able to read sensitive location information.",
  "id": "GHSA-98q5-67c3-cpjc",
  "modified": "2022-11-03T12:00:32Z",
  "published": "2022-11-02T12:00:43Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-42788"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/en-us/HT213488"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-998C-7HF5-G249

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

Incorrect Authorization (CWE-863) in Kibana can lead to cross-space information disclosure via Privilege Abuse (CAPEC-122). A user with Fleet agent management privileges in one Kibana space can retrieve Fleet Server policy details from other spaces through an internal enrollment endpoint. The endpoint bypasses space-scoped access controls by using an unscoped internal client, returning operational identifiers, policy names, management state, and infrastructure linkage details from spaces the user is not authorized to access.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-33460"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-04-08T17:21:18Z",
    "severity": "MODERATE"
  },
  "details": "Incorrect Authorization (CWE-863) in Kibana can lead to cross-space information disclosure via Privilege Abuse (CAPEC-122). A user with Fleet agent management privileges in one Kibana space can retrieve Fleet Server policy details from other spaces through an internal enrollment endpoint. The endpoint bypasses space-scoped access controls by using an unscoped internal client, returning operational identifiers, policy names, management state, and infrastructure linkage details from spaces the user is not authorized to access.",
  "id": "GHSA-998c-7hf5-g249",
  "modified": "2026-04-08T18:34:07Z",
  "published": "2026-04-08T18:34:07Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33460"
    },
    {
      "type": "WEB",
      "url": "https://discuss.elastic.co/t/kibana-8-19-14-9-2-8-9-3-3-security-update-esa-2026-25/385813"
    }
  ],
  "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-99FV-V434-WH6F

Vulnerability from github – Published: 2025-02-12 00:32 – Updated: 2025-02-12 18:31
VLAI
Details

An issue in the SharedConfig class of Telegram Android APK v.11.7.0 allows a physically proximate attacker to bypass authentication and escalate privileges by manipulating the return value of the checkPasscode method.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-54916"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-287",
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-02-11T23:15:09Z",
    "severity": "MODERATE"
  },
  "details": "An issue in the SharedConfig class of Telegram Android APK v.11.7.0 allows a physically proximate attacker to bypass authentication and escalate privileges by manipulating the return value of the checkPasscode method.",
  "id": "GHSA-99fv-v434-wh6f",
  "modified": "2025-02-12T18:31:34Z",
  "published": "2025-02-12T00:32:17Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-54916"
    },
    {
      "type": "WEB",
      "url": "https://drive.google.com/file/d/1knf8-_fFUSLd3ZmbEpy0_OVzSN1UR1JR/view?usp=sharing"
    },
    {
      "type": "WEB",
      "url": "https://github.com/SAHALLL/CVE-2024-54916"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-99J9-W4CP-4529

Vulnerability from github – Published: 2022-05-24 17:18 – Updated: 2022-05-24 17:18
VLAI
Details

There is an Incorrect Authorization vulnerability in Micro Focus Service Management Automation (SMA) product affecting version 2018.05 to 2020.02. The vulnerability could be exploited to provide unauthorized access to the Container Deployment Foundation.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2020-11844"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2020-05-29T22:15:00Z",
    "severity": "HIGH"
  },
  "details": "There is an Incorrect Authorization vulnerability in Micro Focus Service Management Automation (SMA) product affecting version 2018.05 to 2020.02. The vulnerability could be exploited to provide unauthorized access to the Container Deployment Foundation.",
  "id": "GHSA-99j9-w4cp-4529",
  "modified": "2022-05-24T17:18:54Z",
  "published": "2022-05-24T17:18:54Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2020-11844"
    },
    {
      "type": "WEB",
      "url": "https://softwaresupport.softwaregrp.com/doc/KM03645628"
    },
    {
      "type": "WEB",
      "url": "https://softwaresupport.softwaregrp.com/doc/KM03645629"
    },
    {
      "type": "WEB",
      "url": "https://softwaresupport.softwaregrp.com/doc/KM03645630"
    },
    {
      "type": "WEB",
      "url": "https://softwaresupport.softwaregrp.com/doc/KM03645631"
    },
    {
      "type": "WEB",
      "url": "https://softwaresupport.softwaregrp.com/doc/KM03645636"
    },
    {
      "type": "WEB",
      "url": "https://softwaresupport.softwaregrp.com/doc/KM03645642"
    },
    {
      "type": "WEB",
      "url": "https://support.microfocus.com/kb/doc.php?id=7024637"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-99MR-FJVP-4W9W

Vulnerability from github – Published: 2026-03-26 21:31 – Updated: 2026-03-30 15:31
VLAI
Details

Incorrect Authorization vulnerability in Drupal AI (Artificial Intelligence) allows Resource Injection.This issue affects AI (Artificial Intelligence): from 0.0.0 before 1.1.11, from 1.2.0 before 1.2.12.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-3573"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-03-26T21:17:09Z",
    "severity": "HIGH"
  },
  "details": "Incorrect Authorization vulnerability in Drupal AI (Artificial Intelligence) allows Resource Injection.This issue affects AI (Artificial Intelligence): from 0.0.0 before 1.1.11, from 1.2.0 before 1.2.12.",
  "id": "GHSA-99mr-fjvp-4w9w",
  "modified": "2026-03-30T15:31:52Z",
  "published": "2026-03-26T21:31:28Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-3573"
    },
    {
      "type": "WEB",
      "url": "https://www.drupal.org/sa-contrib-2026-028"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-99PG-5RF4-R9X9

Vulnerability from github – Published: 2022-09-20 00:00 – Updated: 2022-09-22 00:00
VLAI
Details

When the LDAP connector is started with StartTLS configured, unauthenticated access is granted. This issue affects: all versions of the LDAP connector prior to 1.5.20.9. The LDAP connector is bundled with Identity Management (IDM) and Remote Connector Server (RCS)

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-0143"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-09-19T22:15:00Z",
    "severity": "CRITICAL"
  },
  "details": "When the LDAP connector is started with StartTLS configured, unauthenticated access is granted. This issue affects: all versions of the LDAP connector prior to 1.5.20.9. The LDAP connector is bundled with Identity Management (IDM) and Remote Connector Server (RCS)",
  "id": "GHSA-99pg-5rf4-r9x9",
  "modified": "2022-09-22T00:00:25Z",
  "published": "2022-09-20T00:00:21Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-0143"
    },
    {
      "type": "WEB",
      "url": "https://backstage.forgerock.com/downloads/browse/idm/featured/connectors"
    },
    {
      "type": "WEB",
      "url": "https://backstage.forgerock.com/knowledge/kb/article/a11380515"
    }
  ],
  "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-99QV-G4X9-MGC3

Vulnerability from github – Published: 2026-05-06 20:45 – Updated: 2026-06-09 00:00
VLAI
Summary
phpMyFAQ has unauthenticated FAQ permission bypass via getFaqBySolutionId fallback query
Details

Summary

The public /solution_id_{id}.html route calls Faq::getIdFromSolutionId() in phpmyfaq/src/phpMyFAQ/Faq.php:1312. That query joins faqdata with faqcategoryrelations solely by solution_id and returns the matching FAQ's id, lang, thema (title), and category_id with no permission filter. An unauthenticated visitor hits the route with a sequential integer and the server 301-redirects to /content/<category>/<id>/<lang>/<title-slug>.html, leaking the FAQ's existence, internal id, language, category binding, and title via the redirect's Location header and the redirected page's canonical link, share-to-social URLs, and hidden form fields. The related getFaqBySolutionId() at line 1221 contains an explicit fallback query (added "for tests") that also bypasses the permission filter, widening the blast radius to any callsite that trusts its result.

Details

The sink: getIdFromSolutionId() has no permission filter

phpmyfaq/src/phpMyFAQ/Faq.php:1312:

public function getIdFromSolutionId(int $solutionId): array
{
    $query = sprintf(
        'SELECT fd.id, fd.lang, fd.thema AS question, fd.content, fcr.category_id
         FROM %sfaqdata fd
         LEFT JOIN %sfaqcategoryrelations fcr
           ON fd.id = fcr.record_id AND fd.lang = fcr.record_lang
         WHERE fd.solution_id = %d',
        Database::getTablePrefix(),
        Database::getTablePrefix(),
        $solutionId,
    );
    // ...
}

No WHERE-clause permission filter, no group/user filter. Every callsite that trusts this method exposes restricted FAQs. The route at phpmyfaq/src/phpMyFAQ/Controller/Frontend/FaqController.php:172 uses this result to compute a slugified URL and 301-redirects to it:

#[Route(path: '/solution_id_{solutionId}.html', name: 'public.faq.solution', methods: ['GET'])]
public function solution(Request $request): Response
{
    $solutionId = Filter::filterVar($request->attributes->get('solutionId'), FILTER_VALIDATE_INT, 0);
    // ...
    $faqData = $this->faq->getIdFromSolutionId($solutionId);
    if ($faqData === []) {
        return new Response('', Response::HTTP_NOT_FOUND);
    }
    $slug = TitleSlugifier::slug($faqData['question']);
    $url = sprintf('/content/%d/%d/%s/%s.html',
        $faqData['category_id'], $faqData['id'], $faqData['lang'], $slug);
    return new RedirectResponse($url, Response::HTTP_MOVED_PERMANENTLY);
}

The redirect URL embeds the title slug, so an unauthenticated visitor observes the title directly even though the canonical /content/<...>.html page may deny rendering the body.

Related sink: getFaqBySolutionId() explicitly falls back without the filter

phpmyfaq/src/phpMyFAQ/Faq.php:1256-1265:

if (false === $row || null === $row) {
    // Fallback without permission filter to ensure retrieval in non-authenticated contexts (e.g., tests)
    $fallbackQuery = sprintf(
        'SELECT * FROM %sfaqdata fd WHERE fd.solution_id = %d LIMIT 1',
        Database::getTablePrefix(),
        $solutionId,
    );
    $fallbackResult = $this->configuration->getDb()->query($fallbackQuery);
    $row = $this->configuration->getDb()->fetchObject($fallbackResult);
}

The inline comment confirms the fallback was introduced for test convenience. In production, the fallback fires exactly when the permission-filtered query returns zero rows (because the caller is unauthenticated or lacks group/user permission) and populates every field of faqRecord, including content, keywords, author, email, and notes. Downstream consumers that expect faqRecord to respect ACLs no longer do.

Entry enumeration

Solution IDs are monotonically increasing integers (faqdata.solution_id). An attacker enumerates /solution_id_<n>.html from 1 upward and records every non-404 response to discover the full set of FAQs on the instance, including ones restricted to admin-only groups or specific users.

Proof of Concept

Prerequisites: a phpMyFAQ instance has at least one FAQ record restricted to a specific user or group via faqdata_user / faqdata_group. Note its solution_id, which is assigned sequentially starting from a six-digit base.

Step 1. Anonymous GET of the solution URL:

curl -sS -L -o /tmp/out.html -w 'HTTP %{http_code}\n' \
  'http://<host>/solution_id_<restricted-solution-id>.html'

Step 2. Observe the 301 redirect that getIdFromSolutionId() returns. The Location header carries the slugified title of the restricted FAQ directly in the URL path:

HTTP/1.1 301 Moved Permanently
Location: /content/<category-id>/<record-id>/<lang>/<title-slug>.html

Step 3. The redirected content page embeds the same metadata in client-controlled sinks, even when the body rendering is suppressed by a separate permission check:

<link rel="canonical" href="http://<host>/content/<category-id>/<record-id>/<lang>/<title-slug>.html">
<input type="hidden" name="voting-id" value="<record-id>">
<a href="http://<host>/pdf/<category-id>/<record-id>/<lang>">...</a>

Step 4. Enumerate solution IDs to discover every FAQ on the instance, including those the permission model intended to hide:

for id in $(seq 1 100000); do
  code=$(curl -sS -o /dev/null -w '%{http_code}' "http://<host>/solution_id_${id}.html")
  if [ "$code" = "301" ]; then
    loc=$(curl -sSI "http://<host>/solution_id_${id}.html" | awk -F': ' '/^Location:/{print $2}' | tr -d '\r')
    echo "solution_id=${id} -> ${loc}"
  fi
done

Each 301 response's Location header reveals category, id, language, and title of a FAQ whose existence the permission model meant to hide.

Impact

Any unauthenticated visitor discovers the full set of FAQ entries on the instance, including the subset restricted to specific groups or users, and reads the title of every restricted FAQ. Deployments that use phpMyFAQ to host internal-only content alongside public content (staff knowledge bases, internal SOPs, confidential customer notes) lose the confidentiality of titles and of the fact that those FAQs exist. Slugified titles often encode the subject directly (for example q3-layoff-plan, aws-root-key-rotation), so the title alone can be sensitive.

The body content is usually still served through a separate permission-enforcing path on the canonical /content/<...>.html URL, so full-body disclosure requires the caller to also defeat that path (for example by combining with a session from any low-privilege account). The title-plus-existence leak is sufficient on its own to harm confidentiality in deployments where titles encode what the FAQ is about.

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N (Medium, 5.3). CWE-863.

Recommended Fix

Add a permission filter to getIdFromSolutionId() the same way getFaqBySolutionId() builds one for its primary query (using QueryHelper::queryPermission()):

public function getIdFromSolutionId(int $solutionId): array
{
    $queryHelper = new QueryHelper($this->user, $this->groups);
    $query = sprintf(
        'SELECT fd.id, fd.lang, fd.thema AS question, fd.content, fcr.category_id
         FROM %sfaqdata fd
         LEFT JOIN %sfaqcategoryrelations fcr
           ON fd.id = fcr.record_id AND fd.lang = fcr.record_lang
         LEFT JOIN (
             SELECT record_id, group_id FROM %sfaqdata_group fdg WHERE fdg.group_id <> -1
             UNION ALL
             SELECT fd.id AS record_id, -1 AS group_id FROM %sfaqdata fd WHERE fd.solution_id = %d
         ) AS fdg ON fd.id = fdg.record_id
         LEFT JOIN %sfaqdata_user fdu ON fd.id = fdu.record_id
         WHERE fd.solution_id = %d %s',
        Database::getTablePrefix(),
        Database::getTablePrefix(),
        Database::getTablePrefix(),
        Database::getTablePrefix(),
        $solutionId,
        Database::getTablePrefix(),
        $solutionId,
        $queryHelper->queryPermission($this->groupSupport),
    );
    // ...
}

Separately, remove the unconditional fallback in getFaqBySolutionId() at Faq.php:1256-1265. If the permission-filtered query returns no rows, the FAQ is not visible to this caller; the method should leave faqRecord empty rather than re-query without the filter. If tests rely on the old behavior, replace the production fallback with a dedicated test helper or a flag that is disabled outside test bootstrap.


Found by aisafe.io

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.1.1"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "thorsten/phpmyfaq"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.1.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.1.1"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "phpmyfaq/phpmyfaq"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.1.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-46366"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-06T20:45:01Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Summary\n\nThe public `/solution_id_{id}.html` route calls `Faq::getIdFromSolutionId()` in `phpmyfaq/src/phpMyFAQ/Faq.php:1312`. That query joins `faqdata` with `faqcategoryrelations` solely by `solution_id` and returns the matching FAQ\u0027s `id`, `lang`, `thema` (title), and `category_id` with no permission filter. An unauthenticated visitor hits the route with a sequential integer and the server 301-redirects to `/content/\u003ccategory\u003e/\u003cid\u003e/\u003clang\u003e/\u003ctitle-slug\u003e.html`, leaking the FAQ\u0027s existence, internal id, language, category binding, and title via the redirect\u0027s `Location` header and the redirected page\u0027s canonical link, share-to-social URLs, and hidden form fields. The related `getFaqBySolutionId()` at line 1221 contains an explicit fallback query (added \"for tests\") that also bypasses the permission filter, widening the blast radius to any callsite that trusts its result.\n\n## Details\n\n### The sink: `getIdFromSolutionId()` has no permission filter\n\n`phpmyfaq/src/phpMyFAQ/Faq.php:1312`:\n\n```php\npublic function getIdFromSolutionId(int $solutionId): array\n{\n    $query = sprintf(\n        \u0027SELECT fd.id, fd.lang, fd.thema AS question, fd.content, fcr.category_id\n         FROM %sfaqdata fd\n         LEFT JOIN %sfaqcategoryrelations fcr\n           ON fd.id = fcr.record_id AND fd.lang = fcr.record_lang\n         WHERE fd.solution_id = %d\u0027,\n        Database::getTablePrefix(),\n        Database::getTablePrefix(),\n        $solutionId,\n    );\n    // ...\n}\n```\n\nNo `WHERE`-clause permission filter, no group/user filter. Every callsite that trusts this method exposes restricted FAQs. The route at `phpmyfaq/src/phpMyFAQ/Controller/Frontend/FaqController.php:172` uses this result to compute a slugified URL and 301-redirects to it:\n\n```php\n#[Route(path: \u0027/solution_id_{solutionId}.html\u0027, name: \u0027public.faq.solution\u0027, methods: [\u0027GET\u0027])]\npublic function solution(Request $request): Response\n{\n    $solutionId = Filter::filterVar($request-\u003eattributes-\u003eget(\u0027solutionId\u0027), FILTER_VALIDATE_INT, 0);\n    // ...\n    $faqData = $this-\u003efaq-\u003egetIdFromSolutionId($solutionId);\n    if ($faqData === []) {\n        return new Response(\u0027\u0027, Response::HTTP_NOT_FOUND);\n    }\n    $slug = TitleSlugifier::slug($faqData[\u0027question\u0027]);\n    $url = sprintf(\u0027/content/%d/%d/%s/%s.html\u0027,\n        $faqData[\u0027category_id\u0027], $faqData[\u0027id\u0027], $faqData[\u0027lang\u0027], $slug);\n    return new RedirectResponse($url, Response::HTTP_MOVED_PERMANENTLY);\n}\n```\n\nThe redirect URL embeds the title slug, so an unauthenticated visitor observes the title directly even though the canonical `/content/\u003c...\u003e.html` page may deny rendering the body.\n\n### Related sink: `getFaqBySolutionId()` explicitly falls back without the filter\n\n`phpmyfaq/src/phpMyFAQ/Faq.php:1256-1265`:\n\n```php\nif (false === $row || null === $row) {\n    // Fallback without permission filter to ensure retrieval in non-authenticated contexts (e.g., tests)\n    $fallbackQuery = sprintf(\n        \u0027SELECT * FROM %sfaqdata fd WHERE fd.solution_id = %d LIMIT 1\u0027,\n        Database::getTablePrefix(),\n        $solutionId,\n    );\n    $fallbackResult = $this-\u003econfiguration-\u003egetDb()-\u003equery($fallbackQuery);\n    $row = $this-\u003econfiguration-\u003egetDb()-\u003efetchObject($fallbackResult);\n}\n```\n\nThe inline comment confirms the fallback was introduced for test convenience. In production, the fallback fires exactly when the permission-filtered query returns zero rows (because the caller is unauthenticated or lacks group/user permission) and populates every field of `faqRecord`, including `content`, `keywords`, `author`, `email`, and `notes`. Downstream consumers that expect `faqRecord` to respect ACLs no longer do.\n\n### Entry enumeration\n\nSolution IDs are monotonically increasing integers (`faqdata.solution_id`). An attacker enumerates `/solution_id_\u003cn\u003e.html` from 1 upward and records every non-404 response to discover the full set of FAQs on the instance, including ones restricted to admin-only groups or specific users.\n\n## Proof of Concept\n\nPrerequisites: a phpMyFAQ instance has at least one FAQ record restricted to a specific user or group via `faqdata_user` / `faqdata_group`. Note its `solution_id`, which is assigned sequentially starting from a six-digit base.\n\nStep 1. Anonymous GET of the solution URL:\n\n```bash\ncurl -sS -L -o /tmp/out.html -w \u0027HTTP %{http_code}\\n\u0027 \\\n  \u0027http://\u003chost\u003e/solution_id_\u003crestricted-solution-id\u003e.html\u0027\n```\n\nStep 2. Observe the 301 redirect that `getIdFromSolutionId()` returns. The `Location` header carries the slugified title of the restricted FAQ directly in the URL path:\n\n```\nHTTP/1.1 301 Moved Permanently\nLocation: /content/\u003ccategory-id\u003e/\u003crecord-id\u003e/\u003clang\u003e/\u003ctitle-slug\u003e.html\n```\n\nStep 3. The redirected content page embeds the same metadata in client-controlled sinks, even when the body rendering is suppressed by a separate permission check:\n\n```html\n\u003clink rel=\"canonical\" href=\"http://\u003chost\u003e/content/\u003ccategory-id\u003e/\u003crecord-id\u003e/\u003clang\u003e/\u003ctitle-slug\u003e.html\"\u003e\n\u003cinput type=\"hidden\" name=\"voting-id\" value=\"\u003crecord-id\u003e\"\u003e\n\u003ca href=\"http://\u003chost\u003e/pdf/\u003ccategory-id\u003e/\u003crecord-id\u003e/\u003clang\u003e\"\u003e...\u003c/a\u003e\n```\n\nStep 4. Enumerate solution IDs to discover every FAQ on the instance, including those the permission model intended to hide:\n\n```bash\nfor id in $(seq 1 100000); do\n  code=$(curl -sS -o /dev/null -w \u0027%{http_code}\u0027 \"http://\u003chost\u003e/solution_id_${id}.html\")\n  if [ \"$code\" = \"301\" ]; then\n    loc=$(curl -sSI \"http://\u003chost\u003e/solution_id_${id}.html\" | awk -F\u0027: \u0027 \u0027/^Location:/{print $2}\u0027 | tr -d \u0027\\r\u0027)\n    echo \"solution_id=${id} -\u003e ${loc}\"\n  fi\ndone\n```\n\nEach `301` response\u0027s `Location` header reveals category, id, language, and title of a FAQ whose existence the permission model meant to hide.\n\n## Impact\n\nAny unauthenticated visitor discovers the full set of FAQ entries on the instance, including the subset restricted to specific groups or users, and reads the title of every restricted FAQ. Deployments that use phpMyFAQ to host internal-only content alongside public content (staff knowledge bases, internal SOPs, confidential customer notes) lose the confidentiality of titles and of the fact that those FAQs exist. Slugified titles often encode the subject directly (for example `q3-layoff-plan`, `aws-root-key-rotation`), so the title alone can be sensitive.\n\nThe body content is usually still served through a separate permission-enforcing path on the canonical `/content/\u003c...\u003e.html` URL, so full-body disclosure requires the caller to also defeat that path (for example by combining with a session from any low-privilege account). The title-plus-existence leak is sufficient on its own to harm confidentiality in deployments where titles encode what the FAQ is about.\n\n`CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N` (Medium, 5.3). CWE-863.\n\n## Recommended Fix\n\nAdd a permission filter to `getIdFromSolutionId()` the same way `getFaqBySolutionId()` builds one for its primary query (using `QueryHelper::queryPermission()`):\n\n```php\npublic function getIdFromSolutionId(int $solutionId): array\n{\n    $queryHelper = new QueryHelper($this-\u003euser, $this-\u003egroups);\n    $query = sprintf(\n        \u0027SELECT fd.id, fd.lang, fd.thema AS question, fd.content, fcr.category_id\n         FROM %sfaqdata fd\n         LEFT JOIN %sfaqcategoryrelations fcr\n           ON fd.id = fcr.record_id AND fd.lang = fcr.record_lang\n         LEFT JOIN (\n             SELECT record_id, group_id FROM %sfaqdata_group fdg WHERE fdg.group_id \u003c\u003e -1\n             UNION ALL\n             SELECT fd.id AS record_id, -1 AS group_id FROM %sfaqdata fd WHERE fd.solution_id = %d\n         ) AS fdg ON fd.id = fdg.record_id\n         LEFT JOIN %sfaqdata_user fdu ON fd.id = fdu.record_id\n         WHERE fd.solution_id = %d %s\u0027,\n        Database::getTablePrefix(),\n        Database::getTablePrefix(),\n        Database::getTablePrefix(),\n        Database::getTablePrefix(),\n        $solutionId,\n        Database::getTablePrefix(),\n        $solutionId,\n        $queryHelper-\u003equeryPermission($this-\u003egroupSupport),\n    );\n    // ...\n}\n```\n\nSeparately, remove the unconditional fallback in `getFaqBySolutionId()` at `Faq.php:1256-1265`. If the permission-filtered query returns no rows, the FAQ is not visible to this caller; the method should leave `faqRecord` empty rather than re-query without the filter. If tests rely on the old behavior, replace the production fallback with a dedicated test helper or a flag that is disabled outside test bootstrap.\n\n---\n*Found by [aisafe.io](https://aisafe.io)*",
  "id": "GHSA-99qv-g4x9-mgc3",
  "modified": "2026-06-09T00:00:00Z",
  "published": "2026-05-06T20:45:01Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/thorsten/phpMyFAQ/security/advisories/GHSA-99qv-g4x9-mgc3"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-46366"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/thorsten/phpMyFAQ"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/phpmyfaq-unauthenticated-information-disclosure-via-getidfromsolutionid-permission-bypass"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "phpMyFAQ has unauthenticated FAQ permission bypass via getFaqBySolutionId fallback query"
}

GHSA-99VM-5V2H-H6R6

Vulnerability from github – Published: 2025-02-19 17:46 – Updated: 2025-02-19 19:59
VLAI
Summary
Directus allows updates to non-allowed fields due to overlapping policies
Details

Summary

If there are two overlapping policies for the update action that allow access to different fields, instead of correctly checking access permissions against the item they apply for the user is allowed to update the superset of fields allowed by any of the policies.

E.g. have one policy allowing update access to field_a if the id == 1 and one policy allowing update access to field_b if the id == 2. The user with both these policies is allowed to update both field_a and field_b for the items with ids 1 and 2.

Details

Before v11, if a user was allowed to update an item they were allowed to update the fields that the single permission, that applied to that item, listed. With overlapping permissions this isn't as clear cut anymore and the union of fields might not be the fields the user is allowed to update for that specific item.

The solution that this PR introduces is to evaluate the permissions for each field that the user tries to update in the validateItemAccess DB query, instead of only verifying access to the item as a whole. This is done by, instead of returning the actual field value, returning a flag that indicates if the user has access to that field. This uses the same case/when mechanism that is used for stripping out non permitted field that is at the core of the permissions engine.

As a result, for every item that the access is validated for, the expected result is an item that has either 1 or null for all the "requested" fields instead of any of the actual field values. These results are not useful for anything other than verifying the field level access permissions.

The final check in validateItemAccess can either fail if the number of items does not match the number of items the access is checked for (ie. the user does not have access to the item at all) or if not all of the passed in fields have access permissions for any of the returned items.

Impact

This is a vulnerability that allows update access to unintended fields, potentially impacting the password field for user accounts.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "directus"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "11.0.0"
            },
            {
              "fixed": "11.1.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "@directus/api"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "22.0.0"
            },
            {
              "fixed": "23.1.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-27089"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-02-19T17:46:27Z",
    "nvd_published_at": "2025-02-19T17:15:15Z",
    "severity": "MODERATE"
  },
  "details": "### Summary\nIf there are two overlapping policies for the `update` action that allow access to different fields, instead of correctly checking access permissions against the item they apply for the user is allowed to update the superset of fields allowed by any of the policies. \n\nE.g. have one policy allowing update access to `field_a` if the `id == 1` and one policy allowing update access to `field_b` if the `id == 2`. The user with both these policies is allowed to update both `field_a` and `field_b` for the items with ids `1` and `2`. \n\n### Details\nBefore v11, if a user was allowed to update an item they were allowed to update the fields that the single permission, that applied to that item, listed. With overlapping permissions this isn\u0027t as clear cut anymore and the union of fields might not be the fields the user is allowed to update for that specific item.\n\nThe solution that this PR introduces is to evaluate the permissions for each field that the user tries to update in the validateItemAccess DB query, instead of only verifying access to the item as a whole. This is done by, instead of returning the actual field value, returning a flag that indicates if the user has access to that field. This uses the same case/when mechanism that is used for stripping out non permitted field that is at the core of the permissions engine.\n\nAs a result, for every item that the access is validated for, the expected result is an item that has either 1 or null for all the \"requested\" fields instead of any of the actual field values. These results are not useful for anything other than verifying the field level access permissions.\n\nThe final check in validateItemAccess can either fail if the number of items does not match the number of items the access is checked for (ie. the user does not have access to the item at all) or if not all of the passed in fields have access permissions for any of the returned items.\n\n### Impact\nThis is a vulnerability that allows update access to unintended fields, potentially impacting the password field for user accounts.",
  "id": "GHSA-99vm-5v2h-h6r6",
  "modified": "2025-02-19T19:59:54Z",
  "published": "2025-02-19T17:46:27Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/directus/directus/security/advisories/GHSA-99vm-5v2h-h6r6"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-27089"
    },
    {
      "type": "WEB",
      "url": "https://github.com/directus/directus/commit/a7ea67783b060d0d6fc964d71c2d4575d5eee4e2"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/directus/directus"
    },
    {
      "type": "WEB",
      "url": "https://github.com/directus/directus/releases/tag/v11.1.2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Directus allows updates to non-allowed fields due to overlapping policies"
}

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.