{
  "parent_claim_id": "cve-2026-10835-salesmanago-export_count_contacts",
  "variant_id": "cve-2026-10835-salesmanago-export_contacts-alt-entrypoint",
  "equivalence_verdict": "same_root_cause",
  "same_root_cause_confidence": "high",
  "same_surface_confidence": "medium",
  "shared_sink": {
    "file_path": "src/Admin/Model/ExportModel.php",
    "function": "ExportModel::getExportContactsQuery()",
    "lines": "341-406 (vulnerable 3.11.2)",
    "defect": "Direct string interpolation of the attacker-controlled $this->dateFrom into the SQL literal: A.post_date >= '{$this->dateFrom}'"
  },
  "shared_input_source": {
    "file_path": "src/Admin/Model/ExportModel.php",
    "function": "ExportModel::parseArgs()",
    "lines": "138-148 (vulnerable 3.11.2)",
    "defect": "$this->dateFrom = empty($data->dateFrom) ? '2000-01-01' : $data->dateFrom; (no sanitization; $data = json_decode(base64_decode($_REQUEST['data'])))"
  },
  "shared_auth_defect": {
    "file_path": "src/Includes/SecureHelper.php",
    "function": "SecureHelper::validate_ajax_nonce()",
    "lines": "81-104 (vulnerable 3.11.2)",
    "defect": "Returns false early for non-admin users WITHOUT calling die()/wp_send_json_error(); callers ignore the return value, so an authenticated Subscriber reaches the sink with no nonce"
  },
  "parent_path": {
    "entrypoint": "POST /wp-admin/admin-ajax.php action=salesmanago_export_count_contacts",
    "controller_method": "ExportController::countContacts()",
    "controller_file": "src/Admin/Controller/ExportController.php",
    "sink_call": "ExportModel::getExportContactsQuery(true) then $wpdb->get_var($query) (scalar count primitive; count is echoed in the JSON response -> direct count oracle + UNION extraction)",
    "lines": "75-93 (vulnerable 3.11.2)"
  },
  "variant_path": {
    "entrypoint": "POST /wp-admin/admin-ajax.php action=salesmanago_export_contacts",
    "controller_method": "ExportController::exportContacts()",
    "controller_file": "src/Admin/Controller/ExportController.php",
    "sink_call": "ExportModel::getExportContactsQuery(false) then $wpdb->get_results($query, ARRAY_A) (row-set primitive; requires packageCount>0 guard; results flow to prepareContactsToExport + SALESmanago API export, so direct UNION extraction is blind via HTTP response \u2014 time-based blind SLEEP is the clean primitive)",
    "lines": "122-168 (vulnerable 3.11.2)",
    "extra_guard": "if ( $this->ExportModel->getPackageCount() ) must be truthy; attacker sets packageCount=1 in the JSON data"
  },
  "differences_from_parent": [
    "Different wp_ajax_* action / endpoint (salesmanago_export_contacts vs salesmanago_export_count_contacts).",
    "Different $wpdb primitive: get_results (row-set) vs get_var (scalar count).",
    "exportContacts requires packageCount>0 to reach the query (attacker supplies packageCount=1); countContacts runs the query unconditionally.",
    "exportContacts passes the wrong action name 'salesmanago_count_contacts' to validate_ajax_nonce in 3.11.2 (a pre-existing typo); for a Subscriber this is irrelevant because the early-return false happens regardless, so the auth-bypass is identical.",
    "Direct UNION-based data extraction via the HTTP response is available on countContacts (count echoed) but blind on exportContacts (rows go to the SALESmanago API, not echoed); time-based blind SLEEP works on both."
  ],
  "what_is_the_same": [
    "Identical SQL sink function (getExportContactsQuery) with identical dateFrom string interpolation.",
    "Identical unsanitized input assignment (parseArgs -> $this->dateFrom = $data->dateFrom).",
    "Identical authorization-bypass defect (validate_ajax_nonce early-return-without-die for non-admins).",
    "Identical trust boundary: authenticated Subscriber over HTTP to /wp-admin/admin-ajax.php.",
    "Identical attacker-controlled field: base64-JSON 'data' -> 'dateFrom'."
  ],
  "fix_coverage_for_variant": "The 3.11.3 fix covers this variant completely: validate_ajax_nonce dies 403 for non-admins (covers the exportContacts action via the AJAX_ACTIONS allow-list + per-handler manage_options gate), parseArgs validates dateFrom, and getExportContactsQuery uses $wpdb->prepare. Empirically the variant is blocked on 3.11.3 (HTTP 403, no SLEEP). Therefore the variant is an alternate trigger on the vulnerable version, NOT a bypass of the fix.",
  "is_bypass": false
}