Skip to content

MainWP — Security & Permissions

WPSigner for MainWP is a Dashboard admin extension. It has no public/nopriv AJAX endpoints. All actions require a logged-in user, a valid nonce (imwp_admin), and capability checks.

Documented behavior reflects addon v1.5.8 security hardening.


The user must:

  1. Be logged in
  2. Pass MainWP extension access for slug insigner-mainwp, or have manage_options
  3. And (when WPSigner RBAC exists) pass Permissions::can_use_signatures()

If WPSigner Permissions is unavailable, fallback is manage_options only after MainWP/admin gate.

Send, remind, unlink, and access also require the document to be linked in MainWP and typically Permissions::can_modify_document (via bridge guards).

Users without manage_options may only create from templates they own (template->user_id).


Contract access (get_document_access) returns signing URLs only when can_view_signing_links() is true:

AllowedCondition
Yesmanage_options, or WPSigner Permissions::can_manage_all()
NoOther users who can still manage the extension — they see PDF actions when available, but signing links are hidden

UI flag: signing_links_hidden. The modal shows a restricted message instead of Copy/Open.


RuleDetail
Global policy lives in WPSignerSecurity & Compliance (otp_mode / kyc_mode)
MainWP does not mutate wps_optionsv1.5.8 removed Off → per-document promotion
Per-document flagsWritten only when gate mode is Choose per document and the Create/Quick create flag is on
KYCRequires Didit ready in WPSigner

Operators who need per-contract OTP/KYC from MainWP must set WPSigner policies to Choose per document first.


Soft limits use per-user transients (~30 seconds):

Action keyScope
create_sendCreate-and-send / Quick create with send
sendSend on an existing document
remindRemind (per document)

Exceeded limit returns a friendly “wait a few seconds” error — not a hard lockout.


If document create succeeds but MainWP link upsert fails, the addon deletes the draft document and returns an error. This prevents unlinked drafts accumulating in WPSigner.


All handlers: wp_ajax_imwp_* (authenticated only).

ActionPurpose
imwp_create_documentCreate from template
imwp_quick_createQuick create & send
imwp_send_documentSend
imwp_remind_documentRemind
imwp_bulk_remindBulk remind (≤50)
imwp_unlink_documentUnlink
imwp_link_documentLink existing
imwp_save_settingsSettings
imwp_client_signerResolve client → signer (POST)
imwp_document_accessAccess modal payload (POST)

Sensitive handlers read parameters from $_POST (not GET). Shared nonce action: imwp_admin.


  • Link/list queries use $wpdb->prepare with whitelisted status/column fragments
  • Admin partials use esc_html / esc_attr / esc_url
  • admin.js uses escapeHtml / jQuery .text() for dynamic strings

  • No signing UI on child sites
  • No anonymous signing endpoints
  • No change to WPSigner global security options
  • No deletion of WPSigner documents on Unlink or uninstall (uninstall drops link/activity tables only)

If you discover a vulnerability in the addon or core, follow Report a Security Issue.