CVE-2021-43780 (Python, published 2021-11-24T16:15Z)
Description: value: Redash is a package for data visualization and sharing. In versions 10.0 and priorm the implementation of URL-loading data sources like JSON, CSV, or Excel is vulnerable to advanced methods of Server Side Request Forgery (SSRF). These vulnerabilities are only exploitable on installations where a URL-loading data source is enabled. As of time of publication, the `master` and `release/10.x.x` branches address this by applying the Advocate library for making http requests instead of the requests library directly. Users should upgrade to version 10.0.1 to receive this patch. There are a few workarounds for mitigating the vulnerability without upgrading. One can disable the vulnerable data sources entirely, by adding the following env variable to one's configuration, making them unavailable inside the webapp. One can switch any data source of certain types (viewable in the GitHub Security Advisory) to be `View Only` for all groups on the Settings > Groups > Data Sources screen. For users unable to update an admin may modify Redash's configuration through environment variables to mitigate this issue. Depending on the version of Redash, an admin may also need to run a CLI command to re-encrypt some fields in the database. The `master` and `release/10.x.x` branches as of time of publication have removed the default value for `REDASH_COOKIE_SECRET`. All future releases will also require this to be set explicitly. For existing installations, one will need to ensure that explicit values are set for the `REDASH_COOKIE_SECRET` and `REDASH_SECRET_KEY `variables.
Severity: MEDIUM (CVSS v3 base score: 8.8)
Weakness: CWE-918 \u2014 Server-Side Request Forgery (SSRF)
The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
Repository: https://github.com/getredash/redash
Files changed:
redash/query_runner/__init__.py
redash/query_runner/csv.py
redash/query_runner/excel.py
redash/query_runner/json_ds.py
redash/utils/requests_session.py
requirements_all_ds.txt
tests/query_runner/test_http.py
Commit message: Merge pull request from GHSA-fcpv-hgq6-87h7



Vulnerable code:
from redash.utils.requests_session import requests, requests_session
def is_private_address(url):
    hostname = urlparse(url).hostname
    ip_address = socket.gethostbyname(hostname)
    return ipaddress.ip_address(text_type(ip_address)).is_private


        if is_private_address(url) and settings.ENFORCE_PRIVATE_ADDRESS_BLOCK:
            raise Exception("Can't query private addresses.")
        except requests.HTTPError as exc:
        except requests.RequestException as exc:
import requests
from redash import settings

            if is_private_address(path) and settings.ENFORCE_PRIVATE_ADDRESS_BLOCK:
                raise Exception("Can't query private addresses.")
            response = requests.get(url=path, headers={"User-agent": ua})
import requests
from redash import settings
            if is_private_address(path) and settings.ENFORCE_PRIVATE_ADDRESS_BLOCK:
                raise Exception("Can't query private addresses.")
            response = requests.get(url=path, headers={"User-agent": ua})
from redash import settings
    is_private_address,
        if is_private_address(query["url"]) and settings.ENFORCE_PRIVATE_ADDRESS_BLOCK:
            raise Exception("Can't query private addresses.")
import requests
class ConfiguredSession(requests.Session):
from redash.utils.requests_session import requests, ConfiguredSession
        http_error = requests.HTTPError()
        requests_exception = requests.RequestException(exception_message)

Fixed code:
from redash.utils.requests_session import requests_or_advocate, requests_session, UnacceptableAddressException

        except requests_or_advocate.HTTPError as exc:
        except UnacceptableAddressException as exc:
            logger.exception(exc)
            error = "Can't query private addresses."
        except requests_or_advocate.RequestException as exc:
from redash.utils.requests_session import requests_or_advocate, UnacceptableAddressException

            response = requests_or_advocate.get(url=path, headers={"User-agent": ua})
        except UnacceptableAddressException:
            error = "Can't query private addresses."
            json_data = None
from redash.utils.requests_session import requests_or_advocate, UnacceptableAddressException

            response = requests_or_advocate.get(url=path, headers={"User-agent": ua})
        except UnacceptableAddressException:
            error = "Can't query private addresses."
            json_data = None

from redash.utils.requests_session import requests_or_advocate, UnacceptableAddressException

from advocate.exceptions import UnacceptableAddressException
if settings.ENFORCE_PRIVATE_ADDRESS_BLOCK:
    import advocate as requests_or_advocate
else:
    import requests as requests_or_advocate


class ConfiguredSession(requests_or_advocate.Session):
advocate==1.0.0
from redash.utils.requests_session import requests_or_advocate, ConfiguredSession
        http_error = requests_or_advocate.HTTPError()
        requests_exception = requests_or_advocate.RequestException(exception_message)