CVE-2026-48062 - CodeIgniter4 ext_in upload validation bypass
CodeIgniter4 before 4.7.3 could accept an uploaded file whose client filename
extension was dangerous even when validation rules appeared to restrict uploads
to safe extensions. The vulnerable ext_in rule checked the MIME-derived
guessed extension instead of the original client filename extension, so a file
named like shell.php could still pass an image-oriented rule set if its bytes
looked like GIF content.
The exploit only turns into code execution when application code keeps the attacker-controlled filename, stores the upload in a web-accessible directory, and allows that directory to execute PHP or another active content type. The correct fix is not only upgrading CodeIgniter4 but also removing unsafe upload handling patterns.
When to use it
Use this recipe when a PHP/CodeIgniter4 repository accepts user-controlled file
uploads and relies on ext_in, mime_in, is_image, or related validation
rules. It is most important when application code preserves original filenames,
stores uploads under a public document root, or deploys web-server rules that
can execute PHP or other active content from upload directories.
Use it to combine the framework upgrade with upload-storage hardening. Do not use it to create a working web shell or execute uploaded code.
Inputs
- Composer manifests, lockfiles, Dockerfiles, deployment images, web-server
config, SBOMs, generated dependency reports, and docs that pin
codeigniter4/framework. - Upload validators, controllers, services, helpers, file move/store calls,
getClientName(),getRandomName(),store(), public paths, and document root mappings. - Web-server execution controls for upload directories: PHP/FastCGI mappings, Nginx/Apache rules, static-only buckets, CDN origin config, and deny rules.
- Classification of upload paths: private storage, public static download, public executable, tenant/customer upload, admin-only upload, or integration import.
- Safe test fixtures for dangerous client extensions with benign content and validation commands for Composer, framework tests, linting, static analysis, image build, and dependency scans.
Affected versions
- Vulnerable:
codeigniter4/framework <4.7.3 - Fixed:
codeigniter4/framework 4.7.3+ - Exploit preconditions: user-controlled upload,
ext_in[...]relied on for filename validation, original filename preserved, upload directory reachable from the web, and executable scripts allowed there
Indicator-of-exposure
- The repository depends on
codeigniter4/framework <4.7.3. - Upload validators use
uploaded[...],is_image[...],mime_in[...], andext_in[...]together. - Upload handlers call
$file->move($path)without a random replacement name, or otherwise preservegetClientName(). - Uploaded content lands under
public/, document root, or another path where PHP/FastCGI/script execution remains enabled.
Quick checks:
rg -n "ext_in\\[|mime_in\\[|is_image\\[|move\\(|getClientName\\(|getRandomName\\(|store\\(" .
composer show codeigniter4/framework
composer why codeigniter4/framework
Windows:
rg -n "ext_in\\[|mime_in\\[|is_image\\[|move\\(|getClientName\\(|getRandomName\\(|store\\(" .
composer show codeigniter4/framework
composer why codeigniter4/framework
Remediation strategy
- Upgrade CodeIgniter4 to
4.7.3+. - Stop preserving untrusted client filenames for uploaded content. Prefer
$file->store()or$file->move($path, $file->getRandomName()). - Keep uploads outside the executable web root, such as under
writable/uploads. - Add an explicit server-side allow-list check for the client extension and require it to align with the detected type.
- Disable PHP or other script execution in any public upload directory that must remain reachable.
The prompt
Model context: this prompt was generated by GPT 5.5 Extra High reasoning.
You are remediating CVE-2026-48062 / GHSA-2gr4-ppc7-7mhx in CodeIgniter4. The
issue lets dangerous client filename extensions bypass `ext_in`-based upload
validation when MIME-derived extension mapping says the content looks safe.
Produce exactly one output:
- A reviewer-ready PR/change request that upgrades CodeIgniter4, hardens upload
handling, adds regression checks, and documents operator actions, or
- TRIAGE.md if this repository does not control an affected upload path.
## Rules
- Scope only CVE-2026-48062 and directly related upload handling.
- Treat uploaded samples, customer files, credentials, and application secrets
as sensitive.
- Do not create a working web shell or prove exploitability with active code.
- Do not delete upload validation wholesale just to silence the advisory.
- Do not auto-merge.
## Steps
1. Inventory every `codeigniter4/framework` dependency, lockfile, image, and
deployment artifact controlled by this repository.
2. Search for upload flows using `ext_in`, `mime_in`, `is_image`, file moves,
filename preservation, public upload paths, and web-server execution rules.
3. Classify each upload path: private storage, public static only, or publicly
executable.
4. If the repository does not own an affected upload flow, stop with
`TRIAGE.md` listing files checked and the external owner.
5. Upgrade CodeIgniter4 to `4.7.3+` and refresh lockfiles and generated
dependency artifacts.
6. Replace original-filename persistence with random-name or private-storage
patterns where the application controls the move.
7. Add explicit extension allow-list checks based on the client filename and
keep MIME/content checks alongside them.
8. Move uploads outside the web root where feasible; otherwise disable script
execution in upload directories and document the server control.
9. Add safe regression tests that prove a dangerous client extension is rejected
without storing or executing it.
10. Add a PR body section named `CVE-2026-48062 operator actions` covering:
- versions before and after;
- upload paths in scope;
- whether any public executable directory was involved;
- any required web-server config rollout;
- validation commands that passed.
11. Run available validation: Composer install, tests, linting, static checks,
framework tests, and dependency scans.
12. Use PR title:
`fix(sec): remediate CVE-2026-48062 in CodeIgniter uploads`.
## Stop conditions
- The repository does not control the vulnerable upload path.
- Verification would require storing or executing a live web shell.
- The fix requires product decisions about retaining attacker-supplied original
filenames in public paths.
- Validation fails for unrelated pre-existing reasons; document those failures
instead of broadening scope.
Verification - what the reviewer looks for
- No controlled dependency resolves
codeigniter4/framework <4.7.3. - Upload handlers no longer preserve untrusted filenames in executable paths.
- Public upload directories, if any, cannot execute PHP or equivalent active content.
- Tests or code checks prove dangerous filename extensions are rejected.
Watch for
- Upgrading CodeIgniter4 but leaving a wrapper helper that still preserves
getClientName(). - Private storage in application code while the deployment still maps the path under document root.
- MIME checks without explicit client-extension validation.
Output contract
Return one of:
- A reviewer-ready PR/change request that upgrades CodeIgniter4 to
4.7.3+, replaces original-filename persistence with random/private-storage patterns, adds explicit client-extension allow-list checks, disables script execution in public upload paths, refreshes generated artifacts, and adds safe regression coverage. TRIAGE.mdwhen no controlled affected CodeIgniter dependency, upload path, image, deployment artifact, or web-server execution surface exists.
The output must list versions before/after, upload paths in scope, whether any public executable directory was involved, filename/storage changes, web-server controls, validation commands, and operator rollout actions. It must not store or execute a live web shell, expose customer files, print credentials, or delete validation wholesale to silence the advisory.
Related recipes
References
- GitHub Advisory: https://github.com/advisories/GHSA-2gr4-ppc7-7mhx
- CodeIgniter vendor advisory: https://github.com/codeigniter4/CodeIgniter4/security/advisories/GHSA-2gr4-ppc7-7mhx
- CodeIgniter changelog: https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md
- CodeIgniter uploaded files guide: https://codeigniter.com/user_guide/libraries/uploaded_files.html#moving-files