Dolibarr/dolibarr · error
Access to this page this way (POST method or GET with a…
Error message
Access to this page this way (POST method or GET with a sensible value for 'action' parameter) is refused by CSRF protection in main.inc.php. Token not provided.
What it means
The generic CSRF refusal in main.inc.php: a state-changing request (POST, or GET with a meaningful 'action' parameter) arrived without a token on a page that did not declare CSRFCHECK_WITH_TOKEN. Dolibarr returns 403 to prevent cross-site request forgery.
Solutions
- Include the token: POST field or GET 'token' parameter from newToken() matching the current session
- Use Dolibarr's REST API (api token) for programmatic access instead of form endpoints
- Ensure the user session is active and stable (same Dolibarr instance) when the form is submitted
- As a last resort, tune MAIN_SECURITY_CSRF_WITH_TOKEN (not recommended) or set $dolibarr_nocsrfcheck in conf.php for trusted contexts
Example fix
// before curl -d 'action=update&id=15' https://doli.example.com/htdocs/societe/card.php // after curl -d 'action=update&id=15&token='$TOKEN https://doli.example.com/htdocs/societe/card.php
Defensive patterns
Strategy: fallback
Validate before calling
if (($_SERVER['REQUEST_METHOD']==='POST' || isset($_GET['action'])) && empty($_REQUEST['token'])) { die('Token required before calling Dolibarr'); } Prevention
- Always append token='.newToken() to action URLs and add the token field to POST forms
- Use the REST API (DOLAPIKEY) for scripts instead of form endpoints
- Keep the browser session alive between rendering and submitting forms
- After login/logout the old token is invalid — refetch the page
When it happens
Trigger: POST to any main.inc.php-protected page without token parameter; GET request with action=add/confirm/update etc. and no token; external form or curl script posting into Dolibarr endpoints.
Common situations: REST/curl scripts posting to page endpoints instead of the REST API; embedding Dolibarr forms in third-party sites; session regenerated (login) making the old token invalid; load-balanced setup with mismatched sessions.
Related errors
- Access to a page that needs a token (constant…
- If you access your server behind a proxy using url…
- ErrorFileSizeTooLarge ErrorGoBackAndCorrectParameters
- ErrorLoginMustBePostMethod
- Access refused by CSRF protection in main.inc.php. Referrer…
AI-assisted analysis of Dolibarr/dolibarr@598aa4bdad (2026-09-14).
Data as JSON: /api/errors/cbf3e272652c95e3.
Report an issue: GitHub.
Appendix: source
Thrown at htdocs/main.inc.php:443
GETPOSTISSET('massaction') ||
((GETPOSTISSET('actionlogin') || GETPOSTISSET('action')) && defined('CSRFCHECK_WITH_TOKEN'))
) {
// If token is not provided or empty, error (we are in case it is mandatory)
if (!GETPOST('token', 'alpha') || GETPOST('token', 'alpha') == 'notrequired') {
top_httphead();
if (GETPOSTINT('uploadform')) {
dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused. File size too large or not provided.");
$langs->loadLangs(array("errors", "install"));
print $langs->trans("ErrorFileSizeTooLarge").' ';
print $langs->trans("ErrorGoBackAndCorrectParameters");
} else {
http_response_code(403);
if (defined('CSRFCHECK_WITH_TOKEN')) {
dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused by CSRF protection (CSRFCHECK_WITH_TOKEN protection) in main.inc.php. Token not provided.", LOG_WARNING);
print "Access to a page that needs a token (constant CSRFCHECK_WITH_TOKEN is defined) is refused by CSRF protection in main.inc.php. Token not provided.\n";
} else {
dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused by CSRF protection (POST method or GET with a sensible value for 'action' parameter) in main.inc.php. Token not provided.", LOG_WARNING);
print "Access to this page this way (POST method or GET with a sensible value for 'action' parameter) is refused by CSRF protection in main.inc.php. Token not provided.\n";
print "If you access your server behind a proxy using url rewriting and the parameter is provided by caller, you might check that all HTTP header are propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file or MAIN_SECURITY_CSRF_WITH_TOKEN to 0";
if (getDolGlobalString('MAIN_SECURITY_CSRF_WITH_TOKEN')) {
print " instead of " . getDolGlobalString('MAIN_SECURITY_CSRF_WITH_TOKEN');
}
print " into setup).\n";
}
}
die;
}
}
$sessiontokenforthisurl = (empty($_SESSION['token']) ? '' : $_SESSION['token']);
// TODO Get the sessiontokenforthisurl into an array of session token (one array per base URL so we can use the CSRF per page and we keep ability for several tabs per url in a browser)
if (GETPOSTISSET('token') && GETPOST('token') != 'notrequired' && GETPOST('token', 'alpha') != $sessiontokenforthisurl) {
dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused by CSRF protection (invalid token), so we disable POST and some GET parameters - referrer=".(empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER']).", action=".GETPOST('action', 'aZ09').", _GET|POST['token']=".GETPOST('token', 'alpha'), LOG_WARNING);
//dol_syslog("_SESSION['token']=".$sessiontokenforthisurl, LOG_DEBUG);
// Do not output anything on standard output because this create problems when using the BACK button on browsers. So we just set a message into session.
if (!defined('NOTOKENRENEWAL')) {View on GitHub (pinned to 598aa4bdad)