WP Manifestindependent plugin directory
manifest / integrations / mainwp-monitoring-notify

MainWP Monitoring Notify WP Registry grade D+. High-severity findings · 3 findingsWP RegistryHigh-severity findings · 3 findingsOpen the reportD+

The MainWP Monitoring Notify extension allows you to send notifications via Line Notify when your site goes offline.

★ 4stars
38release downloads
≈10active sites
v1.3.0latest · 2 years ago

Install

Download mainwp-monitoring-notify.zip From the v1.3.0 release on GitHub, Feb 18, 2024

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/j7-dev/mainwp-monitoring-notify/releases/download/v1.3.0/mainwp-monitoring-notify.zip
Updates itself. It ships its own updater (Plugin Update Checker), so new versions appear under Dashboard → Updates.

MainWP Monitoring Notify | 讓 MainWP 監控更及時 :

一句話講完 MainWP Monitoring Notify :

MainWP Monitoring Notify 是一個 WordPress 套件,依賴 MainWP 來監控網站運作狀態,並透過 LINE Notify 來通知你。




預覽

image




⚡ 主要功能

使用 LINE NOTIFY 通知
如果你覺得通知太頻繁,可以設定,只有網站斷線時才通知

image




1. 如何申請 LINE Notify Token

1-1. 請先前往 LINE Notify 並登入你的 LINE

1-2. 點擊 Generate token 然後選擇想要通知的聊天室

image

1-3. 複製 token 然後貼到這邊保存

image

1-4. 最後,邀請 LINE Notify 到你第二步選擇的聊天室就完成了🎉🎉🎉

image




2. 常見 Q & A

2-1. 多久檢查一次?

看你 Sites > Monitoring ,中的設置是多久,最短可以 每 5 分鐘 檢查一次

2-2. 運作原理是什麼?

是使用 WP CRON 搭配 MainWP 本身的 hook 做成

⚠️ WP CRON 必須是 有人造訪網站時才會觸發,如果您的網站流量本身並不高,推薦使用 主機本身提供的 crontab 來實現,詳細可參考 官方文章 或 這篇文章

也因為如此,斷線的檢查推波通知 並非準確的 5 分鐘

2-3. [進階] 設定準確的定時任務 - 使用 crontab

如果你的主機商允許你設定 crontab 那麼,你可以透過 crontab 實現準確的定時任務,也可以參考此 crontab 教學

2-3-1. 取消這個外掛的 WP CRON

在你主題底下的 functions.php 輸入

add_filter( 'mainwp_monitoring_notify_wp_cron_enabled' , '__return_false', 100, 1 );

2-3-2. ssh 伺服器後輸入 crontab -e ,開啟 crontab 設定

⚠️ 請確保你的伺服器上可以執行 php 指令

⚠️ 下方的 {{PATH}} 請自行替換此網站的檔案路徑,例: /var/www/html/MY_SITE

例: 每分鐘執行一次:

* * * * * php {{PATH}}/wp-content/plugins/mainwp-monitoring-notify/cron/exec.php > /dev/null 2>&1

例: 每 5 分鐘執行一次:

*/5 * * * * php {{PATH}}/wp-content/plugins/mainwp-monitoring-notify/cron/exec.php > /dev/null 2>&1

image




Releases

6 releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
v1.3.0 latest
Feb 18, 2024 2 years ago
mainwp-monitoring-notify.zip
13
Feb 18, 2024 2 years ago
mainwp-monitoring-notify.zip
6
Feb 18, 2024 2 years ago
mainwp-monitoring-notify.zip
3
Feb 18, 2024 2 years ago
mainwp-monitoring-notify.zip
4
Feb 16, 2024 2 years ago
mainwp-monitoring-notify.zip
6
May 26, 2023 3 years ago
mainwp-monitoring-notify-v1.0.0.zip
6

Active-site estimate ≈10 comes from the median of recent superseded releases. Method.

D+ grade

Security

MainWP Monitoring Notify 1.3.0 · audited by WP Registry

High-severity findings.

2 high 1 medium
Audited release
1.3.0
Findings
3
Worst severity
high
Content hash
2788d06ba4c9b24264db153e…

Findings

  • high Unauthenticated cron/exec.php loads WordPress and runs the full monitoring job with no secret

    missing_auth

    cron/exec.php is web-reachable under wp-content/plugins/ (no .htaccess, no index.php, no php_sapi_name()==='cli' check, no shared secret). It requires cron/bootstrap.php, which sets ignore_user_abort(true), memory_limit 512M, max_execution_time 0, define('DOING_CRON', true), and include_once of wp-load.php (or eval's an ABSPATH line from wp-config.php as a fallback). It then calls Functions::exec_crontab_task() with no authentication. That method SELECTs every name,url from {$wpdb->prefix}mainwp_wp, curl_init's each URL with CURLOPT_FOLLOWLOCATION, optionally runs exec('top -bn 1 | awk …'), exec('free | awk …'), and shell_exec('/usr/sbin/service nginx|mysql status') when option mainwp_monitoring_notify_show_system_info is truthy, then POSTs the assembled message to https://notify-api.line.me/api/notify using the stored LINE token, sleeping 3s per chunk, with no concurrency lock. Observable as an unauthenticated visitor: GET /wp-content/plugins/mainwp-monitoring-notify/cron/exec.php starts a long-lived PHP worker that will continue after the client disconnects, floods the operator's LINE chat, and issues outbound HTTP to every managed child site. Parallel requests fork-bomb the dashboard (the box that holds every child-site credential). This is not RCE (the exec strings are hardcoded) and the HTTP response only echoes 'All sites are online' or a class-missing notice — blast is availability plus notification/SSRF-to-inventory abuse.

    cron/exec.php:1-6

    Recommendation

    Refuse non-CLI invocation (php_sapi_name() !== 'cli' and empty $_SERVER['argv']) or require a high-entropy secret in the query string compared to an option that is never printed. Deny HTTP access to cron/ with .htaccess/nginx. Drop ignore_user_abort/unlimited time for web SAPIs. Add a file lock so overlapping runs exit. Do not eval wp-config.php.

  • high Settings AJAX has no capability check (and is registered nopriv); Subscriber+ can read and overwrite the LINE Notify token

    missing_capability

    Bootstrap registers both wp_ajax_mainwp_monitoring_notify_update and wp_ajax_nopriv_mainwp_monitoring_notify_update to update_callback(). The handler only check_ajax_referer('mainwp-monitoring-notify-extension') then sanitize_text_field's POST and update_option's mainwp_monitoring_notify_line_token, _interval_in_minute, _only_notify_when_site_offline, _hide_healthy_sites, and _show_system_info. There is no current_user_can('manage_options') (or mainwp_current_user_can) in the handler. MainWP core adds this extension page with capability 'read' and slug Extensions-Mainwp-Monitoring-Notify; a logged-in Subscriber can load that URL. admin_init matches stripos($_GET['page'], 'Mainwp-Monitoring-Notify') and wp_localize_script's a usable per-user nonce; render_fields() prints the current token in <input value="<?=$line_token?>"> with no esc_attr. Observable: Subscriber views the live LINE bearer token, then POSTs admin-ajax.php?action=mainwp_monitoring_notify_update with that nonce and their own token (and show_system_info=1). Subsequent exec_crontab_task()/handle_offline_site() deliveries go to the attacker's LINE chat with every child-site name/URL/HTTP code and dashboard CPU/RAM/load/nginx/mysql status. sanitize_text_field does not encode quotes, so a token such as " autofocus onfocus="alert(document.domain) stored here is admin stored XSS when an administrator later opens Settings. wp_ajax_nopriv_ is extra attack surface; unauth still needs a uid-0 nonce that this plugin only mints on the admin page, so the practical write is authenticated-low-priv, not anonymous.

    mainwp-monitoring-notify.php:45-47,94-145,203-214

    Recommendation

    Remove the nopriv hook. In update_callback, require current_user_can('manage_options') (or a MainWP right checked after plugins_loaded) in addition to the nonce. Do not print the LINE token into the form; use type=password / a 'token is set' placeholder. Escape with esc_attr() if it must be shown. Move the mainwp_current_user_can gate out of plugin-include time so it actually runs after have_right exists.

  • medium admin_post_run_test has no nonce or capability check, so any logged-in user or CSRF GET triggers the monitoring job

    csrf

    Bootstrap hooks admin_post_run_test to static run_test_callback(), which immediately calls Functions::exec_crontab_task() with no wp_verify_nonce, no check_admin_referer, and no current_user_can. WordPress admin-post.php fires admin_post_{action} for every is_user_logged_in() user. The settings-page jQuery posts {action:'run_test'} to admin-post.php with no nonce field. Observable: a Subscriber GET or POST /wp-admin/admin-post.php?action=run_test runs the same curl/LINE/optional-exec job as finding 1. Cross-site CSRF of an administrator also works via a top-level GET navigation (WordPress auth cookies are SameSite=Lax, which are sent on top-level GET). Blast is the same monitoring-job side effects (LINE flood, child-site traffic, optional host command execution) without changing stored settings — limited compared with token theft, hence medium.

    mainwp-monitoring-notify.php:47,162-165

    Recommendation

    Rename the action to a plugin-prefixed slug. Require check_admin_referer plus current_user_can('manage_options') before exec_crontab_task(). Send the nonce from localized script and reject GET. Do not use a generic action name like run_test.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.