Dolibarr/dolibarr · error · Exception

Security injection exception

Error message

Security injection exception: ${message}

What it means

Same WAF detection as the 403 case, but this branch runs when Dolibarr detects it is executing under PHPUnit (class PHPUnit\Framework\TestSuite exists). Instead of exit, analyseVarsForSqlAndScriptsInjection throws a plain Exception with the 'Security injection exception: ...' message so tests can assert on it. Production code never sees this exception — production just exits with 403.

Solutions

  1. In tests, wrap the call in a try/catch (Exception) and assert the message starts with 'Security injection exception:'.
  2. Clean your test fixtures: remove SQL/script-looking strings from GET/POST simulation, or set the variables the WAF considers safe.
  3. If testing the WAF itself, expect this exception and catch it; do not rely on exit codes as in production.
  4. Ensure NOSCANPHPUSENUMPARAMS-type guards or define('NOSCANPOSTFORINJECTION') in test bootstrap only if the test legitimately needs raw payloads.

Example fix

// before
$this->callMainIncWithMaliciousVar();
// after
try {
    $this->callMainIncWithMaliciousVar();
    $this->fail('WAF did not trigger');
} catch (Exception $e) {
    $this->assertStringContainsString('Security injection exception', $e->getMessage());
}
Defensive patterns

Strategy: try-catch

Validate before calling

// test bootstrap: detect PHPUnit context and pre-scan simulated superglobals
if (class_exists('PHPUnit\Framework\TestSuite')) {
    foreach ($_GET + $_POST as $k => $v) {
        if (!is_string($v)) continue;
        if (preg_match('/<\s*script|union\s+select/i', $v)) {
            unset($_GET[$k], $_POST[$k]);
        }
    }
}

Type guard

function isWafTestException(Throwable $e): bool {
    return $e instanceof Exception && str_starts_with($e->getMessage(), 'Security injection exception:');
}

Try / catch

try {
    $this->bootMainInc();
} catch (Exception $e) {
    if (str_starts_with($e->getMessage(), 'Security injection exception:')) {
        $this->markTestSkipped('Payload rejected by WAF: '.$e->getMessage());
    }
    throw $e;
}

Prevention

When it happens

Trigger: Running Dolibarr PHPUnit tests (e.g. test/unit framework) with a request/variable containing injection-pattern content, so the WAF throws instead of exiting; also triggered by tests that deliberately post malicious payloads to verify the WAF.

Common situations: Writing or running Dolibarr core test suites; custom test harnesses that bootstrap main.inc.php under PHPUnit; a test fixture whose data accidentally contains script/SQL patterns.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of Dolibarr/dolibarr@598aa4bdad (2026-09-14). Data as JSON: /api/errors/48e312285c3ec08a. Report an issue: GitHub.

Appendix: source

Thrown at htdocs/waf.inc.php:302

					print "<br>\n";
					print 'Try to go back, fix data of your form and resubmit it. You can contact also your technical support.';

					print "\n".'<!--'."\n";
					print $errormessage2;
					print "\n".'-->';

					// Add entry into the PHP server error log
					if (function_exists('error_log')) {
						error_log($errormessage.' '.substr($errormessage2, 2000));
					}

					// Note: No addition into security audit table is done because we don't want to execute code in such a case.
					// Detection of too many such requests can be done with a fail2ban rule on 403 error code or into the PHP server error log.


					if (class_exists('PHPUnit\Framework\TestSuite')) {
						$message = $errormessage.' '.substr($errormessage2, 2000);
						throw new Exception("Security injection exception: $message");
					}
					exit;
				} else {
					return false;
				}
			}
		}
		return true;
	} else {
		return (testSqlAndScriptInject($var, $type) <= 0);
	}
}

// Prevent the use of method TRACE in case of the web server authorizes it (some do it by default). TRACE method can be used by attacker to steal cookies or other sensitive information.
if (!empty($_SERVER["REQUEST_METHOD"]) && $_SERVER["REQUEST_METHOD"] == "TRACE") {
	print 'Access refused with request method TRACE';
	http_response_code(405);
	exit();

View on GitHub (pinned to 598aa4bdad)