{"record":{"id":"a16801a3b90fad14","repo":"Dolibarr/dolibarr","slug":"if-you-access-your-server-behind-a-proxy-using-url-rewriting-a16801","errorCode":null,"errorMessage":"If you access your server behind a proxy using url rewriting, you might check that all HTTP headers are propagated (or add the line $dolibarr_nocsrfcheck=1 into your conf.php file to remove this security check).","messagePattern":"If you access your server behind a proxy using url rewriting, you might check that all HTTP headers are propagated \\(or add the line \\$dolibarr_nocsrfcheck=1 into your conf\\.php file to remove this security check\\)\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"htdocs/filefunc.inc.php","lineNumber":353,"sourceCode":"// See also CSRF protections done into main.inc.php\nif (!defined('NOCSRFCHECK') && isset($dolibarr_nocsrfcheck) && $dolibarr_nocsrfcheck == 1) {    // If $dolibarr_nocsrfcheck is 0, there is a strict CSRF test with token in main\n\tif (!empty($_SERVER['REQUEST_METHOD']) && !in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD')) && !empty($_SERVER['HTTP_HOST'])) {\n\t\t$csrfattack = false;\n\t\tif (empty($_SERVER['HTTP_REFERER'])) {\n\t\t\t$csrfattack = true; // An evil browser was used\n\t\t} else {\n\t\t\t$tmpa = parse_url($_SERVER['HTTP_HOST']);\n\t\t\t$tmpb = parse_url($_SERVER['HTTP_REFERER']);\n\t\t\tif ((empty($tmpa['host']) ? $tmpa['path'] : $tmpa['host']) != (empty($tmpb['host']) ? $tmpb['path'] : $tmpb['host'])) {\n\t\t\t\t$csrfattack = true;\n\t\t\t}\n\t\t}\n\t\tif ($csrfattack) {\n\t\t\t//print 'NOCSRFCHECK='.defined('NOCSRFCHECK').' REQUEST_METHOD='.$_SERVER['REQUEST_METHOD'].' HTTP_HOST='.$_SERVER['HTTP_HOST'].' HTTP_REFERER='.$_SERVER['HTTP_REFERER'];\n\t\t\t// Note: We can't use dol_escape_htmltag here to escape output because lib functions.lib.ph is not yet loaded.\n\t\t\tdol_syslog(\"--- Access to \".(empty($_SERVER[\"REQUEST_METHOD\"]) ? '' : $_SERVER[\"REQUEST_METHOD\"].' ').$_SERVER[\"PHP_SELF\"].\" refused by CSRF protection (Bad referrer).\", LOG_WARNING);\n\t\t\tprint \"Access refused by CSRF protection in main.inc.php. Referrer of form (\".htmlentities(empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'], ENT_COMPAT, 'UTF-8').\") is outside the server that serve this page (with method = \".htmlentities($_SERVER['REQUEST_METHOD'], ENT_COMPAT, 'UTF-8').\").\\n\";\n\t\t\tprint \"If you access your server behind a proxy using url rewriting, you might check that all HTTP headers are propagated (or add the line \\$dolibarr_nocsrfcheck=1 into your conf.php file to remove this security check).\\n\";\n\t\t\tdie;\n\t\t}\n\t}\n\t// Another test is done later on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on.\n}\nif (empty($dolibarr_main_db_host) && !defined('NOREQUIREDB')) {\n\tprint '<div class=\"center\">Dolibarr setup is not yet complete.<br><br>'.\"\\n\";\n\tprint '<a href=\"install/index.php\">Click here to finish Dolibarr install process</a> ...</div>'.\"\\n\";\n\tdie;\n}\nif (empty($dolibarr_main_url_root) && !defined('NOREQUIREVIRTUALURL')) {\n\tprint 'Value for parameter \\'dolibarr_main_url_root\\' is not defined in your \\'htdocs\\conf\\conf.php\\' file.<br>'.\"\\n\";\n\tprint 'You must add this parameter with your full Dolibarr root Url (Example: http://myvirtualdomain/ or http://mydomain/mydolibarrurl/)'.\"\\n\";\n\tdie;\n}\n\nif (empty($dolibarr_main_url_root_alt)) {\n\t$dolibarr_main_url_root_alt = '/custom';","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/Dolibarr/dolibarr/blob/598aa4bdada683d17ca04b1842548821ff0eb6c6/htdocs/filefunc.inc.php#L335-L371","documentation":"This is the advisory second line printed alongside error 26 when the CSRF referrer check fails. It tells the operator the usual root cause (a proxy not propagating headers) and the escape hatch ($dolibarr_nocsrfcheck=1 in conf.php). On its own it never appears; it is emitted by the same die-block in filefunc.inc.php after the main CSRF refusal message.","triggerScenarios":"Same as the CSRF referrer refusal: a POST with a foreign/mismatched HTTP_REFERER, after which the proxy-hint line is printed before die.","commonSituations":"Reverse proxy / load balancer stripping or rewriting Host and Referer; admins searching logs and finding only this hint line; operators considering the conf.php switch without fixing headers.","solutions":["Fix header propagation at the proxy (Host, X-Forwarded-*, Referer) — the proper fix; see error 26 solutions.","Align dolibarr_main_url_root with the URL users actually use.","Only if the setup is trusted and internal, add $dolibarr_nocsrfcheck=1 to htdocs/conf/conf.php to bypass the referrer check.","Verify the fix by reproducing the POST and confirming it is accepted with correct Referer."],"exampleFix":"// before (htdocs/conf/conf.php)\n$dolibarr_main_url_root = 'http://internal-host:8080';\n// after (matches public URL so Referer host matches)\n$dolibarr_main_url_root = 'https://doli.example.com';","handlingStrategy":"fallback","validationCode":"// infra check before blaming the app: does the proxy forward headers?\ncurl -s -o /dev/null -w '%header{host}' -H 'Referer: https://public-host/' https://internal-doli/ ; // compare with expected host","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat this hint line in logs as a signal that proxy header propagation is broken.","Standardize proxy templates: Host, X-Forwarded-Host, X-Forwarded-Proto, Referer are always set.","Avoid the $dolibarr_nocsrfcheck=1 escape hatch unless risk-approved.","Re-test POST flows after any proxy or TLS termination change."],"tags":["csrf","proxy","configuration","referrer"],"backgroundTag":"missing-config-value","analyzedSha":"598aa4bdada683d17ca04b1842548821ff0eb6c6","analyzedAt":"2026-09-14T11:12:15.309Z","contentChangedAt":"2026-09-14T11:12:15.309Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}