Skip to content

Instantly share code, notes, and snippets.

@oshoval
Last active April 22, 2025 08:09
Show Gist options
  • Select an option

  • Save oshoval/2eae889f25582b723d408ab30de50c8d to your computer and use it in GitHub Desktop.

Select an option

Save oshoval/2eae889f25582b723d408ab30de50c8d to your computer and use it in GitHub Desktop.
CVE Symbol check
import requests
from lxml import html
url = "https://pkg.go.dev/vuln/GO-2024-3333"
response = requests.get(url)
tree = html.fromstring(response.content)
symbols_div = tree.xpath('//div[@class="VulnEntryPackages-attr VulnEntryPackages-symbols"]')[0]
symbols = symbols_div.xpath('.//ul/li/a/text()')
package_name = symbols_div.xpath('.//ul/li/a/@href')[0].split('#')[0].lstrip('/')
# print(f"{package_name}\n")
# print("\n".join(symbols))
for symbol in symbols:
cmd = f'callgraph -format=digraph ./... | digraph nodes | egrep "{package_name}.*{symbol}"'
print(cmd)
@oshoval
Copy link
Author

oshoval commented Apr 3, 2025

Quick and dirty poc, still need to fix / improve a lot

Example output

callgraph -format=digraph ./... | digraph nodes | egrep "golang.org/x/net/html.*Parse"
callgraph -format=digraph ./... | digraph nodes | egrep "golang.org/x/net/html.*ParseFragment"
callgraph -format=digraph ./... | digraph nodes | egrep "golang.org/x/net/html.*ParseFragmentWithOptions"
callgraph -format=digraph ./... | digraph nodes | egrep "golang.org/x/net/html.*ParseWithOptions"

@oshoval
Copy link
Author

oshoval commented Apr 6, 2025

Given the CVE, i.e CVE-2024-45338
We can get the NVD data, and the https://pkg.go.dev/vuln link via:
curl -s https://api.osv.dev/v1/vulns/CVE-2024-45338 | jq | grep pkg.go | awk -F\" '{print $4}'

maybe there is a more straight forward way that given CVE, we will get the package / affected symbols

@oshoval
Copy link
Author

oshoval commented Apr 9, 2025

Putting it together
The regex isn't perfect yet (it can match partial matches and so on)

Usage example (in the source code directory):
./cve.py CVE-2024-45338

#!/usr/bin/env python3

import requests
import json
from lxml import html
import sys
import subprocess


results = []
def find_pkg_go(obj):
    if isinstance(obj, dict):
        for k, v in obj.items():
            find_pkg_go(v)
    elif isinstance(obj, list):
        for item in obj:
            find_pkg_go(item)
    elif isinstance(obj, str) and "pkg.go" in obj:
        results.append(obj)


if len(sys.argv) != 2:
    print("Usage: cve.py <CVE-ID>")
    exit(1)

cve_id = sys.argv[1]

url = f"https://api.osv.dev/v1/vulns/{cve_id}"

response = requests.get(url)
data = response.json()
find_pkg_go(data)

if len(results) != 1:
    print("can't find go package URL")
    exit(1)

url = results[0]
response = requests.get(url)
tree = html.fromstring(response.content)

symbols_div = tree.xpath('//div[@class="VulnEntryPackages-attr VulnEntryPackages-symbols"]')[0]
symbols = symbols_div.xpath('.//ul/li/a/text()')

package_name = symbols_div.xpath('.//ul/li/a/@href')[0].split('#')[0].lstrip('/')

for symbol in symbols:
    cmd = f'callgraph -format=digraph ./... | digraph nodes | grep -E "{package_name}.*{symbol}"'
    print(cmd)
    result = subprocess.run(cmd, shell=True)
    if result.returncode == 0:
        sys.exit(1)

print("No symbols found")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment