CVE-2019-16983
Description
In FusionPBX up to v4.5.7, the file resources\paging.php has a paging function (called by several pages of the interface), which uses an unsanitized "param" variable constructed partially from the URL args and reflected in HTML, leading to XSS.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
FusionPBX versions up to 4.5.7 contain a reflected XSS vulnerability in the paging function of paging.php due to unsanitized 'param' parameter.
Vulnerability
FusionPBX versions up to 4.5.7 contain a reflected cross-site scripting (XSS) vulnerability in the paging() function of resources/paging.php [1]. The param variable, constructed from URL arguments, is unsanitized and directly reflected in HTML output, allowing injection of arbitrary JavaScript [2]. This function is called by multiple pages in the interface.
Exploitation
An attacker must trick an authenticated user into clicking a crafted URL containing malicious JavaScript in the param parameter [2]. The URL is part of the FusionPBX interface; no additional privileges are needed beyond user authentication. The injected script executes in the context of the victim's session.
Impact
Successful exploitation allows the attacker to execute arbitrary JavaScript in the victim's browser, leading to actions such as session hijacking, defacement, or redirection to malicious sites. The attack is limited to actions the victim can perform within FusionPBX.
Mitigation
The vulnerability was fixed in commit 23581e5 on August 12, 2019, and is included in FusionPBX v4.5.7 onwards [1][2]. Users should upgrade to a patched version. No workarounds are documented.
AI Insight generated on May 26, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2- FusionPBX/FusionPBXdescription
Patches
11 file changed · +44 −10
resources/paging.php+44 −10 modified@@ -39,6 +39,40 @@ function paging($num_rows, $param, $rows_per_page, $mini = false, $result_count $page_number = 0; } + //sanitize the parameters + $sanitized_parameters = ''; + if (isset($param) && strlen($param) > 0) { + $param_array = explode("&", $param); + if (is_array($param_array)) { + foreach($param_array as $row) { + $param_sub_array = explode("=", $row); + $key = preg_replace('#[^a-zA-Z0-9_\-]#', '', $param_sub_array['0']); + $value = urldecode($param_sub_array['1']); + if ($key == 'order_by' && strlen($value) > 0) { + //validate order by + $sanitized_parameters .= "&order_by=". preg_replace('#[^a-zA-Z0-9_\-]#', '', $value); + } + elseif ($key == 'order' && strlen($value) > 0) { + //validate order + switch ($value) { + case 'asc': + $sanitized_parameters .= "&order=asc"; + break; + case 'desc': + $sanitized_parameters .= "&order=desc"; + break; + } + } + elseif (strlen($value) > 0 && is_numeric($value)) { + $sanitized_parameters .= "&".$key."=".$value; + } + else { + $sanitized_parameters .= "&".$key."=".urlencode($value); + } + } + } + } + //get the offset $offset = ($page_number - 1) * $rows_per_page; @@ -51,8 +85,8 @@ function paging($num_rows, $param, $rows_per_page, $mini = false, $result_count $language = new text; $text = $language->get(); - // print the link to access each page - $self = $_SERVER['PHP_SELF']; + //print the link to access each page + $self = escape($_SERVER['PHP_SELF']); $nav = ''; for($page = 1; $page <= $max_page; $page++){ if ($page == $page_number) { @@ -64,21 +98,21 @@ function paging($num_rows, $param, $rows_per_page, $mini = false, $result_count } if ($page_number > 0) { - $page = $page_number - 1; - $prev = "<input class='btn' type='button' value='".$text['button-back']."' alt='".($page+1)."' title='".($page+1)."' onClick=\"window.location = '".$self."?page=$page".$param."';\">\n"; //◀ - $first = "<input class='btn' type='button' value='".$text['button-next']."' onClick=\"window.location = '".$self."?page=1".$param."';\">\n"; //▲ + $page = $page_number - 1; + $prev = "<input class='btn' type='button' value='".$text['button-back']."' alt='".($page+1)."' title='".($page+1)."' onClick=\"window.location = '".$self."?page=".$page.$sanitized_parameters."';\">\n"; //◀ + $first = "<input class='btn' type='button' value='".$text['button-next']."' onClick=\"window.location = '".$self."?page=1".$sanitized_parameters."';\">\n"; //▲ } else { $prev = "<input class='btn' type='button' disabled value='".$text['button-back']."' style='opacity: 0.4; -moz-opacity: 0.4; cursor: default;'>\n"; //◀ } if (($page_number + 1) < $max_page) { - $page = $page_number + 1; - $next = "<input class='btn' type='button' value='".$text['button-next']."' alt='".($page+1)."' title='".($page+1)."' onClick=\"window.location = '".$self."?page=$page".$param."';\">\n"; //▶ - $last = "<input class='btn' type='button' value='".$text['button-back']."' onClick=\"window.location = '".$self."?page=$max_page".$param."';\">\n"; //▼ + $page = $page_number + 1; + $next = "<input class='btn' type='button' value='".$text['button-next']."' alt='".($page+1)."' title='".($page+1)."' onClick=\"window.location = '".$self."?page=".$page.$sanitized_parameters."';\">\n"; //▶ + $last = "<input class='btn' type='button' value='".$text['button-back']."' onClick=\"window.location = '".$self."?page=".$max_page.$sanitized_parameters."';\">\n"; //▼ } else { - $last = "<input class='btn' type='button' value='".$text['button-next']."' onClick=\"window.location = '".$self."?page=$max_page".$param."';\">\n"; //▼ + $last = "<input class='btn' type='button' value='".$text['button-next']."' onClick=\"window.location = '".$self."?page=".$max_page.$sanitized_parameters."';\">\n"; //▼ $next = "<input class='btn' type='button' disabled value='".$text['button-next']."' style='opacity: 0.4; -moz-opacity: 0.4; cursor: default;'>\n"; //▶ } @@ -123,7 +157,7 @@ function paging($num_rows, $param, $rows_per_page, $mini = false, $result_count "// action to peform when enter is hit\n". "if (page_num < 1) { page_num = 1; }\n". "if (page_num > ".$max_page.") { page_num = ".$max_page."; }\n". - "document.location.href = '".$self."?page='+(--page_num)+'".$param."';\n". + "document.location.href = '".$self."?page='+(--page_num)+'".$sanitized_parameters."';\n". "}\n". "}\n". "</script>\n";
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2- github.com/fusionpbx/fusionpbx/commit/23581e56e9a4d1685ddf1c7d67137417d654e134mitrex_refsource_MISC
- resp3ctblog.wordpress.com/2019/10/19/fusionpbx-xss-15/mitrex_refsource_MISC
News mentions
0No linked articles in our index yet.