diff --git a/.gitignore b/.gitignore
index eff3ba3..f6b7fd8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,4 +21,5 @@
*.swp
.DS_Store
+.omc/
locales/po/*.mo
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..8228fe0
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,27 @@
+# Security Policy
+
+## Supported Versions
+
+This plugin follows the Cacti project's support policy. Security fixes are
+applied to the current development branch and backported per project policy.
+
+## Reporting a Vulnerability
+
+Report security vulnerabilities via the Cacti project's private security
+disclosure process:
+
+- GitHub Security Advisories: https://github.com/Cacti/plugin_webseer/security/advisories
+- Do NOT open public issues for security vulnerabilities.
+
+Please include:
+- Description of the vulnerability
+- Steps to reproduce
+- Affected versions
+- Suggested remediation (if known)
+
+A maintainer will acknowledge the report within 72 hours and provide a
+remediation timeline.
+
+## Security Hardening Notes
+
+See SECURITY-AUDIT.md for the current known finding backlog and remediation status.
diff --git a/classes/cURL.php b/classes/cURL.php
index d263e71..ddb1878 100644
--- a/classes/cURL.php
+++ b/classes/cURL.php
@@ -1,4 +1,6 @@
debug('Executing Post Request');
@@ -91,14 +93,14 @@ function post($url, $data = array()) {
$process = curl_init($url);
$this->headers[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8';
- $d = array();
+ $d = [];
foreach ($data as $i => $j) {
$d[] = "$i=$j";
}
$data = implode('&', $d);
- $options = array(
+ $options = [
CURLOPT_HTTPHEADER => $this->headers,
CURLOPT_HEADER => true,
CURLOPT_USERAGENT => $this->user_agent,
@@ -107,7 +109,7 @@ function post($url, $data = array()) {
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_POST => true,
- );
+ ];
if (!empty($this->compression)) {
$options[CURLOPT_ENCODING] = $httpcompressions[$this->compression];
@@ -175,38 +177,38 @@ function get() {
$is_https = (substr(strtolower($url), 0, 5) == 'https');
- $proxy_opts = array(
+ $proxy_opts = [
CURLOPT_UNRESTRICTED_AUTH => true,
CURLOPT_PROXY => $this->proxy_hostname,
CURLOPT_PROXYPORT => $is_https ? $port_https : $port_http,
- );
+ ];
if ($this->proxy_username != '') {
$proxy_opts[CURLOPT_PROXYUSERPWD] = $this->proxy_username . ':' . $this->proxy_password;
}
} else {
- $proxy_opts = array();
+ $proxy_opts = [];
}
// Disable Cert checking for now
if ($this->host['checkcert'] == '') {
- $cert_opts = array(
+ $cert_opts = [
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_SSL_VERIFYHOST => FALSE,
- );
+ ];
} else {
- $cert_opts = array();
+ $cert_opts = [];
}
$options += $proxy_opts;
$options += $cert_opts;
$this->debug('cURL options: ' . clean_up_lines(var_export($options, true)));
- curl_setopt_array($process,$options);
+ curl_setopt_array($process, $options);
$data = curl_exec($process);
- $this->data = str_replace(array("'", "\\"), array(''), $data);
+ $this->data = str_replace(["'", "\\"], [''], $data);
$this->results['options'] = curl_getinfo($process);
$this->results['options']['compression'] = $this->compression;
@@ -222,7 +224,7 @@ function get() {
case 0:
break;
default:
- $this->results['error'] = 'HTTP ERROR: ' . str_replace(array('"', "'"), '', (curl_error($process)));
+ $this->results['error'] = 'HTTP ERROR: ' . str_replace(['"', "'"], '', (curl_error($process)));
break;
}
diff --git a/classes/index.php b/classes/index.php
index 9a6d459..596a8fb 100644
--- a/classes/index.php
+++ b/classes/index.php
@@ -1,4 +1,6 @@
gdi($this->cIx));
//$this->parse_data($curmx);
- //$this->arrMX[] = array('MX_Pref' => $mxPref, 'MX' => $curmx);
+ //$this->arrMX[] = ['MX_Pref' => $mxPref, 'MX' => $curmx];
//$this->cIx += 3;
}
}
@@ -77,7 +79,7 @@ function __destruct() {
}
function parse_data(&$retval) {
- $arName = array();
+ $arName = [];
$byte = ord($this->gdi($this->cIx));
while($byte !== 0) {
diff --git a/images/index.php b/images/index.php
index a16f0e6..52af78f 100644
--- a/images/index.php
+++ b/images/index.php
@@ -1,4 +1,6 @@
'HTTP Version Not Supported',
);
-$httpcompressions = array(
+$httpcompressions = [
0 => '',
1 => 'aes128gcm',
2 => 'br',
@@ -87,7 +89,7 @@
9 => 'x-compress',
10 => 'x-gzip',
11 => 'zstd',
-);
+];
$webseer_minutes = array(
1 => __('%d Minute', 1, 'webseer'),
@@ -113,10 +115,10 @@
10 => __('%d Seconds', 10, 'webseer'),
);
-$webseer_notify_formats = array(
+$webseer_notify_formats = [
WEBSEER_FORMAT_HTML => 'html',
WEBSEER_FORMAT_PLAIN => 'plain',
-);
+];
if (db_table_exists('plugin_webseer_contacts')) {
$webseer_contact_users = db_fetch_assoc("SELECT pwc.id, pwc.data, pwc.type, ua.full_name
@@ -125,10 +127,10 @@
ON ua.id=pwc.user_id
WHERE pwc.data != ''");
} else {
- $webseer_contact_users = array();
+ $webseer_contact_users = [];
}
-$webseer_notify_accounts = array();
+$webseer_notify_accounts = [];
if (!empty($webseer_contact_users)) {
foreach ($webseer_contact_users as $webseer_contact_user) {
$webseer_notify_accounts[$webseer_contact_user['id']] = $webseer_contact_user['full_name'] . ' - ' . ucfirst($webseer_contact_user['type']);
@@ -211,14 +213,14 @@
'size' => '40',
'default' => ''
),
- 'id' => array(
+ 'id' => [
'method' => 'hidden_zero',
'value' => '|arg1:id|'
- ),
- 'save_component_proxy' => array(
+ ],
+ 'save_component_proxy' => [
'method' => 'hidden',
'value' => '1'
- )
+ ]
);
$webseer_server_fields = array(
@@ -275,10 +277,10 @@
'value' => '|arg1:location|',
'max_length' => '256',
),
- 'id' => array(
+ 'id' => [
'method' => 'hidden_zero',
'value' => '|arg1:id|'
- ),
+ ],
);
$webseer_url_fields = array(
@@ -433,8 +435,8 @@
'description' => __('You may specify here extra Emails to receive alerts for this URL (comma separated)', 'webseer'),
'value' => '|arg1:notify_extra|',
),
- 'id' => array(
+ 'id' => [
'method' => 'hidden_zero',
'value' => '|arg1:id|'
- ),
+ ],
);
diff --git a/includes/constants.php b/includes/constants.php
index aa99487..0788041 100644
--- a/includes/constants.php
+++ b/includes/constants.php
@@ -1,4 +1,6 @@
post($server['url'], $data);
@@ -78,9 +80,9 @@ function plugin_webseer_refresh_servers() {
foreach ($servers as $save) {
db_execute_prepared('REPLACE INTO plugin_webseer_servers (id, enabled, master, name, url, ip, location)
VALUES (?,?,?,?,?,?,?)',
- array(
+ [
$save['id'], $save['enabled'], $save['master'], $save['name'], $save['url'], $save['ip'] , $save['location']
- )
+ ]
);
}
}
@@ -96,7 +98,7 @@ function plugin_webseer_refresh_urls () {
$server['debug_type'] = 'Server';
$cc = new cURL(true, 'cookies.txt', 'gzip', '', $server);
- $data = array();
+ $data = [];
$data['action'] = 'GETURLS';
$results = $cc->post($server['url'], $data);
$results = explode("\n", $results);
@@ -113,12 +115,12 @@ function plugin_webseer_refresh_urls () {
db_execute_prepared('REPLACE INTO plugin_webseer_urls
(id, enabled, requiresauth, checkcert, ip, display_name, notify_list, notify_accounts, url, search, search_maint, search_failed, notify_extra, downtrigger)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
- array(
+ [
$save['id'], $save['enabled'], $save['requiresauth'], $save['checkcert'],
$save['ip'], $save['display_name'], $save['notify_list'], $save['notify_accounts'],
$save['url'], $save['search'], $save['search_maint'],
$save['search_failed'], $save['notify_extra'], $save['downtrigger']
- )
+ ]
);
}
}
@@ -131,7 +133,7 @@ function plugin_webseer_refresh_urls () {
function plugin_webseer_remove_old_users () {
$users = db_fetch_assoc('SELECT id FROM user_auth');
- $u = array();
+ $u = [];
foreach ($users as $user) {
$u[] = $user['id'];
@@ -141,7 +143,7 @@ function plugin_webseer_remove_old_users () {
foreach ($contacts as $c) {
if (!in_array($c['user_id'], $u)) {
- db_execute_prepared('DELETE FROM plugin_webseer_contacts WHERE user_id = ?', array($c['user_id']));
+ db_execute_prepared('DELETE FROM plugin_webseer_contacts WHERE user_id = ?', [$c['user_id']]);
}
}
}
@@ -150,7 +152,7 @@ function plugin_webseer_check_dns ($host) {
$results = false;
if (cacti_sizeof($host)) {
- $results = array();
+ $results = [];
$results['result'] = 0;
$results['options']['http_code'] = 0;
$results['error'] = '';
@@ -189,12 +191,12 @@ function plugin_webseer_set_remote_masters ($ip) {
}
db_execute('UPDATE plugin_webseer_servers set master = 0');
- db_execute_prepared('UPDATE plugin_webseer_servers set master = 1 WHERE ip = ?', array($ip));
+ db_execute_prepared('UPDATE plugin_webseer_servers set master = 1 WHERE ip = ?', [$ip]);
}
function plugin_webseer_set_remote_master ($url, $ip) {
$cc = new cURL(true, 'cookies.txt', 'gzip', '', $url);
- $data = array();
+ $data = [];
$data['action'] = 'SETMASTER';
$data['ip'] = $ip;
$results = $cc->post($url['url'], $data);
@@ -205,7 +207,7 @@ function plugin_webseer_enable_remote_hosts ($id, $value = true) {
foreach ($servers as $server) {
$cc = new cURL(true, 'cookies.txt', 'gzip', '', $server);
- $data = array();
+ $data = [];
$data['action'] = ($value ? 'ENABLEURL' : 'DISABLEURL');
$data['id'] = $id;
$results = $cc->post($server['url'], $data);
@@ -217,7 +219,7 @@ function plugin_webseer_delete_remote_hosts ($id) {
foreach ($servers as $server) {
$cc = new cURL(true, 'cookies.txt', 'gzip', '', $server);
- $data = array();
+ $data = [];
$data['action'] = 'DELETEURL';
$data['id'] = $id;
$results = $cc->post($server['url'], $data);
@@ -281,7 +283,7 @@ function plugin_webseer_enable_remote_server ($id, $value = true) {
$server['debug_type'] = 'Server';
$cc = new cURL(true, 'cookies.txt', 'gzip', '', $server);
- $data = array();
+ $data = [];
$data['action'] = ($value ? 'ENABLESERVER' : 'DISABLESERVER');
$data['id'] = $id;
$results = $cc->post($server['url'], $data);
@@ -295,7 +297,7 @@ function plugin_webseer_delete_remote_server ($id) {
$server['debug_type'] = 'Server';
$cc = new cURL(true, 'cookies.txt', 'gzip', '', $server);
- $data = array();
+ $data = [];
$data['action'] = 'DELETESERVER';
$data['id'] = $id;
$results = $cc->post($server['url'], $data);
@@ -337,7 +339,7 @@ function plugin_webseer_check_debug() {
}
}
-function plugin_webseer_debug($message='', $host=array()) {
+function plugin_webseer_debug($message='', $host=[]) {
global $debug;
if ($debug) {
$prefix = (empty($host['id']) && empty($host['debug_type'])) ? '' : '[';
diff --git a/includes/index.php b/includes/index.php
index a16f0e6..52af78f 100644
--- a/includes/index.php
+++ b/includes/index.php
@@ -1,4 +1,6 @@
0) {
$url['debug_type'] = 'Url';
@@ -150,7 +152,7 @@
$running = db_fetch_cell_prepared('SELECT COUNT(*)
FROM plugin_webseer_processes
WHERE poller_id = ?',
- array($poller_id));
+ [$poller_id]);
if ($running == 0) {
break;
@@ -190,15 +192,15 @@ function plugin_webseer_register_server() {
$found = db_fetch_cell_prepared('SELECT id
FROM plugin_webseer_servers
WHERE ip = ?',
- array($ipaddress));
+ [$ipaddress]);
if (!$found) {
- $found = array();
+ $found = [];
$found['debug_type'] = 'Server';
plugin_webseer_debug('Registering Server ' . $ipaddress, $found);
- $save = array();
+ $save = [];
$save['enabled'] = 'on';
$save['isme'] = 1;
$save['lastcheck'] = $lastcheck;
@@ -238,9 +240,9 @@ function plugin_webseer_update_servers() {
foreach ($servers as $server) {
$server['debug_type'] = 'Server';
- $cc = new cURL(true, 'cookies.txt', $server['compression'], '', $server);;
+ $cc = new cURL(true, 'cookies.txt', $server['compression'], '', $server);
- $data = array();
+ $data = [];
$data['action'] = 'HEARTBEAT';
$results = $cc->post($server['url'], $data);
}
diff --git a/remote.php b/remote.php
index ab3aff6..c7263c0 100644
--- a/remote.php
+++ b/remote.php
@@ -1,4 +1,6 @@
0) {
- db_execute_prepared('UPDATE plugin_webseer_urls SET enabled = "on" WHERE id = ?', array($id));
+ db_execute_prepared('UPDATE plugin_webseer_urls SET enabled = "on" WHERE id = ?', [$id]);
plugin_webseer_enable_remote_hosts($id, true);
}
@@ -55,7 +57,7 @@
$id = get_filter_request_var('id');
if ($id > 0) {
- db_execute_prepared('UPDATE plugin_webseer_urls SET enabled = "" WHERE id = ?', array($id));
+ db_execute_prepared('UPDATE plugin_webseer_urls SET enabled = "" WHERE id = ?', [$id]);
plugin_webseer_enable_remote_hosts($id, false);
}
@@ -110,18 +112,18 @@ function form_actions() {
if (cacti_sizeof($urls)) {
if ($action == WEBSEER_ACTION_URL_DELETE) { // delete
foreach ($urls as $id) {
- db_execute_prepared('DELETE FROM plugin_webseer_urls WHERE id = ?', array($id));
- db_execute_prepared('DELETE FROM plugin_webseer_urls_log WHERE url_id = ?', array($id));
+ db_execute_prepared('DELETE FROM plugin_webseer_urls WHERE id = ?', [$id]);
+ db_execute_prepared('DELETE FROM plugin_webseer_urls_log WHERE url_id = ?', [$id]);
plugin_webseer_delete_remote_hosts($id);
}
} elseif ($action == WEBSEER_ACTION_URL_DISABLE) { // disable
foreach ($urls as $id) {
- db_execute_prepared('UPDATE plugin_webseer_urls SET enabled = "" WHERE id = ?', array($id));
+ db_execute_prepared('UPDATE plugin_webseer_urls SET enabled = "" WHERE id = ?', [$id]);
plugin_webseer_enable_remote_hosts($id, false);
}
} elseif ($action == WEBSEER_ACTION_URL_ENABLE) { // enable
foreach ($urls as $id) {
- db_execute_prepared('UPDATE plugin_webseer_urls SET enabled = "on" WHERE id = ?', array($id));
+ db_execute_prepared('UPDATE plugin_webseer_urls SET enabled = "on" WHERE id = ?', [$id]);
plugin_webseer_enable_remote_hosts($id, true);
}
} elseif ($action == WEBSEER_ACTION_URL_DUPLICATE) { // duplicate
@@ -129,7 +131,7 @@ function form_actions() {
$newid = 1;
foreach ($urls as $id) {
- $save = db_fetch_row_prepared('SELECT * FROM plugin_webseer_urls WHERE id = ?', array($id));
+ $save = db_fetch_row_prepared('SELECT * FROM plugin_webseer_urls WHERE id = ?', [$id]);
$save['id'] = 0;
$save['poller_id'] = 1;
$save['display_name'] = 'New Service Check (' . $newid . ')';
@@ -165,7 +167,7 @@ function form_actions() {
/* setup some variables */
$url_list = '';
- $url_array = array();
+ $url_array = [];
/* loop through each of the graphs selected on the previous page and get more info about them */
foreach ($_POST as $var => $val) {
@@ -174,7 +176,7 @@ function form_actions() {
input_validate_input_number($matches[1]);
/* ==================================================== */
- $url_list .= '
' . db_fetch_cell_prepared('SELECT display_name FROM plugin_webseer_urls WHERE id = ?', array($matches[1])) . '';
+ $url_list .= '' . db_fetch_cell_prepared('SELECT display_name FROM plugin_webseer_urls WHERE id = ?', [$matches[1]]) . '';
$url_array[] = $matches[1];
}
}
@@ -338,9 +340,9 @@ function purge_log_events($id) {
$name = db_fetch_cell_prepared('SELECT display_name
FROM plugin_webseer_urls
WHERE id = ?',
- array($id));
+ [$id]);
- db_execute_prepared('DELETE FROM plugin_webseer_urls_log WHERE url_id = ?', array($id));
+ db_execute_prepared('DELETE FROM plugin_webseer_urls_log WHERE url_id = ?', [$id]);
raise_message('url_log_purged', __('The Service Check history was purged for %s', $name, 'webseer'), MESSAGE_LEVEL_INFO);
}
@@ -352,7 +354,7 @@ function webseer_edit_url() {
get_filter_request_var('id');
/* ==================================================== */
- $url = array();
+ $url = [];
if (!isempty_request_var('id')) {
$url = db_fetch_row_prepared('SELECT * FROM plugin_webseer_urls WHERE id = ?', array(get_request_var('id')), false);
$header_label = __('Query [edit: %s]', $url['url'], 'webseer');
@@ -371,7 +373,7 @@ function webseer_edit_url() {
draw_edit_form(
array(
- 'config' => array('form_name' => 'chk'),
+ 'config' => ['form_name' => 'chk'],
'fields' => inject_form_variables($webseer_url_fields, $url)
)
);
@@ -455,15 +457,15 @@ function webseer_edit_url() {
function webseer_request_validation() {
/* ================= input validation and session storage ================= */
$filters = array(
- 'rows' => array(
+ 'rows' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
- ),
- 'page' => array(
+ ],
+ 'page' => [
'filter' => FILTER_VALIDATE_INT,
'default' => '1'
- ),
+ ],
'refresh' => array(
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
@@ -473,23 +475,23 @@ function webseer_request_validation() {
'filter' => FILTER_VALIDATE_IS_REGEX,
'default' => '',
'pageset' => true,
- 'options' => array('options' => 'sanitize_search_string')
+ 'options' => ['options' => 'sanitize_search_string']
),
'sort_column' => array(
'filter' => FILTER_CALLBACK,
'default' => 'display_name',
- 'options' => array('options' => 'sanitize_search_string')
+ 'options' => ['options' => 'sanitize_search_string']
),
'sort_direction' => array(
'filter' => FILTER_CALLBACK,
'default' => 'ASC',
- 'options' => array('options' => 'sanitize_search_string')
+ 'options' => ['options' => 'sanitize_search_string']
),
- 'state' => array(
+ 'state' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
- )
+ ]
);
validate_store_request_vars($filters, 'sess_webseerurl');
@@ -501,33 +503,33 @@ function webseer_log_request_validation() {
/* ================= input validation and session storage ================= */
$filters = array(
- 'id' => array(
+ 'id' => [
'filter' => FILTER_VALIDATE_INT,
'default' => '-1'
- ),
- 'rows' => array(
+ ],
+ 'rows' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
- ),
- 'page' => array(
+ ],
+ 'page' => [
'filter' => FILTER_VALIDATE_INT,
'default' => '1'
- ),
+ ],
'filter' => array(
'filter' => FILTER_CALLBACK,
'default' => '',
- 'options' => array('options' => 'sanitize_search_string')
+ 'options' => ['options' => 'sanitize_search_string']
),
'sort_column' => array(
'filter' => FILTER_CALLBACK,
'default' => 'lastcheck',
- 'options' => array('options' => 'sanitize_search_string')
+ 'options' => ['options' => 'sanitize_search_string']
),
'sort_direction' => array(
'filter' => FILTER_CALLBACK,
'default' => 'DESC',
- 'options' => array('options' => 'sanitize_search_string')
+ 'options' => ['options' => 'sanitize_search_string']
),
);
@@ -675,16 +677,16 @@ function list_urls() {
/* ================= input validation and session storage ================= */
$filters = array(
- 'rows' => array(
+ 'rows' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
- ),
- 'state' => array(
+ ],
+ 'state' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
- ),
+ ],
'refresh' => array(
'filter' => FILTER_VALIDATE_INT,
'default' => read_config_option('log_refresh_interval')
@@ -692,12 +694,12 @@ function list_urls() {
'sort_column' => array(
'filter' => FILTER_CALLBACK,
'default' => 'display_name',
- 'options' => array('options' => 'sanitize_search_string')
+ 'options' => ['options' => 'sanitize_search_string']
),
'sort_direction' => array(
'filter' => FILTER_CALLBACK,
'default' => 'ASC',
- 'options' => array('options' => 'sanitize_search_string')
+ 'options' => ['options' => 'sanitize_search_string']
)
);
@@ -1014,7 +1016,7 @@ function clearFilter() {