Critical severity9.4GHSA Advisory· Published May 9, 2026· Updated May 13, 2026
CVE-2026-42569
CVE-2026-42569
Description
phpVMS is a PHP application to run and simulate an airline. Prior to version 7.0.6, a critical vulnerability in phpVMS allowed unauthenticated access to a legacy import feature. This issue has been patched in version 7.0.6.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
nabeel/phpvmsPackagist | < 7.0.6 | 7.0.6 |
Affected products
1Patches
111 files changed · +11 −453
app/Providers/RouteServiceProvider.php+0 −19 modified@@ -28,29 +28,10 @@ public function map() $this->mapWebRoutes(); $this->mapAdminRoutes(); $this->mapApiRoutes(); - $this->mapImporterRoutes(); $this->mapInstallerRoutes(); $this->mapUpdaterRoutes(); } - private function mapImporterRoutes() - { - Route::group([ - 'as' => 'importer.', - 'prefix' => 'importer', - 'middleware' => ['web'], - 'namespace' => 'App\Http\Controllers\System', - ], function () { - Route::get('/', 'ImporterController@index')->name('index'); - Route::post('/config', 'ImporterController@config')->name('config'); - Route::post('/dbtest', 'ImporterController@dbtest')->name('dbtest'); - - // Run the actual importer process. Additional middleware - Route::post('/run', 'ImporterController@run')->middleware('api')->name('run'); - Route::post('/complete', 'ImporterController@complete')->name('complete'); - }); - } - private function mapInstallerRoutes() { Route::group([
mise.toml+11 −0 added@@ -0,0 +1,11 @@ +[tools] +php = '8.4' + +[settings] +# keep downloaded archive/source files for debugging +always_keep_download = false # deleted after install; not a cache +always_keep_install = false # deleted on failure by default + +trusted_config_paths = [ + '.', +]
resources/views/system/importer/app.blade.php+0 −90 removed@@ -1,90 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - -<head> - <meta charset="utf-8"/> - <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> - <meta name="csrf-token" content="{{ csrf_token() }}"> - - <title>@yield('title') - installer</title> - - <link rel="shortcut icon" type="image/png" href="{{ public_asset('/assets/img/favicon.png') }}"/> - - <meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no' - name='viewport'/> - <meta name="base-url" content="{!! url('') !!}"> - <meta name="api-key" content="{!! Auth::check() ? Auth::user()->api_key: '' !!}"> - <meta name="csrf-token" content="{!! csrf_token() !!}"> - - <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700,200" rel="stylesheet"/> - <link href="https://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css" rel="stylesheet"/> - - <link href="{{ public_asset('/assets/frontend/css/bootstrap.min.css') }}" rel="stylesheet"/> - <link href="{{ public_asset('/assets/frontend/css/now-ui-kit.css') }}" rel="stylesheet"/> - <link href="{{ public_asset('/assets/installer/css/vendor.css') }}" rel="stylesheet"/> - <link href="{{ public_asset('/assets/frontend/css/styles.css') }}" rel="stylesheet"/> - - <link rel="stylesheet" - href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"> - - <style> - .table tr:first-child td { - border-top: 0px; - } - @yield('css') - </style> -</head> - -<body class="login-page" style="background: #067ec1;"> -<div class="page-header clear-filter"> - <div class="content"> - <div class="container"> - <div class="row"> - <div class="col-md-8 ml-auto mr-auto content-center"> - <div class="p-10" style="padding: 10px 0;"> - <div class="row"> - <div class="col-4"> - <img src="{{ public_asset('/assets/img/logo_blue_bg.svg') }}" width="135px" style="" alt=""/> - </div> - <div class="col-8 text-right"> - <h4 class="text-white mb-0 mr-0 ml-0" style="margin-top: 5px;">@yield('title')</h4> - </div> - </div> - </div> - <div class="card card-login card-plain" style="background: #FFF"> - <div class="card-body"> - @include('system.importer.flash.message') - @yield('content') - </div> - </div> - </div> - </div> - </div> - </div> -</div> - -{{--<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>--}} - -<script src="{{ public_mix('/assets/global/js/vendor.js') }}"></script> -<script src="{{ public_mix('/assets/installer/js/vendor.js') }}"></script> -<script src="{{ public_mix('/assets/installer/js/app.js') }}"></script> -<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script> - -<script> - hljs.configure({languages: ['sh']}); - - $(document).ready(function () { - - $(".select2").select2(); - - $('pre code').each(function (i, block) { - hljs.fixMarkup(block); - hljs.highlightBlock(block); - }); - }); -</script> - -@yield('scripts') - -</body> -</html>
resources/views/system/importer/complete.blade.php+0 −18 removed@@ -1,18 +0,0 @@ -@extends('system.importer.app') -@section('title', 'Import Completed!') - -@section('content') - <div style="align-content: center;"> - <form method="get" action="{{ route('importer.complete') }}"> - @csrf - <h4>Installer Completed!</h4> - - <p>Edit the <span class="code">config.php</span> to fill in some additional settings. </p> - <p>Click the button to proceed to the login screen!</p> - - <p style="text-align: right"> - <button type="submit" class="btn btn-success">Import Complete! Continue to Log-In >></button> - </p> - </form> - </div> -@endsection
resources/views/system/importer/dbtest.blade.php+0 −8 removed@@ -1,8 +0,0 @@ -<div class="alert alert-{{ $status }}" role="alert"> - <div class="container"> - <div class="alert-icon"> - <i class="now-ui-icons ui-1_bell-53"></i> - </div> - {{ $message }} - </div> -</div>
resources/views/system/importer/error.blade.php+0 −9 removed@@ -1,9 +0,0 @@ -@extends('system.importer.app') -@section('title', 'Import Error!') - -@section('content') - <div style="align-content: center;"> - <h4>Error!</h4> - <p class="text-danger">{{ $error }}</p> - </div> -@endsection
resources/views/system/importer/flash/check_error.blade.php+0 −6 removed@@ -1,6 +0,0 @@ -@if($errors->has($field)) - <p class="text-danger" style="margin-top: 10px;">{{ $errors->first($field) }}</p> - {{--<div class="alert alert-danger" role="alert" style="margin-top: 10px;"> - {{ $errors->first($field) }} - </div>--}} -@endif
resources/views/system/importer/flash/message.blade.php+0 −11 removed@@ -1,11 +0,0 @@ -@foreach (session('flash_notification', collect())->toArray() as $message) - <div class="alert alert-danger" role="alert"> - <div class="container"> - <div class="alert-icon"> - <i class="now-ui-icons ui-2_like"></i> - </div> - {{ $message['message'] }} - </div> - </div> -@endforeach -{{ session()->forget('flash_notification') }}
resources/views/system/importer/step1-configure.blade.php+0 −132 removed@@ -1,132 +0,0 @@ -@extends('system.importer.app') -@section('title', 'Import Configuration') - -@section('content') - <div style="align-content: center;"> - <form method="post" action="{{ route('importer.config') }}"> - @csrf - <table class="table"> - <tr> - <td colspan="2"> - <h4>IMPORTANT NOTES</h4> - <ul> - <li>The first user's password (admin) will be "admin". Please change it after logging in</li> - <li>User passwords will be reset and they will need to use "Forgot Password" to reset it</li> - <li>If you have more than 1000 PIREPs or flights, it's best to use the command-line importer! - <a href="{{ docs_link('importing_legacy') }}" target="_blank">Click here</a> to - see the documentation of how to use it. - </li> - <li><strong>THIS WILL WIPE OUT YOUR EXISTING DATA</strong> - this is required to make sure that - things like - pilot IDs match up - </li> - </ul> - </td> - </tr> - - <tr> - <td colspan="2"> - <h4>Database Config</h4> - <p>Enter the database information for your legacy phpVMS installation</p> - </td> - </tr> - - <tbody id="mysql_settings"> - <tr> - <td>Database Host</td> - <td style="text-align:center;"> - <div class="form-group"> - <input type="text" name="db_host" value="127.0.0.1" class="form-control" /> - </div> - </td> - </tr> - - <tr> - <td>Database Port</td> - <td style="text-align:center;"> - <div class="form-group"> - <input type="text" name="db_port" value="3306" class="form-control" /> - </div> - </td> - </tr> - - <tr> - <td>Database Name</td> - <td style="text-align:center;"> - <div class="form-group"> - <input type="text" name="db_name" value="phpvms" class="form-control" /> - </div> - </td> - </tr> - - <tr> - <td>Database User</td> - <td style="text-align:center;"> - <div class="form-group"> - <input type="text" name="db_user" class="form-control" /> - </div> - </td> - </tr> - - <tr> - <td>Database Password</td> - <td style="text-align:center;"> - <div class="form-group"> - <input type="text" name="db_pass" class="form-control" /> - </div> - </td> - </tr> - - <tr> - <td colspan="2" style="text-align: right;"> - <button type="submit" class="btn btn-info" id="dbtest_button">Test Database - Credentials</button> - </td> - </tr> - </tbody> - - <tr> - <td>Database Prefix</td> - <td style="text-align:center;"> - <div class="form-group"> - <input type="text" name="db_prefix" value="phpvms_" class="form-control" /> - <p>Prefix of the tables, if you're using one</p> - </div> - </td> - </tr> - - </table> - <div id="dbtest"></div> - <p style="text-align: right"> - <button type="submit" class="btn btn-success">Start Importer >></button> - </p> - </form> - </div> -@endsection - -@section('scripts') - <script> - $(document).ready(() => { - $("#dbtest_button").click((e) => { - e.preventDefault(); - const opts = { - method: 'POST', - url: '/importer/dbtest', - data: { - _token: "{{ csrf_token() }}", - db_conn: 'mysql', - db_host: $("input[name=db_host]").val(), - db_port: $("input[name=db_port]").val(), - db_name: $("input[name=db_name]").val(), - db_user: $("input[name=db_user]").val(), - db_pass: $("input[name=db_pass]").val(), - }, - }; - - phpvms.request(opts).then(response => { - $("#dbtest").html(response.data); - }); - }); - }); - </script> -@endsection
resources/views/system/importer/step2-processing.blade.php+0 −154 removed@@ -1,154 +0,0 @@ -@extends('system.importer.app') -@section('title', 'Import Configuration') - -@section('content') - <div style="align-content: center;"> - <form method="post" action="{{ route('importer.complete') }}"> - @csrf - <table class="table" width="25%"> - - <tr> - <td colspan="2"><h4>Running Importer</h4></td> - </tr> - - <tr> - <td colspan="2"> - <div class="progress"> - <div id="progress" class="progress-bar" style="width: 0%"></div> - </div> - <div> - <p id="message" style="margin-top: 7px;"></p> - <p id="error" class="text-danger" style="margin-top: 7px;"></p> - </div> - </td> - </tr> - - </table> - <p style="text-align: right"> - <button type="submit" class="btn btn-success" id="completebutton">Complete Import</button> - </p> - </form> - </div> -@endsection - -@section('scripts') - <script> - const manifest = {!!json_encode($manifest) !!}; - - /** - * Run each step of the importer - */ - async function startImporter() { - let current = 1; - const total_steps = manifest.length; - - /** - * Update the progress bar - */ - const setProgress = (current, message) => { - const percent = Math.round(current / total_steps * 100); - $("#progress").css("width", `${percent}%`); - $("#message").text(message); - }; - - /** - * Sleep for a given interval - */ - const sleep = (timeout) => { - return new Promise((resolve, reject) => { - setTimeout(() => { - resolve(); - }, timeout); - }); - }; - - const setError = (error) => { - let message = ''; - if (error.response) { - // The request was made and the server responded with a status code - // that falls out of the range of 2xx - console.log(error.response.data); - console.log(error.response.status); - console.log(error.response.headers); - - message = error.response.data.message; - - } else if (error.request) { - // The request was made but no response was received - // `error.request` is an instance of XMLHttpRequest in the browser and an instance of - // http.ClientRequest in node.js - console.log(error.request); - message = error.request; - } else { - // Something happened in setting up the request that triggered an Error - console.log('Error', error.message); - message = error.message; - } - - $("#error").text(`Error processing, check the logs: ${message}`); - console.log(error.config); - }; - - /** - * Call the endpoint as a POST - */ - const runStep = async function (stage) { - setProgress(current, stage.message); - - try { - return await phpvms.request({ - method: 'post', - url: '/importer/run', - data: { - importer: stage.importer, - start: stage.start, - } - }); - } catch (e) { - - if (e.response.status === 504) { - const err = $("#error"); - - console.log('got timeout, retrying'); - err.text(`Timed out, attempting to retry`); - - // await sleep(5000); - const val = await runStep(stage); - - err.text(''); - - return val; - } - - setError(e); - throw e; - } - }; - - let errors = false; - const complete_button = $("#completebutton"); - complete_button.hide(); - - for (let stage of manifest) { - console.log(`Running ${stage.importer} step ${stage.start}`); - try { - await runStep(stage); - } catch (e) { - errors = true; - break; - } - - current++; - } - - if (!errors) { - $("#message").text('Done!'); - complete_button.show(); - } - } - - $(document).ready(() => { - startImporter(); - }); - </script> -@endsection
resources/views/system/installer/install/steps/step3-user.blade.php+0 −6 modified@@ -9,12 +9,6 @@ @csrf <table class="table" width="25%"> - <tr> - <td colspan="2" style="text-align: right"> - <a href="{{ route('importer.index') }}">Importing from a legacy install?</a> - </td> - </tr> - <tr> <td colspan="2"> <h4>Airline Information</h4>
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-fv26-4939-62fhghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-42569ghsaADVISORY
- github.com/phpvms/phpvms/commit/f59ba8e0e8fc25c60c3faf14e526cfd49df3f7dcnvdWEB
- github.com/phpvms/phpvms/releases/tag/7.0.6nvdWEB
- github.com/phpvms/phpvms/releases/tag/7.0.7nvdWEB
- github.com/phpvms/phpvms/security/advisories/GHSA-fv26-4939-62fhnvdWEB
News mentions
0No linked articles in our index yet.