Enviar #911004: Gibbon Gibbon (GibbonEdu core) 30.0.01 Missing Authenticationinformación

TítuloGibbon Gibbon (GibbonEdu core) 30.0.01 Missing Authentication
DescripciónGibbon v30.0.01 exposes modules/Planner/units_add_blockAjax.php without any authorization check. The file self-bootstraps ../../gibbon.php and so never passes through index.php's isActionAccessible() gate. An unauthenticated HTTP GET returns the full contents of any gibbonUnitBlock row selected by integer ID, including the staff-only teachersNotes field. CLASS AND SCORE CWE-306 (Missing Authentication for Critical Function). CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N = 5.3 Read-only, medium severity, and I do not want it overstated: no student PII, no credentials, no write access, no RCE. One table, five columns. AFFECTED - v30.0.01, current stable (2026-02-06), commit b3b0219f49f2328508b989afd7e9b0843450cb9f - exploited live. - Default branch v31.0.00 (pushed 2026-07-26): the sink file is BYTE-IDENTICAL. I fetched it at ref=v31.0.00 via the contents API today (blob 03a64576a8308cce176d59d10c77a7de9661e223, 2325 bytes) and diffed against my v30.0.01 copy: zero differences, no isActionAccessible, no gibbonPersonID. The path was last modified 2024-02-23 (298f1dbc, a $_GET null-coalesce refactor) and has never received an authorization commit. The v31.0.00 changelog's "Security" section is empty. AFFECTED FILE AND PARAMETERS modules/Planner/units_add_blockAjax.php - parameters gibbonUnitBlockID (record selector) and mode (how much of the record is rendered); the makeBlock() call is at line 71. ENTRY POINT: GET /modules/Planner/units_add_blockAjax.php?id=1&mode=embed&gibbonUnitBlockID=<n> THE DATA IS STAFF-ONLY BY THE PRODUCT'S OWN PERMISSION MODEL gibbonAction 0000661 Unit Planner_all / 0000662 Unit Planner_learningAreas: Staff=Y Student=N Parent=N, granted only to roles Administrator and Teacher PROOF OF CONCEPT (verbatim from my own run on 2026-07-30) Environment: the v30.0.01 tree on PHP 8.2 + Apache with MariaDB 10.11, loaded with the project's SHIPPED gibbon.sql schema and gibbon_demo.sql demo dataset. config.php contains only database credentials and $guid - no non-default setting, no feature flag, no .htaccess change. Planner is active in the shipped schema (gibbonModule 0009, active='Y'). Instance reported 30.0.01. One canary row stands in for a lesson block created by a teacher: gibbonUnitBlockID 424242, title 'PG17-CANARY-TITLE', contents '<p>PG17_SECRET_LESSON_CONTENT_a91f</p>', teachersNotes '<p>PG17_PRIVATE_TEACHER_NOTE_b73c</p>'. NEGATIVE CONTROL A - the normal route refuses the same anonymous client: GET /index.php?q=/modules/Planner/units.php -> HTTP 200 serving the login form; 0 x PG17_ NEGATIVE CONTROL B - a GUARDED sibling AJAX file in the SAME module refuses it: GET /modules/Planner/resources_addQuick_ajax.php?gibbonUnitBlockID=424242 -> "This page requires you to be logged in to access it. Please login and try again." That is exactly the behaviour the vulnerable file is missing. Same bootstrap, same module, same anonymous request. resources_addQuick_ajax.php begins with the $session->has('gibbonPersonID') guard; units_add_blockAjax.php has none. NEGATIVE CONTROL C - the exploit request minus the exploit primitive: ?id=1&mode=embed and ?id=1&mode=embed&gibbonUnitBlockID=999999 -> 0 occurrences of PG17 The output really is database-driven; only a valid gibbonUnitBlockID yields data. EXPLOIT - no cookie, no Authorization header, no CSRF token (confirmed with curl -v): GET /modules/Planner/units_add_blockAjax.php?id=1&mode=embed&gibbonUnitBlockID=424242 HTTP/1.1 200 OK Content-Length: 1932 <input readonly ... value='PG17-CANARY-TITLE'> <input ... value='Discussion'> <... value='45'> <div>Block Contents</div><div><p><p>PG17_SECRET_LESSON_CONTENT_a91f</p></p></div> <div>Teacher's Notes</div> <div style='background-color: #F6CECB'><p><p>PG17_PRIVATE_TEACHER_NOTE_b73c</p></p></div> The teacher's notes are rendered in the product's own staff-only highlighted style. MODE MATRIX - every request unauthenticated no mode parameter, or mode=masterAdd -> teachersNotes leaks mode=masterEdit / plannerEdit / workingEdit / workingDeploy / embed / any other value -> teachersNotes + full lesson contents The teacher's-notes leak needs no parameter tuning at all. ENUMERATION - sequential integer IDs, against the project's own shipped demo curriculum 39667 "Want To Make Some Eye Candy?" 39668 "Assessment" 39669 "Getting Started With Acorn" 39670 "Find A CC Texture" 39671 "Use Your Texture" Database IDs are 12-digit zero-filled ('000000039667') yet plain integers match, so enumeration from 1 upward works. A real, non-canary teacher's-notes body was also extracted verbatim from gibbonUnitBlockID=39686 (a lesson-preparation note about raster vs vector graphics). CODE-LEVEL CONFIRMATION grep -nE "isActionAccessible|gibbonPersonID" modules/Planner/units_add_blockAjax.php -> no output, NO GUARD, whereas units_edit_working.php:47 and units_edit_deploy.php:47 are both guarded. The only in-tree callers of the vulnerable file are those two authorization-gated staff pages (units_edit_working.php:240,249 mode=workingEdit; units_edit_deploy.php:328,337 mode=workingDeploy). Vendor intent is unambiguously staff-only: mode=embed is invoked nowhere in the tree, docs.gibbonedu.org documents no public-embed feature, and the shipped .htaccess does not restrict direct .php access to modules/. RELATED UNGUARDED ENDPOINTS (same root cause; named so the vendor can fix them together) Enumerating every module file that includes '../../gibbon.php' directly, exactly five lack a guard on v30.0.01 and trunk: Planner/units_add_blockAjax.php (this report, confirmed data-bearing); Students/student_view_details_notes_addAjax.php (same class, data-bearing - reached unauthenticated, but the shipped demo data leaves gibbonStudentNoteCategory.template empty so no meaningful payload was demonstrated); and Planner/units_add_blockOutcomeAjax.php, Planner/planner_editorAjax.php, Rubrics/rubrics_edit_ajax.php (these three reflect only request parameters). Every other AJAX sibling in these modules already carries a guard, which is why this reads as an omission, not a design decision. SUGGESTED FIX Add the guard the sibling files already use at the top of each of the five: $session->has('gibbonPersonID') plus isActionAccessible() for the owning action. PRECONDITION AND SCOPE, STATED HONESTLY The only precondition is that at least one curriculum unit block exists, i.e. a teacher has used the Unit Planner. Nothing else - no non-default setting, no feature flag, no authenticated user. The contents field may in some deployments be visible to enrolled students via the Lesson Planner; the unambiguously staff-restricted field is teachersNotes, and the defect is that the endpoint enforces no authentication at all. No XSS is claimed: gibbon.php sanitises $_GET and the raw-HTML echo in mode=embed renders staff-authored stored content, not attacker input. PRIOR ART - the root-cause CLASS is public, this instance is not CVE-2023-45878 disclosed the same "self-bootstrap gibbon.php, bypass index.php authorization" pattern in modules/Rubrics/rubrics_visualise_saveAjax.php, which now carries the guard. This is a distinct, still-unfixed instance in a different module with different data. Precedent for separate assignment: CVE-2023-45881 was assigned for a separate Planner-module instance alongside it. VENDOR CONTACTED Yes, before this submission: reported privately on 2026-07-30 to [email protected], the address named in the vendor's own .github/SECURITY.md. GitHub private vulnerability reporting is disabled on GibbonEdu/core, so that mailbox is the only private channel. I offered to hold on their timeline, and to withdraw this request if they publish their own advisory. Default window 90 days. DUPLICATE CHECK (re-run from scratch on 2026-07-30) Repository advisories: one entry, GHSA-4mq5-8jvh-qq3p / CVE-2022-27305 (session issue), unrelated. All 19 Gibbon advisories in the GitHub Advisory Database read individually, plus all 20 NVD results for "Gibbon" - none concerns units_add_blockAjax.php, unit blocks, teachersNotes, or unauthenticated information disclosure. Closest prior art is CVE-2023-45878/45881, addressed above; both target different files that now carry guards. Composer advisories: empty. CHANGELOG.txt for v30.0.01/v30.0.00 and the v31.0.00 dev changelog: no entry about authentication on Planner AJAX endpoints. Open and closed issues and PRs searched for units_add_blockAjax, blockAjax, makeBlock, teachersNotes, unauthenticated and missing authentication: all zero. No indexed mention of the filename anywhere. Not documented by the vendor. VALIDATION NOTE Validated against the official released source and the project's own shipped schema and demo dataset, deployed locally in Docker. Not tested against any third party's live instance. All test containers were removed afterwards; the canary values were synthetic strings created by me.
Fuente⚠️ https://github.com/GibbonEdu/core/blob/v31.0.00/modules/Planner/units_add_blockAjax.php
Usuario
 f_asadbek1 (UID 100235)
Sumisión2026-07-30 16:56 (hace 2 meses)
Moderación2026-09-25 10:12 (2 months later)
EstadoAceptado
Entrada de VulDB409878 [GibbonEdu Gibbon hasta 30.0.01 Unit Planner units_add_blockAjax.php makeBlock gibbonUnitBlockID/mode autenticación débil]
Puntos20

Want to know what is going to be exploited?

We predict KEV entries!