VYPR
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.

PackageAffected versionsPatched versions
nabeel/phpvmsPackagist
< 7.0.67.0.6

Affected products

1

Patches

1
f59ba8e0e8fc

Merge commit from fork

https://github.com/phpvms/phpvmsNabeel S.Apr 23, 2026via ghsa
11 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

News mentions

0

No linked articles in our index yet.