All vulnerabilities
GHSA-6xm9-p734-8fx6

phpMyFAQ: Public open-questions API returns hidden questions

phpMyFAQ
CVSS
5.3Medium
ExploitationNo known exploitationNot in CISA KEV, which does not prove it is unexploitedCISA KEV
Exploit odds (EPSS)No scoreNo FIRST EPSS score in this snapshot yet
Fixed in4.2.0-betaFixed versionGitHub
Published3 Oct 2026Updated 3 Oct 2026GitHub

What fixes it

A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.

Description

Summary

Unauthenticated GET /api/v4.0/open-questions returns questions marked is_visible = N when api.onlyPublicQuestions is enabled (the default). The HTML page /open-questions.html correctly hides those rows. The API does the opposite of the documented flag.

Description

OpenQuestionController::list() reads api.onlyPublicQuestions and passes that boolean into Question::getAll($showAll).

QuestionRepository::getAll() treats $showAll === true as “do not filter on is_visible” and $showAll === false as AND is_visible = 'Y'.

Default config is api.onlyPublicQuestions = true (“API returns only public questions”). That becomes getAll(true), which returns all rows, including hidden ones.

The public HTML helper queries is_visible = 'Y' only, so the website and the API disagree.

The existing unit test encodes the inverted call (getAll expected with true when the flag is true).

Root cause

phpmyfaq/src/phpMyFAQ/Controller/Api/OpenQuestionController.php:

$onlyPublic = (bool) $this->configuration->get('api.onlyPublicQuestions');
// ...
$this->question->getAll($onlyPublic);

phpmyfaq/src/phpMyFAQ/Question/QuestionRepository.php:

$showAll === false ? " AND is_visible = 'Y'" : '',

Should be getAll(showAll: !$onlyPublic).

Proof of concept

Environment: phpMyFAQ 4.2.0-beta, PHP 8.4, SQLite, API enabled (default).

  1. Insert one hidden and one public open question, language en.
  2. Leave api.onlyPublicQuestions=true (default).
  3. Unauthenticated:

GET /api/v4.0/open-questions HTTP/1.1 Accept-Language: en

Observed: JSON data contains both rows, including isVisible: false and the hidden question text/username.

  1. GET /open-questions.html shows only the public question.
  2. Set api.onlyPublicQuestions=false and repeat step 3: API returns only the public row (flag is inverted).

Impact

Any internet client can read open questions administrators marked non-public (moderation / internal asks) and the associated usernames.

Text from GitHub Advisory Database

Affected versions 1

  • phpMyFAQ< 4.2.0-alpha.2GitHub