CVE-2018-19995
Description
A stored XSS vulnerability in Dolibarr 8.0.2 allows authenticated users to inject arbitrary script via the address or town parameters.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A stored XSS vulnerability in Dolibarr 8.0.2 allows authenticated users to inject arbitrary script via the address or town parameters.
Vulnerability
Dolibarr version 8.0.2 contains a stored cross-site scripting (XSS) vulnerability in the user management module. The address and town POST parameters in user/card.php are passed through GETPOST with the alpha filter, which does not strip HTML tags, allowing injection of arbitrary web script or HTML. The injected payload is stored in the database and later executed when an administrator or other user views the affected user's card [2]. The commit history shows that the fix changed the filter from alpha to alphanohtml for these fields [3][4].
Exploitation
An attacker must be a remote authenticated user with rights to create or edit user profiles. The attacker sends a crafted POST request to user/card.php containing malicious JavaScript or HTML in the address or town parameter. No additional privileges or special network position is required beyond being authenticated [2]. The payload is stored and subsequently rendered without sanitization, triggering the XSS in the browser of any user who views the modified user card [3][4].
Impact
Successful exploitation allows an authenticated attacker to execute arbitrary JavaScript in the context of a victim's session, potentially leading to session hijacking, credential theft, or defacement. The attack can affect other administrators or users who access the infected user profile, and the XSS is persistent in the database [2]. The privilege scope is limited to the application's user interface, but an attacker could perform actions on behalf of the victim if the victim has higher privileges.
Mitigation
The vulnerability is fixed in versions after 8.0.2 by changing the input filter from alpha to alphanohtml in the user creation/editing code path [3][4]. Users should upgrade to a patched version of Dolibarr. There is no known workaround provided by the vendor; however, applying a web application firewall (WAF) rule to block HTML tags in the address and town parameters may serve as a temporary mitigation. Dolibarr is open source and the fix is publicly available in the repository [1].
- GitHub - Dolibarr/dolibarr: Dolibarr ERP CRM is a modern software package to manage your company or foundation's activity (contacts, suppliers, invoices, orders, stocks, agenda, accounting, ...). it's an open source Web application (written in PHP) designed for businesses of any sizes, foundations and freelancers.
- NVD - CVE-2018-19995
- FIX CVE-2018-19995 and CVE-2018-19998 · Dolibarr/dolibarr@bacd511
- FIX CVE-2018-19995 · Dolibarr/dolibarr@4b8be6e
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
dolibarr/dolibarrPackagist | < 8.0.4 | 8.0.4 |
Affected products
2Patches
24b8be6ed6476FIX CVE-2018-19995
1 file changed · +28 −28
htdocs/user/card.php+28 −28 modified@@ -191,31 +191,31 @@ $birth = dol_mktime(0, 0, 0, GETPOST('birthmonth'), GETPOST('birthday'), GETPOST('birthyear')); $object->birth = $birth; $object->admin = GETPOST("admin", 'alpha'); - $object->address = GETPOST('address', 'alpha'); - $object->zip = GETPOST('zipcode', 'alpha'); - $object->town = GETPOST('town', 'alpha'); + $object->address = GETPOST('address', 'alphanohtml'); + $object->zip = GETPOST('zipcode', 'alphanohtml'); + $object->town = GETPOST('town', 'alphanohtml'); $object->country_id = GETPOST('country_id', 'int'); $object->state_id = GETPOST('state_id', 'int'); - $object->office_phone = GETPOST("office_phone", 'alpha'); - $object->office_fax = GETPOST("office_fax", 'alpha'); - $object->user_mobile = GETPOST("user_mobile"); - $object->skype = GETPOST("skype", 'alpha'); + $object->office_phone = GETPOST("office_phone", 'alphanohtml'); + $object->office_fax = GETPOST("office_fax", 'alphanohtml'); + $object->user_mobile = GETPOST("user_mobile", 'alphanohtml'); + $object->skype = GETPOST("skype", 'alphanohtml'); $object->email = preg_replace('/\s+/', '', GETPOST("email", 'alpha')); $object->job = GETPOST("job", 'alpha'); - $object->signature = GETPOST("signature"); - $object->accountancy_code = GETPOST("accountancy_code"); - $object->note = GETPOST("note"); - $object->ldap_sid = GETPOST("ldap_sid"); - $object->fk_user = GETPOST("fk_user") > 0 ? GETPOST("fk_user") : 0; - $object->employee = GETPOST('employee'); - - $object->thm = GETPOST("thm") != '' ? GETPOST("thm") : ''; - $object->tjm = GETPOST("tjm") != '' ? GETPOST("tjm") : ''; - $object->salary = GETPOST("salary") != '' ? GETPOST("salary") : ''; - $object->salaryextra = GETPOST("salaryextra") != '' ? GETPOST("salaryextra") : ''; - $object->weeklyhours = GETPOST("weeklyhours") != '' ? GETPOST("weeklyhours") : ''; - - $object->color = GETPOST("color") != '' ? GETPOST("color") : ''; + $object->signature = GETPOST("signature", 'none'); + $object->accountancy_code = GETPOST("accountancy_code", 'alphanohtml'); + $object->note = GETPOST("note", 'none'); + $object->ldap_sid = GETPOST("ldap_sid", 'alphanohtml'); + $object->fk_user = GETPOST("fk_user", 'int') > 0 ? GETPOST("fk_user", 'int') : 0; + $object->employee = GETPOST('employee', 'alphanohtml'); + + $object->thm = GETPOST("thm", 'alphanohtml') != '' ? GETPOST("thm", 'alphanohtml') : ''; + $object->tjm = GETPOST("tjm", 'alphanohtml') != '' ? GETPOST("tjm", 'alphanohtml') : ''; + $object->salary = GETPOST("salary", 'alphanohtml') != '' ? GETPOST("salary", 'alphanohtml') : ''; + $object->salaryextra = GETPOST("salaryextra", 'alphanohtml') != '' ? GETPOST("salaryextra", 'alphanohtml') : ''; + $object->weeklyhours = GETPOST("weeklyhours", 'alphanohtml') != '' ? GETPOST("weeklyhours", 'alphanohtml') : ''; + + $object->color = GETPOST("color", 'alphanohtml') != '' ? GETPOST("color", 'alphanohtml') : ''; $dateemployment = dol_mktime(0, 0, 0, GETPOST('dateemploymentmonth'), GETPOST('dateemploymentday'), GETPOST('dateemploymentyear')); $object->dateemployment = $dateemployment; @@ -335,22 +335,22 @@ $object->pass = GETPOST("password",'none'); $object->api_key = (GETPOST("api_key", 'alpha')) ? GETPOST("api_key", 'alpha') : $object->api_key; if (! empty($user->admin)) $object->admin = GETPOST("admin"); // admin flag can only be set/unset by an admin user. A test is also done later when forging sql request - $object->address = GETPOST('address', 'alpha'); - $object->zip = GETPOST('zipcode', 'alpha'); - $object->town = GETPOST('town', 'alpha'); + $object->address = GETPOST('address', 'alphanohtml'); + $object->zip = GETPOST('zipcode', 'alphanohtml'); + $object->town = GETPOST('town', 'alphanohtml'); $object->country_id = GETPOST('country_id', 'int'); $object->state_id = GETPOST('state_id', 'int'); - $object->office_phone = GETPOST("office_phone", 'alpha'); - $object->office_fax = GETPOST("office_fax", 'alpha'); - $object->user_mobile = GETPOST("user_mobile"); + $object->office_phone = GETPOST("office_phone", 'alphanohtml'); + $object->office_fax = GETPOST("office_fax", 'alphanohtml'); + $object->user_mobile = GETPOST("user_mobile", 'alphanohtml'); $object->skype = GETPOST("skype", 'alpha'); $object->email = preg_replace('/\s+/', '', GETPOST("email", 'alpha')); $object->job = GETPOST("job", 'alpha'); $object->signature = GETPOST("signature",'none'); $object->accountancy_code = GETPOST("accountancy_code",'alpha'); $object->openid = GETPOST("openid",'alpha'); $object->fk_user = GETPOST("fk_user",'int') > 0 ? GETPOST("fk_user",'int') : 0; - $object->employee = GETPOST('employee'); + $object->employee = GETPOST('employee','alphanothtml'); $object->thm = GETPOST("thm",'alphanohtml') != '' ? GETPOST("thm",'alphanohtml') : ''; $object->tjm = GETPOST("tjm",'alphanohtml') != '' ? GETPOST("tjm",'alphanohtml') : '';
bacd5110fbdcFIX CVE-2018-19995 and CVE-2018-19998
1 file changed · +28 −28
htdocs/user/card.php+28 −28 modified@@ -191,31 +191,31 @@ $birth = dol_mktime(0, 0, 0, GETPOST('birthmonth'), GETPOST('birthday'), GETPOST('birthyear')); $object->birth = $birth; $object->admin = GETPOST("admin", 'alpha'); - $object->address = GETPOST('address', 'alpha'); - $object->zip = GETPOST('zipcode', 'alpha'); - $object->town = GETPOST('town', 'alpha'); + $object->address = GETPOST('address', 'alphanohtml'); + $object->zip = GETPOST('zipcode', 'alphanohtml'); + $object->town = GETPOST('town', 'alphanohtml'); $object->country_id = GETPOST('country_id', 'int'); $object->state_id = GETPOST('state_id', 'int'); - $object->office_phone = GETPOST("office_phone", 'alpha'); - $object->office_fax = GETPOST("office_fax", 'alpha'); - $object->user_mobile = GETPOST("user_mobile"); - $object->skype = GETPOST("skype", 'alpha'); + $object->office_phone = GETPOST("office_phone", 'alphanohtml'); + $object->office_fax = GETPOST("office_fax", 'alphanohtml'); + $object->user_mobile = GETPOST("user_mobile", 'alphanohtml'); + $object->skype = GETPOST("skype", 'alphanohtml'); $object->email = preg_replace('/\s+/', '', GETPOST("email", 'alpha')); $object->job = GETPOST("job", 'alpha'); - $object->signature = GETPOST("signature"); - $object->accountancy_code = GETPOST("accountancy_code"); - $object->note = GETPOST("note"); - $object->ldap_sid = GETPOST("ldap_sid"); - $object->fk_user = GETPOST("fk_user") > 0 ? GETPOST("fk_user") : 0; - $object->employee = GETPOST('employee'); - - $object->thm = GETPOST("thm") != '' ? GETPOST("thm") : ''; - $object->tjm = GETPOST("tjm") != '' ? GETPOST("tjm") : ''; - $object->salary = GETPOST("salary") != '' ? GETPOST("salary") : ''; - $object->salaryextra = GETPOST("salaryextra") != '' ? GETPOST("salaryextra") : ''; - $object->weeklyhours = GETPOST("weeklyhours") != '' ? GETPOST("weeklyhours") : ''; - - $object->color = GETPOST("color") != '' ? GETPOST("color") : ''; + $object->signature = GETPOST("signature", 'none'); + $object->accountancy_code = GETPOST("accountancy_code", 'alphanohtml'); + $object->note = GETPOST("note", 'none'); + $object->ldap_sid = GETPOST("ldap_sid", 'alphanohtml'); + $object->fk_user = GETPOST("fk_user", 'int') > 0 ? GETPOST("fk_user", 'int') : 0; + $object->employee = GETPOST('employee', 'alphanohtml'); + + $object->thm = GETPOST("thm", 'alphanohtml') != '' ? GETPOST("thm", 'alphanohtml') : ''; + $object->tjm = GETPOST("tjm", 'alphanohtml') != '' ? GETPOST("tjm", 'alphanohtml') : ''; + $object->salary = GETPOST("salary", 'alphanohtml') != '' ? GETPOST("salary", 'alphanohtml') : ''; + $object->salaryextra = GETPOST("salaryextra", 'alphanohtml') != '' ? GETPOST("salaryextra", 'alphanohtml') : ''; + $object->weeklyhours = GETPOST("weeklyhours", 'alphanohtml') != '' ? GETPOST("weeklyhours", 'alphanohtml') : ''; + + $object->color = GETPOST("color", 'alphanohtml') != '' ? GETPOST("color", 'alphanohtml') : ''; $dateemployment = dol_mktime(0, 0, 0, GETPOST('dateemploymentmonth'), GETPOST('dateemploymentday'), GETPOST('dateemploymentyear')); $object->dateemployment = $dateemployment; @@ -335,22 +335,22 @@ $object->pass = GETPOST("password",'none'); $object->api_key = (GETPOST("api_key", 'alpha')) ? GETPOST("api_key", 'alpha') : $object->api_key; if (! empty($user->admin)) $object->admin = GETPOST("admin"); // admin flag can only be set/unset by an admin user. A test is also done later when forging sql request - $object->address = GETPOST('address', 'alpha'); - $object->zip = GETPOST('zipcode', 'alpha'); - $object->town = GETPOST('town', 'alpha'); + $object->address = GETPOST('address', 'alphanohtml'); + $object->zip = GETPOST('zipcode', 'alphanohtml'); + $object->town = GETPOST('town', 'alphanohtml'); $object->country_id = GETPOST('country_id', 'int'); $object->state_id = GETPOST('state_id', 'int'); - $object->office_phone = GETPOST("office_phone", 'alpha'); - $object->office_fax = GETPOST("office_fax", 'alpha'); - $object->user_mobile = GETPOST("user_mobile"); + $object->office_phone = GETPOST("office_phone", 'alphanohtml'); + $object->office_fax = GETPOST("office_fax", 'alphanohtml'); + $object->user_mobile = GETPOST("user_mobile", 'alphanohtml'); $object->skype = GETPOST("skype", 'alpha'); $object->email = preg_replace('/\s+/', '', GETPOST("email", 'alpha')); $object->job = GETPOST("job", 'alpha'); $object->signature = GETPOST("signature",'none'); $object->accountancy_code = GETPOST("accountancy_code",'alpha'); $object->openid = GETPOST("openid",'alpha'); $object->fk_user = GETPOST("fk_user",'int') > 0 ? GETPOST("fk_user",'int') : 0; - $object->employee = GETPOST('employee'); + $object->employee = GETPOST('employee','alphanothtml'); $object->thm = GETPOST("thm",'alphanohtml') != '' ? GETPOST("thm",'alphanohtml') : ''; $object->tjm = GETPOST("tjm",'alphanohtml') != '' ? GETPOST("tjm",'alphanohtml') : '';
Vulnerability mechanics
Root cause
"Insufficient input sanitization — the `'alpha'` filter in `GETPOST()` does not strip HTML tags, allowing stored XSS via the `address` and `town` parameters."
Attack vector
A remote authenticated attacker sends a POST request to `user/card.php` with malicious JavaScript embedded in the `address` or `town` parameter [ref_id=2]. Because the application used the `'alpha'` filter (which only removes non-alphabetic characters) instead of `'alphanohtml'`, the injected script tags are stored in the database. When any user (including administrators) views the affected user's profile, the stored payload executes in their browser [CWE-79].
Affected code
The vulnerability resides in `htdocs/user/card.php` [patch_id=1700839][patch_id=1700840]. The `address` and `town` POST parameters (and several other fields) were passed through `GETPOST()` with the `'alpha'` filter, which strips only non-alphabetic characters but does **not** remove HTML tags, allowing stored XSS injection.
What the fix does
Both patches [patch_id=1700839][patch_id=1700840] change the filter parameter in `GETPOST()` calls from `'alpha'` to `'alphanohtml'` for the `address`, `town`, `zip`, `office_phone`, `office_fax`, `user_mobile`, `skype`, and several other fields. The `'alphanohtml'` filter strips HTML tags from the input, preventing the storage and later rendering of arbitrary script or HTML content. This closes the stored XSS vector by ensuring user-supplied data cannot contain markup when saved and displayed.
Preconditions
- authAttacker must be an authenticated user of the Dolibarr application
- configThe application must be Dolibarr version 8.0.2 (or an earlier unpatched version)
- inputAttacker sends POST request to user/card.php with malicious payload in address or town parameter
Generated on May 23, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-3v8x-286h-9pxpghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2018-19995ghsaADVISORY
- github.com/Dolibarr/dolibarr/commit/4b8be6ed64763327018ac1c076f81ddffa87855eghsax_refsource_MISCWEB
- github.com/Dolibarr/dolibarr/commit/bacd5110fbdc81a35030fdc322775fa15ea85924ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.