WP Manifestindependent plugin directory
manifest / forms / gospel-ambition-webforms

Gospel Ambition - Webforms WP Registry grade D+. High-severity findings · 4 findingsWP RegistryHigh-severity findings · 4 findingsOpen the reportD+

★ 0stars
18release downloads
≈10active sites
2023.05.11latest · 3 years ago

Install

Download gospel-ambition-webforms.zip From the 2023.05.11 release on GitHub, May 11, 2023

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

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/gospelambition/gospel-ambition-webforms/releases/download/2023.05.11/gospel-ambition-webforms.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Webforms.

Display list sign up form:

[go_display_opt_in name="Disciple.Tools" sourc="dt_news]

Releases

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

Tag
Published
Assets
Downloads
2023.05.11 latest
May 11, 2023 3 years ago
gospel-ambition-webforms.zip
3
May 8, 2023 3 years ago
gospel-ambition-webforms.zip
5
May 8, 2023 3 years ago
gospel-ambition-webforms.zip
5
May 8, 2023 3 years ago
gospel-ambition-webforms.zip
5

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

D+ grade

Security

Gospel Ambition - Webforms 2023.05.11 · audited by WP Registry

High-severity findings.

1 high 2 medium 1 low
Audited release
2023.05.11
Findings
4
Worst severity
high
Content hash
655ad9cc10667a98e80853d8…

Findings

  • high Unauthenticated optin proxies arbitrary CRM lists, tags, and contact_fields with the site-link Bearer token

    unsafe_input

    POST /wp-json/go-webform/optin is registered with permission_callback __return_true and no nonce. optin() takes $request->get_params() (JSON or form), runs apply_filters('go_webform_options', $params) — Disciple.Tools and Kingdom Training handlers only append list_18/list_22 or list_24/list_22 and overwrite a few contact_fields keys (projects, sources, maybe notes/steps_taken); they never strip extra lists or unknown contact_fields. Pray4Movement does not even inject default lists, so a client-supplied lists array is required and fully attacker-controlled. The handler then looks up the site_link_system row whose dev_key is crm_link, mints an hourly transfer token, and wp_remote_post's email, lists, name, first_name, last_name, contact_fields, source, tags, and named_tags to https://{linked host}/wp-json/crm-email/create with Authorization: Bearer. The public shortcode only sends email/first_name/last_name/source, so extra keys are not a documented form field — they are a privileged CRM write. Observable: subscribe any address to any list ID the CRM accepts (sequential list_18..24 are in this codebase), attach arbitrary tags, and set arbitrary contact_fields (notes, milestones, assigned_to, etc. if the CRM maps them) using this site's site-link identity. No email sanitization, CAPTCHA, or rate limit in 2023.05.11. Upstream master still forwards the same keys (nonce only when home_url is https://disciple.tools).

    globals/rest-api.php:23-65

    Recommendation

    Treat the public optin body as an allowlist: accept only email, first_name, last_name, and a site-defined source; ignore client lists/tags/named_tags/contact_fields. Set lists and contact_fields only inside go_webform_options from hardcoded values. sanitize_email() and reject empty/invalid email. Add rate-limiting or a CAPTCHA. Campaigns that need extra fields should authenticate with the site-link token (or a dedicated campaign secret), not share the anonymous route.

  • medium Unauthenticated site_link_server_check mints a transfer token and probes the linked host

    missing_permission_callback

    POST /wp-json/dt-public/v1/sites/site_link_server_check is registered with permission_callback __return_true. The only caller in this plugin is admin JS check_link_status() on the site_link_system edit screen, which is manage_dt-only UI, but the REST route has no current_user_can, nonce, or cookie check. An unauthenticated client posts {site_link_id: N}. For each integer N the handler does get_post_meta(N,'site_key') → md5(site_key + GMT hour) and get_post_meta site1/site2 → wp_remote_post('https://' . $url . '/wp-json/dt-public/v1/sites/site_link_check') with body transfer_token; on SSL failure it retries over HTTP, sending the live token in cleartext. Responses distinguish Linked, token verification failed, not secured with SSL, and failed to connect — an ID oracle for published site_link_system rows plus a credentialed outbound request to the configured partner. Host is not attacker-chosen (no arbitrary SSRF) unless that post already has site1/site2 meta, which subscribers cannot write. This class is skipped when the Disciple.Tools theme already defined Site_Link_System; it is live on the non-DT Gospel Ambition sites this plugin bootstraps.

    globals/site-link-post-type.php:1257-1338

    Recommendation

    Set permission_callback to current_user_can('manage_dt') (or edit_post on the given site_link_id) and send a wp_rest nonce from the admin script. Do not fall back to HTTP. Do not mint or transmit a transfer token on an anonymous route. Keep site_link_check public only as the token handshake.

  • medium Unauthenticated GET /dt-public/v1/sites/server_ip discloses the origin server address

    information_disclosure

    GET /wp-json/dt-public/v1/sites/server_ip is registered with permission_callback __return_true. server_ip() wp_remote_post's http://ifconfig.co/ip and returns the response body with no capability, nonce, or login check. The only UI that calls it is the Get Server IP button on the site_link_system metabox (manage_dt). Any unauthenticated client can therefore learn the WordPress host's public origin IP, which bypasses CDN/WAF hiding, and can use this site as a one-shot reflector against ifconfig.co. Same class_exists caveat as the site-link check: this plugin's copy runs when the Disciple.Tools theme is not loaded.

    globals/site-link-post-type.php:1266-1274,1372-1383

    Recommendation

    Gate the route with current_user_can('manage_dt') and a REST nonce. Prefer a server-side lookup only in admin-ajax, or show $_SERVER['SERVER_ADDR'] to capable users instead of calling a third-party HTTP echo service.

  • low No GitHub release since 2023.05.11; version-control.json still Tested up to 5.7

    unmaintained

    The audited zip is still the latest GitHub release (published 2023-05-11, three downloads). version-control.json last_updated is 2023-05 and tested is 5.7 while the plugin header says Tested up to: 6.3. Master has since added /double-optin, /confirm, and /contact plus a zume_vision tree, but this tagged build require_once's zume_vision/loader.php for bloginfo Vision / Zúme Training and that directory is absent from the zip (fatal on those site titles). Plugin Update Checker will keep serving this 2023 build, including the unauthenticated CRM proxy and dt-public admin routes above.

    version-control.json:1-19

    Recommendation

    Cut a new tagged release from current master after allowlisting optin fields and locking down the dt-public admin routes. Align Tested up to with a current WordPress run. Ship the zume_vision loader if those bloginfo titles are still in the switch, or remove the cases.

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.