In the News

Terror of cURL - Preparation is half the battle

CVE-2023-38545 - HIGH Severity Vulnerability

Parth Patel

October 16, 2023

Co-Authored with Brandon Lum (Google) and Mihai Maruseac (Google)

October 11th has come and gone, and we have more information about the HIGH severity CVE that affects the common cURL package that is used throughout the software ecosystem. We now have much more information regarding the actual exploitable vulnerability and the versions that were affected (libcurl 7.69.0 to and including 8.3.0). But almost a week before this information was released, the maintainers had already advised the community of the upcoming HIGH severity vulnerability but did not disclose information about which versions were affected, just mentioning the “last several years” of versions. 

Getting ahead of the problem and being prepared is half the battle and this statement is also very true when it comes to software supply chain security. The problem is that the vulnerability is so new and with little information about the versions that are affected, the vulnerability and SCA scanners will not be able to help you find the issue. What do you do now?

SBOMs to the rescue!?

You’ve been doing your part in response to EO 14028 and you have collected a bunch of accurately built SBOMs (securely during the build process), which should magically give you the answer! Using our favorite tool, grep, over our corpus of SBOMs, we find many occurrences of “curl”. When we look at the results, there is much to digest!

$ grep -r "curl" * | wc -l

$ grep -r "curl" *

piwik.json:   "name": "libcurl3",
piwik.json:   "licenseConcluded": "BSD-3-Clause AND BSD-4-Clause AND ISC AND curl",
piwik.json:     "referenceLocator": "cpe:2.3:a:libcurl3:libcurl3:7.52.1-5\\+deb9u7:*:*:*:*:*:*:*",
piwik.json:     "referenceLocator": "pkg:deb/debian/libcurl3@7.52.1-5+deb9u7?arch=amd64&upstream=curl&distro=debian-9",
piwik.json:   "licenseDeclared": "BSD-3-Clause AND BSD-4-Clause AND ISC AND curl",
piwik.json:   "sourceInfo": "acquired package info from DPKG DB: /usr/share/doc/libcurl3/copyright, /var/lib/dpkg/info/libcurl3:amd64.md5sums, /var/lib/dpkg/status",
piwik.json:   "fileName": "/usr/bin/curl",
piwik.json:   "fileName": "/usr/lib/x86_64-linux-gnu/",
piwik.json:   "fileName": "/usr/lib/x86_64-linux-gnu/",
piwik.json:   "fileName": "/usr/lib/x86_64-linux-gnu/",
piwik.json:   "fileName": "/usr/local/include/curl",
piwik.json:   "fileName": "/usr/share/doc/curl",
piwik.json:   "fileName": "/usr/share/doc/curl/copyright",
piwik.json:   "fileName": "/usr/share/doc/libcurl3",
piwik.json:   "fileName": "/usr/share/doc/libcurl3/copyright",
piwik.json:   "fileName": "/usr/share/zsh/vendor-completions/_curl",
piwik.json:   "fileName": "/var/lib/dpkg/info/curl.list",
piwik.json:   "fileName": "/var/lib/dpkg/info/curl.md5sums",
piwik.json:   "fileName": "/var/lib/dpkg/info/libcurl3:amd64.list",
piwik.json:   "fileName": "/var/lib/dpkg/info/libcurl3:amd64.md5sums",
piwik.json:   "fileName": "/var/lib/dpkg/info/libcurl3:amd64.shlibs",
piwik.json:   "fileName": "/var/lib/dpkg/info/libcurl3:amd64.symbols",
piwik.json:   "fileName": "/var/lib/dpkg/info/libcurl3:amd64.triggers",
plone.json:   "name": "libcurl3-gnutls",
plone.json:   "licenseConcluded": "BSD-3-Clause AND BSD-4-Clause AND ISC AND curl",
plone.json:     "referenceLocator": "cpe:2.3:a:libcurl3-gnutls:libcurl3-gnutls:7.64.0-4\\+deb10u3:*:*:*:*:*:*:*",
plone.json:     "referenceLocator": "cpe:2.3:a:libcurl3-gnutls:libcurl3_gnutls:7.64.0-4\\+deb10u3:*:*:*:*:*:*:*",
plone.json:     "referenceLocator": "cpe:2.3:a:libcurl3_gnutls:libcurl3-gnutls:7.64.0-4\\+deb10u3:*:*:*:*:*:*:*",
plone.json:     "referenceLocator": "cpe:2.3:a:libcurl3_gnutls:libcurl3_gnutls:7.64.0-4\\+deb10u3:*:*:*:*:*:*:*",
plone.json:     "referenceLocator": "cpe:2.3:a:libcurl3:libcurl3-gnutls:7.64.0-4\\+deb10u3:*:*:*:*:*:*:*",
plone.json:     "referenceLocator": "cpe:2.3:a:libcurl3:libcurl3_gnutls:7.64.0-4\\+deb10u3:*:*:*:*:*:*:*",
plone.json:     "referenceLocator": "pkg:deb/debian/libcurl3-gnutls@7.64.0-4+deb10u3?arch=amd64&upstream=curl&distro=debian-10",
plone.json:   "licenseDeclared": "BSD-3-Clause AND BSD-4-Clause AND ISC AND curl",
plone.json:   "sourceInfo": "acquired package info from DPKG DB: /usr/share/doc/libcurl3-gnutls/copyright, /var/lib/dpkg/info/libcurl3-gnutls:amd64.md5sums, /var/lib/dpkg/status",
plone.json:   "fileName": "/plone/buildout-cache/eggs/cp38/diazo-1.4.2-py3.8.egg/diazo/tests/allow-curly-brackets",
plone.json:   "fileName": "/plone/buildout-cache/eggs/cp38/diazo-1.4.2-py3.8.egg/diazo/tests/allow-curly-brackets/README.rst",
plone.json:   "fileName": "/plone/buildout-cache/eggs/cp38/diazo-1.4.2-py3.8.egg/diazo/tests/allow-curly-brackets/content.html",
plone.json:   "fileName": "/plone/buildout-cache/eggs/cp38/diazo-1.4.2-py3.8.egg/diazo/tests/allow-curly-brackets/output.html",
plone.json:   "fileName": "/plone/buildout-cache/eggs/cp38/diazo-1.4.2-py3.8.egg/diazo/tests/allow-curly-brackets/rules.xml",
plone.json:   "fileName": "/plone/buildout-cache/eggs/cp38/diazo-1.4.2-py3.8.egg/diazo/tests/allow-curly-brackets/theme.html",
plone.json:   "fileName": "/plone/buildout-cache/eggs/cp38/plone.staticresources-1.4.6-py3.8.egg/plone/staticresources/static/components/ace-builds/src/mode-curly.js",
plone.json:   "fileName": "/plone/buildout-cache/eggs/cp38/plone.staticresources-1.4.6-py3.8.egg/plone/staticresources/static/components/ace-builds/src/snippets/curly.js",
plone.json:   "fileName": "/usr/lib/x86_64-linux-gnu/",
plone.json:   "fileName": "/usr/lib/x86_64-linux-gnu/",
plone.json:   "fileName": "/usr/lib/x86_64-linux-gnu/",
plone.json:   "fileName": "/usr/share/doc/libcurl3-gnutls",
plone.json:   "fileName": "/usr/share/doc/libcurl3-gnutls/copyright",
plone.json:   "fileName": "/var/lib/dpkg/info/libcurl3-gnutls:amd64.list",
plone.json:   "fileName": "/var/lib/dpkg/info/libcurl3-gnutls:amd64.md5sums",
plone.json:   "fileName": "/var/lib/dpkg/info/libcurl3-gnutls:amd64.shlibs",
plone.json:   "fileName": "/var/lib/dpkg/info/libcurl3-gnutls:amd64.symbols",
plone.json:   "fileName": "/var/lib/dpkg/info/libcurl3-gnutls:amd64.triggers",

We see many things, license annotations, metadata files, binaries, CPEs, dynamically linked libraries, etc. However, finding the right signal in the sea of information becomes a tedious exercise!

This is the perfect use-case for GUAC (Graph for Understanding Artifact Composition) to provide insight into where other tools lack behind. GUAC aggregates all the software security metadata (SBOMS, SLSA attestations, Vulnerability reports, VEX, Scorecard, and others) into a high-fidelity graph database that can be easily and quickly queried to find the blast radius and determine a patch plan to remediate issues quickly. Let's see how GUAC could have been used in the case of the cURL vulnerability to be proactively ready when the updated version gets released.

First setup your GUAC environment by following our guide here: Once GUAC is up and running, we will ingest the SBOMs above that we generated using Syft which makes up our software environment.

Let’s find what we need!

Now with GUAC, once we’ve ingested the SBOMs, we can do a search to find things related to curl. This can be done easily with a `findSoftware` GraphQL query:

query FindCurl {
  findSoftware(searchText: "curl") {
    ... on Package {
      namespaces {
        names {

This yields succinct results of just 27 relevant curl software - both packages and libraries, from debian, alpine, pycurl, rpm/amzn, etc. 

  "data": {
    "findSoftware": [
        "__typename": "Package",
        "type": "alpine",
        "namespaces": [
            "namespace": "",
            "names": [
                "name": "libcurl"
        "__typename": "Package",
        "type": "alpine",
        "namespaces": [
            "namespace": "",
            "names": [
                "name": "curl"
        "__typename": "Package",
        "type": "deb",
        "namespaces": [
            "namespace": "ubuntu",
            "names": [
                "name": "libcurl4-openssl-dev"

Piping this out to a more readable form:

$ cat results.json | jq '.data.findSoftware[] | "pkg:" + .type + "/" + .namespaces[0].namespace + "/" + .namespaces[0].names[0].name'

From here, we can then pick out one that we know would be of interest, for example, pkg:deb/debian/curl, and let’s dive deep!

There are multiple approaches we can take:

  1. Based on the curl package being used, we can run the patch planning CLI to find which packages must be updated to remediate this vulnerability.
  2. We can also mark the curl package as “CertifyBad”, which can be used by policy engines to either send out alerts or block the deployment of any artifact or package from running in a production environment.

Patch Planning

Our ingested data contains curl Debian packages that we can query quickly. By running:

guacone query patch  plan --is-pkg-version-stop false --start-purl pkg:deb/debian/curl --search-depth 2

We see the output:

3448900: pkg:deb/debian/curl@7.52.1-5+deb9u7?distro=debian-9&arch=amd64
267406: pkg:deb/debian/curl@7.74.0-1.3+deb11u3?arch=amd64&distro=debian-11
267405: pkg:deb/debian/curl
1956416: pkg:deb/debian/curl@7.38.0-4+deb8u5?distro=debian-8&arch=amd64
3170064: pkg:deb/debian/curl@7.52.1-5+deb9u8?arch=amd64&distro=debian-9
1721289: pkg:deb/debian/curl@7.64.0-4+deb10u3?arch=amd64&distro=debian-10
4892275: pkg:deb/debian/curl@7.74.0-1.3+deb11u1?arch=amd64&distro=debian-11
5151532: pkg:deb/debian/curl

4849803: pkg:guac/spdx/
2719720: pkg:guac/spdx/
3446447: pkg:guac/spdx/
239474: pkg:guac/spdx/
4849802: pkg:guac/spdx/
1728535: pkg:guac/spdx/
2472917: pkg:guac/spdx/
2045229: pkg:guac/spdx/
3402867: pkg:guac/spdx/
4892530: pkg:guac/spdx/
960275: pkg:guac/spdx/
4547762: pkg:guac/spdx/
4611812: pkg:guac/spdx/
1121489: pkg:guac/spdx/
2708193: pkg:guac/spdx/
2274583: pkg:guac/spdx/
834321: pkg:guac/spdx/
2811969: pkg:guac/spdx/
1827368: pkg:guac/spdx/
5053811: pkg:guac/spdx/
1728536: pkg:guac/spdx/
3706912: pkg:guac/spdx/
2274584: pkg:guac/spdx/
1560097: pkg:guac/spdx/
705010: pkg:guac/spdx/
2153945: pkg:guac/spdx/
834320: pkg:guac/spdx/
3871427: pkg:guac/spdx/
2811970: pkg:guac/spdx/
3706911: pkg:guac/spdx/
3776026: pkg:guac/spdx/
4547763: pkg:guac/spdx/
1955885: pkg:guac/spdx/
1955886: pkg:guac/spdx/
4611811: pkg:guac/spdx/
2045228: pkg:guac/spdx/
705009: pkg:guac/spdx/
1917592: pkg:guac/spdx/
2153944: pkg:guac/spdx/
5053812: pkg:guac/spdx/
3377174: pkg:guac/spdx/
3377175: pkg:guac/spdx/
3446446: pkg:guac/spdx/
2708192: pkg:guac/spdx/
4037945: pkg:guac/spdx/
3309554: pkg:guac/spdx/
2573201: pkg:guac/spdx/
3309555: pkg:guac/spdx/
2719719: pkg:guac/spdx/
1560096: pkg:guac/spdx/
239475: pkg:guac/spdx/
1121490: pkg:guac/spdx/
3958782: pkg:guac/spdx/
3402866: pkg:guac/spdx/
3958781: pkg:guac/spdx/
2573200: pkg:guac/spdx/
960276: pkg:guac/spdx/
3183579: pkg:guac/spdx/
2472918: pkg:guac/spdx/
3776027: pkg:guac/spdx/
1917591: pkg:guac/spdx/
3871426: pkg:guac/spdx/
4892529: pkg:guac/spdx/
4037944: pkg:guac/spdx/
3183578: pkg:guac/spdx/
1827367: pkg:guac/spdx/

no info nodes found

no POCs found


By clicking on the guac-visualizer link, we can view the graph in real-time:

Patch Planning Visualization

If you noticed, we did not specify a version on the cURL purl we used to run the patch planning CLI. This was done such that, we do not know the vulnerable versions of cURL and we need to be prepared to update when the time comes. FRONTIER LEVEL 0, shows all the current versions of cURL we are using in our environment. Going down to FRONTIER LEVEL 1, we see the various images that need to be updated as they rely on a version of cURL. No longer do you need to re-scan or pour through large amounts of data to determine if/where cURL is used.

GUAC reduces the time it takes to remediate by quickly helping you determine your blast radius and the proper patch planning to quickly get ahead of the problem. Going a level further, GUAC can also keep track of the “Point of Contact” or organization that is responsible for a specific package. This greatly reduces the churn that enterprises with multiple organizations or teams have to determine who to contact to get the remediation process started. Moving the MTTR (Mean Time to Remediate) needle back significantly!


Depending on the package and vulnerability, you may need to mark it as “bad”. This can be useful in a variety of situations where you want to ensure that a package that depends on a vulnerable version does not run in a production environment. It can also be marked by the security team to allow for developers to quickly locate if and where they are affected. 

A quick example of how this can be done in GUAC (for our debian example):

bin/guacone certify package "unreleased vuln curl" -n pkg:deb/debian/curl

From here that package (along with all its versions) is marked as “bad” such that policy engines and other integrations can act autonomously. 

CertifyBad Visualization


SBOMs are a starting point. They help us collect the data but to get the full value out of them, we have to turn to GUAC! SBOM alone is not the answer, but combined with the synthesis capabilities of GUAC, we can be proactive about vulnerabilities before they are released. We can quickly determine the various packages that match and run patch planning queries to get to the root source that needs to be remediated. We can even mark them “bad” to trigger alerts for other teams and kick-off automated policy actions! 

This was just a small example of how GUAC can help enterprises get ahead of software supply chain incidents. Be sure to check out for more information and other demos. We are always building out new use cases and queries to match.

Want to have a conversation about your software supply chain?

We’d love to hear from you.  Get in touch and we'll get back to you.

Say Hello
By clicking “Accept”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. View our Privacy Policy for more information.