GUAC blog

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
    3454

$ 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/libcurl.so.3",
piwik.json:   "fileName": "/usr/lib/x86_64-linux-gnu/libcurl.so.4",
piwik.json:   "fileName": "/usr/lib/x86_64-linux-gnu/libcurl.so.4.4.0",
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/libcurl-gnutls.so.3",
plone.json:   "fileName": "/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4",
plone.json:   "fileName": "/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.5.0",
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: https://docs.guac.sh/setup/. 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") {
    __typename
    ... on Package {
      type
      namespaces {
        namespace
        names {
          name
        }
      }
    }
  }
}
  

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"
              }
            ]
          }
        ]
      },
     …TRUNCATED
      {
        "__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'
"pkg:alpine//libcurl"
"pkg:alpine//curl"
"pkg:deb/ubuntu/libcurl4"
"pkg:deb/ubuntu/curl"
"pkg:deb/debian/libcurl4"
"pkg:deb/debian/libcurl4-openssl-dev"
"pkg:pypi//pycurl"
"pkg:rpm/amzn/python-pycurl"
"pkg:rpm/amzn/libcurl"
"pkg:rpm/amzn/curl"
"pkg:alpm/arch/curl"
"pkg:deb/debian/libcurl3-gnutls"
"pkg:deb/debian/curl"
"pkg:rpm/centos/libcurl-minimal"
"pkg:rpm/centos/curl"
"pkg:deb/ubuntu/libcurl3-gnutls"
"pkg:golang/github.com/couchbasedeps/go-curl"
"pkg:rpm/centos/python-pycurl"
"pkg:rpm/centos/libcurl"
"pkg:rpm/fedora/curl"
"pkg:rpm/fedora/libcurl"
"pkg:deb/debian/libcurl3"
"pkg:rpm/ol/libcurl"
"pkg:rpm/ol/curl"
"pkg:rpm/photon/curl-libs"
"pkg:rpm/photon/curl"
"pkg:deb/ubuntu/libcurl4-openssl-dev"
  

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:

 	
---FRONTIER LEVEL 0---
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

---FRONTIER LEVEL 1---
4849803: pkg:guac/spdx/docker.io/library/telegraf-latest
2719720: pkg:guac/spdx/docker.io/library/node-latest
3446447: pkg:guac/spdx/docker.io/library/piwik-latest
239474: pkg:guac/spdx/docker.io/library/buildpack-deps-latest
4849802: pkg:guac/spdx/docker.io/library/telegraf-latest
1728535: pkg:guac/spdx/docker.io/library/haskell-latest
2472917: pkg:guac/spdx/docker.io/library/monica-latest
2045229: pkg:guac/spdx/docker.io/library/joomla-latest
3402867: pkg:guac/spdx/docker.io/library/phpmyadmin-latest
4892530: pkg:guac/spdx/docker.io/library/tomee-latest
960275: pkg:guac/spdx/docker.io/library/erlang-latest
4547762: pkg:guac/spdx/docker.io/library/ruby-latest
4611812: pkg:guac/spdx/docker.io/library/rust-latest
1121489: pkg:guac/spdx/docker.io/library/gcc-latest
2708193: pkg:guac/spdx/docker.io/library/nginx-latest
2274583: pkg:guac/spdx/docker.io/library/mediawiki-latest
834321: pkg:guac/spdx/docker.io/library/elixir-latest
2811969: pkg:guac/spdx/docker.io/library/odoo-latest
1827368: pkg:guac/spdx/docker.io/library/haxe-latest
5053811: pkg:guac/spdx/docker.io/library/yourls-latest
1728536: pkg:guac/spdx/docker.io/library/haskell-latest
3706912: pkg:guac/spdx/docker.io/library/pypy-latest
2274584: pkg:guac/spdx/docker.io/library/mediawiki-latest
1560097: pkg:guac/spdx/docker.io/library/golang-latest
705010: pkg:guac/spdx/docker.io/library/drupal-latest
2153945: pkg:guac/spdx/docker.io/library/julia-latest
834320: pkg:guac/spdx/docker.io/library/elixir-latest
3871427: pkg:guac/spdx/docker.io/library/rails-latest
2811970: pkg:guac/spdx/docker.io/library/odoo-latest
3706911: pkg:guac/spdx/docker.io/library/pypy-latest
3776026: pkg:guac/spdx/docker.io/library/python-latest
4547763: pkg:guac/spdx/docker.io/library/ruby-latest
1955885: pkg:guac/spdx/docker.io/library/iojs-latest
1955886: pkg:guac/spdx/docker.io/library/iojs-latest
4611811: pkg:guac/spdx/docker.io/library/rust-latest
2045228: pkg:guac/spdx/docker.io/library/joomla-latest
705009: pkg:guac/spdx/docker.io/library/drupal-latest
1917592: pkg:guac/spdx/docker.io/library/influxdb-latest
2153944: pkg:guac/spdx/docker.io/library/julia-latest
5053812: pkg:guac/spdx/docker.io/library/yourls-latest
3377174: pkg:guac/spdx/docker.io/library/php-latest
3377175: pkg:guac/spdx/docker.io/library/php-latest
3446446: pkg:guac/spdx/docker.io/library/piwik-latest
2708192: pkg:guac/spdx/docker.io/library/nginx-latest
4037945: pkg:guac/spdx/docker.io/library/rethinkdb-latest
3309554: pkg:guac/spdx/docker.io/library/perl-latest
2573201: pkg:guac/spdx/docker.io/library/mono-latest
3309555: pkg:guac/spdx/docker.io/library/perl-latest
2719719: pkg:guac/spdx/docker.io/library/node-latest
1560096: pkg:guac/spdx/docker.io/library/golang-latest
239475: pkg:guac/spdx/docker.io/library/buildpack-deps-latest
1121490: pkg:guac/spdx/docker.io/library/gcc-latest
3958782: pkg:guac/spdx/docker.io/library/redmine-latest
3402866: pkg:guac/spdx/docker.io/library/phpmyadmin-latest
3958781: pkg:guac/spdx/docker.io/library/redmine-latest
2573200: pkg:guac/spdx/docker.io/library/mono-latest
960276: pkg:guac/spdx/docker.io/library/erlang-latest
3183579: pkg:guac/spdx/docker.io/library/owncloud-latest
2472918: pkg:guac/spdx/docker.io/library/monica-latest
3776027: pkg:guac/spdx/docker.io/library/python-latest
1917591: pkg:guac/spdx/docker.io/library/influxdb-latest
3871426: pkg:guac/spdx/docker.io/library/rails-latest
4892529: pkg:guac/spdx/docker.io/library/tomee-latest
4037944: pkg:guac/spdx/docker.io/library/rethinkdb-latest
3183578: pkg:guac/spdx/docker.io/library/owncloud-latest
1827367: pkg:guac/spdx/docker.io/library/haxe-latest

---INFO NODES---
no info nodes found

---POINTS OF CONTACT---
no POCs found


---SUBGRAPH VISUALIZER URL---
http://localhost:3000/?path=288315,1594,729846,859235,960637,1125809,1574660,1832763,2075968,2158991,2315402,2512104,2708470,2723947,2934088,3311956,3377364,3410314,3711574,3776927,3984380,4038146,4548004,4612457,4851183,5054950,1751154,1918058,2584925,1968929,3877701,3217543,3468267,4894479,3448900,267406,267405,1956416,3170064,1721289,4892275,5151532,4849803,2719720,3446447,239474,4849802,1728535,2472917,2045229,3402867,4892530,960275,4547762,4611812,1121489,2708193,2274583,834321,2811969,1827368,5053811,1728536,3706912,2274584,1560097,705010,2153945,834320,3871427,2811970,3706911,3776026,4547763,1955885,1955886,4611811,2045228,705009,1917592,2153944,5053812,3377174,3377175,3446446,2708192,4037945,3309554,2573201,3309555,2719719,1560096,239475,1121490,3958782,3402866,3958781,2573200,960276,3183579,2472918,3776027,1917591,3871426,4892529,4037944,3183578,1827367
  

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!

CertifyBad

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

Summary

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 https://guac.sh for more information and other demos. We are always building out new use cases and queries to match.

Like what you read? Share it with others.

Other blog posts 

The latest industry news, interviews, technologies, and resources.

View all posts

Previous

No older posts

Next

No newer posts

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.