VYPR
Moderate severityOSV Advisory· Published Jan 3, 2019· Updated Aug 5, 2024

CVE-2018-19995

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].

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.

PackageAffected versionsPatched versions
dolibarr/dolibarrPackagist
< 8.0.48.0.4

Affected products

2

Patches

2
4b8be6ed6476

FIX CVE-2018-19995

https://github.com/dolibarr/dolibarrLaurent DestailleurDec 22, 2018via ghsa
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') : '';
    
bacd5110fbdc

FIX CVE-2018-19995 and CVE-2018-19998

https://github.com/dolibarr/dolibarrLaurent DestailleurDec 22, 2018via ghsa
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

News mentions

0

No linked articles in our index yet.