Skip to main content

CKAN Authenticated SSRF <= 2.9.11/2.10.4

 

Vulnerability Information

Product: Ckan

Vendor: https://github.com/ckan 

Affected Version(s): <= 2.9.11/2.10.4

CVE ID: TBD

Description: SSRF vulnerability in resource proxy functionality in Ckan <=2.9.11/2.10.4, allowing authenticated attackers to scan internal ports/hosts, and map the infrastructure environment. 

Vulnerability Type: Server Side Request Forgery

Root Cause: User supplied property is not sanitized against common SSRF payloads when specifying the URL of external resources.

Impact: An authenticated attacker can scan ports/hosts of the internal network, and map the infrastructure environment.

 

Reproduction Steps

1. Use grep to search potential vulnerable code:

image.png

2. Take a closer look into the code:

<...SNIP...>
    resource_id = data_dict[u'resource_id']
    log.info(u'Proxify resource {id}'.format(id=resource_id))
    try:
        resource = get_action(u'resource_show')(context, {u'id': resource_id})
    except logic.NotFound:
        return abort(404, _(u'Resource not found'))
    url = resource[u'url']

    parts = urlsplit(url)
    if not parts.scheme or not parts.netloc:
        return abort(409, _(u'Invalid URL.'))

    timeout = config.get('ckan.resource_proxy.timeout')
    max_file_size = config.get(u'ckan.resource_proxy.max_file_size')
    response = make_response()
    try:
        did_get = False
        r = requests.head(url, timeout=timeout)
        if r.status_code in (400, 403, 405):
            r = requests.get(url, timeout=timeout, stream=True)
<...SNIP...>        

url is a user supplied property, and no input sanitization are employed.

3. To exploit the vulnerability, resource proxy plugin should be enabled: https://docs.ckan.org/en/2.9/maintaining/data-viewer.html#resource-proxy 

4. The vulnerability requires authentication, and the user should have specific permissions.

5. Add a view for a resource, specify the above internal URL.
image.png

image.png
6. Access the view, we can see hit logs. Attacker induces the server to make a request on his behalf.

image.png

7. Stop the HTTP listener, and switch to a TCP listener.
image.png
8. Preview the view again, and the listener captures the access log against. 
image.png
Interestingly, since it is a non-http port, the preview keeps loading.
image.png
The difference in response time can indicate whether a port is open, and whether the port is a http/https port. In this way, attackers can weaponize this vulnerability to scan internal network's hosts and ports.