-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
359 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
from ._depgraph import DependencyGraph | ||
from ._vuln_graph import VulnerabilityGraph | ||
from ._sandboxer import RestrictionLayer | ||
from ._unsafe import unsafe_functions |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
"""List of unsafe python functions taken from | ||
https://xcg.tech.gov.sg/packages/dangerousfunctions/ | ||
""" | ||
|
||
unsafe_functions = [ | ||
"subprocess.Popen", | ||
"os.system", | ||
"os.popen", | ||
"subprocess.check_output", | ||
"builtins.eval", | ||
"builtins.exec", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,341 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Generate Dependency Graph for Numpy, Max Depth = 4" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stderr", | ||
"output_type": "stream", | ||
"text": [ | ||
"Cloning into 'numpy'...\n", | ||
"dummymodule.py:140: WARNING: SKIPPING ILLEGAL MODULE_NAME: numpy.numpy._pyinstaller.hook-numpy\n", | ||
"dummymodule.py:140: WARNING: SKIPPING ILLEGAL MODULE_NAME: numpy.numpy._pyinstaller.tests.pyinstaller-smoke\n" | ||
] | ||
}, | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"<pydeps.configs.Config object at 0x74046d34f460> \n", | ||
"\n", | ||
"changing __main__ => _dummy_numpy.py\n", | ||
"changing __main__ => _dummy_numpy.py\n", | ||
"changing __main__ => _dummy_numpy.py\n", | ||
"changing __main__ => _dummy_numpy.py\n", | ||
"Graph built with 292 nodes and 1494 edges.\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"from pygraas import DependencyGraph, VulnerabilityGraph\n", | ||
"g = DependencyGraph(package_name=\"numpy\", package_url=\"https://github.com/numpy/numpy\")\n", | ||
"graph = g.build_graph(max_bacon=4)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Generate Vulnerability Graph based on the Dependency Graph" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Vulnerability Graph marks the external packages which are Vulnerable, also add's the CVEs, advisory and \n", | ||
"vulnerable package versions as node attributes." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"<pygraas._depgraph.DependencyGraph at 0x74046d3c2740>" | ||
] | ||
}, | ||
"execution_count": 3, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"v = VulnerabilityGraph(g)\n", | ||
"v.build_vulnerability_graph()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"#### List external vulnerable packages based on the Safety-DB Database" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 4, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"['numpy', 'psutil', 'setuptools']\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"vulnerables = v.get_vulnerables()\n", | ||
"print(vulnerables)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### Read Details" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 5, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"['<1.13.2',\n", | ||
" '<1.16.3',\n", | ||
" '<1.21.0rc1',\n", | ||
" '<1.22.0',\n", | ||
" '<1.22.0',\n", | ||
" '<1.22.2',\n", | ||
" '<1.8.1',\n", | ||
" '<1.8.1']" | ||
] | ||
}, | ||
"execution_count": 5, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"v.get_vulnerables(details=True)[0][\"numpy\"][\"version\"]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 6, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"['CVE-2017-12852',\n", | ||
" 'CVE-2019-6446',\n", | ||
" 'CVE-2021-33430',\n", | ||
" 'CVE-2021-34141',\n", | ||
" 'CVE-2021-41496',\n", | ||
" 'CVE-2021-41495',\n", | ||
" 'CVE-2014-1858',\n", | ||
" 'CVE-2014-1859']" | ||
] | ||
}, | ||
"execution_count": 6, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"v.get_vulnerables(details=True)[0][\"numpy\"][\"CVE\"]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 7, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"['Numpy 1.13.2 includes a fix for CVE-2017-12852: The numpy.pad function in Numpy 1.13.1 and older versions is missing input validation. An empty list or ndarray will stick into an infinite loop, which can allow attackers to cause a DoS attack.\\r\\nhttps://github.com/numpy/numpy/issues/9560#issuecomment-322395292',\n", | ||
" 'Numpy 1.16.3 includes a fix for CVE-2019-6446: It uses the pickle Python module unsafely, which allows remote attackers to execute arbitrary code via a crafted serialized object, as demonstrated by a numpy.load call.\\r\\nNOTE: Third parties dispute this issue because it is a behavior that might have legitimate applications in (for example) loading serialized Python object arrays from trusted and authenticated sources.\\r\\nhttps://github.com/numpy/numpy/commit/89b688732b37616c9d26623f81aaee1703c30ffb',\n", | ||
" 'Numpy 1.21.0rc1 includes a fix for CVE-2021-33430: A Buffer Overflow vulnerability in the PyArray_NewFromDescr_int function of ctors.c when specifying arrays of large dimensions (over 32) from Python code, which could let a malicious user cause a Denial of Service. \\r\\nNOTE: The vendor does not agree this is a vulnerability. In (very limited) circumstances a user may be able provoke the buffer overflow, the user is most likely already privileged to at least provoke denial of service by exhausting memory. Triggering this further requires the use of uncommon API (complicated structured dtypes), which is very unlikely to be available to an unprivileged user.\\r\\nhttps://github.com/numpy/numpy/issues/18939',\n", | ||
" 'Numpy 1.22.0 includes a fix for CVE-2021-34141: An incomplete string comparison in the numpy.core component in NumPy before 1.22.0 allows attackers to trigger slightly incorrect copying by constructing specific string objects. \\r\\nNOTE: the vendor states that this reported code behavior is \"completely harmless.\"\\r\\nhttps://github.com/numpy/numpy/issues/18993',\n", | ||
" 'Numpy 1.22.0 includes a fix for CVE-2021-41496: Buffer overflow in the array_from_pyobj function of fortranobject.c, which allows attackers to conduct a Denial of Service attacks by carefully constructing an array with negative values. \\r\\nNOTE: The vendor does not agree this is a vulnerability; the negative dimensions can only be created by an already privileged user (or internally).\\r\\nhttps://github.com/numpy/numpy/issues/19000',\n", | ||
" 'Numpy 1.22.2 includes a fix for CVE-2021-41495: Null Pointer Dereference vulnerability exists in numpy.sort in NumPy in the PyArray_DescrNew function due to missing return-value validation, which allows attackers to conduct DoS attacks by repetitively creating sort arrays. \\r\\nNOTE: While correct that validation is missing, an error can only occur due to an exhaustion of memory. If the user can exhaust memory, they are already privileged. Further, it should be practically impossible to construct an attack which can target the memory exhaustion to occur at exactly this place.\\r\\nNOTE2: The specs we include in this advisory differ from the publicly available on other sources. For example, the advisory posted by the NVD indicate that versions up to and including 1.19.0 are affected. However, research by Safety CLI Cybersecurity confirms that the vulnerability remained unaddressed until version 1.22.2.',\n", | ||
" 'Numpy 1.8.1 includes a fix for CVE-2014-1858: __init__.py in f2py in NumPy before 1.8.1 allows local users to write to arbitrary files via a symlink attack on a temporary file.\\r\\nhttps://github.com/numpy/numpy/commit/0bb46c1448b0d3f5453d5182a17ea7ac5854ee15',\n", | ||
" 'Numpy 1.8.1 includes a fix for CVE-2014-1859: (1) core/tests/test_memmap.py, (2) core/tests/test_multiarray.py, (3) f2py/f2py2e.py, and (4) lib/tests/test_io.py in NumPy before 1.8.1 allow local users to write to arbitrary files via a symlink attack on a temporary file.\\r\\nhttps://github.com/numpy/numpy/pull/4262']" | ||
] | ||
}, | ||
"execution_count": 7, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"v.get_vulnerables(details=True)[0][\"numpy\"][\"advisory\"]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"`np.pad` seems vulnerable, we can restrict it using `pygraas.RestrictionLayer` ." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Here, just for demonstration purposes, we'll restricted the usage of `numpy.zeros` which is called internally in `skimage.filters.sobel` ." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 16, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"ename": "RestrictedFunctionError", | ||
"evalue": "The function 'numpy.zeros' is blocked.", | ||
"output_type": "error", | ||
"traceback": [ | ||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | ||
"\u001b[0;31mRestrictedFunctionError\u001b[0m Traceback (most recent call last)", | ||
"Cell \u001b[0;32mIn[16], line 9\u001b[0m\n\u001b[1;32m 6\u001b[0m l\u001b[38;5;241m.\u001b[39mactivate()\n\u001b[1;32m 8\u001b[0m image \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mrandom((\u001b[38;5;241m4000\u001b[39m, \u001b[38;5;241m4000\u001b[39m))\n\u001b[0;32m----> 9\u001b[0m \u001b[43msobel\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimage\u001b[49m\u001b[43m)\u001b[49m\n", | ||
"File \u001b[0;32m~/.local/lib/python3.10/site-packages/skimage/filters/edges.py:250\u001b[0m, in \u001b[0;36msobel\u001b[0;34m(image, mask, axis, mode, cval)\u001b[0m\n\u001b[1;32m 200\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21msobel\u001b[39m(image, mask\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m, axis\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, mode\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mreflect\u001b[39m\u001b[38;5;124m'\u001b[39m, cval\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0.0\u001b[39m):\n\u001b[1;32m 201\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Find edges in an image using the Sobel filter.\u001b[39;00m\n\u001b[1;32m 202\u001b[0m \n\u001b[1;32m 203\u001b[0m \u001b[38;5;124;03m Parameters\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 248\u001b[0m \u001b[38;5;124;03m >>> edges = filters.sobel(camera)\u001b[39;00m\n\u001b[1;32m 249\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 250\u001b[0m output \u001b[38;5;241m=\u001b[39m \u001b[43m_generic_edge_filter\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 251\u001b[0m \u001b[43m \u001b[49m\u001b[43mimage\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msmooth_weights\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mSOBEL_SMOOTH\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxis\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmode\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmode\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcval\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcval\u001b[49m\n\u001b[1;32m 252\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 253\u001b[0m output \u001b[38;5;241m=\u001b[39m _mask_filter_result(output, mask)\n\u001b[1;32m 254\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m output\n", | ||
"File \u001b[0;32m~/.local/lib/python3.10/site-packages/skimage/filters/edges.py:183\u001b[0m, in \u001b[0;36m_generic_edge_filter\u001b[0;34m(image, smooth_weights, edge_weights, axis, mode, cval, mask)\u001b[0m\n\u001b[1;32m 181\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 182\u001b[0m image \u001b[38;5;241m=\u001b[39m img_as_float(image)\n\u001b[0;32m--> 183\u001b[0m output \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mzeros\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimage\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mshape\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdtype\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mimage\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdtype\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 185\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m edge_dim \u001b[38;5;129;01min\u001b[39;00m axes:\n\u001b[1;32m 186\u001b[0m kernel \u001b[38;5;241m=\u001b[39m _reshape_nd(edge_weights, ndim, edge_dim)\n", | ||
"File \u001b[0;32m/usr/lib/python3.10/unittest/mock.py:1114\u001b[0m, in \u001b[0;36mCallableMixin.__call__\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1112\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_mock_check_sig(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 1113\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_increment_mock_call(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m-> 1114\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_mock_call\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", | ||
"File \u001b[0;32m/usr/lib/python3.10/unittest/mock.py:1118\u001b[0m, in \u001b[0;36mCallableMixin._mock_call\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1117\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_mock_call\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;241m/\u001b[39m, \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[0;32m-> 1118\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_execute_mock_call\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", | ||
"File \u001b[0;32m/usr/lib/python3.10/unittest/mock.py:1179\u001b[0m, in \u001b[0;36mCallableMixin._execute_mock_call\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1177\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m result\n\u001b[1;32m 1178\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 1179\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43meffect\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1181\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m result \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m DEFAULT:\n\u001b[1;32m 1182\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m result\n", | ||
"File \u001b[0;32m~/Desktop/dev/ga/pygraas/_sandboxer.py:13\u001b[0m, in \u001b[0;36mRestrictionLayer._restrict_function.<locals>.restricted_func\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mrestricted_func\u001b[39m(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[0;32m---> 13\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m RestrictedFunctionError(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThe function \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfunc_path\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m is blocked.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", | ||
"\u001b[0;31mRestrictedFunctionError\u001b[0m: The function 'numpy.zeros' is blocked." | ||
] | ||
} | ||
], | ||
"source": [ | ||
"from pygraas import RestrictionLayer, unsafe_functions\n", | ||
"from skimage.filters import sobel\n", | ||
"import numpy as np\n", | ||
"\n", | ||
"# Block other unsafe functions as well.\n", | ||
"unsafe = [\"numpy.zeros\"].extend(unsafe_functions)\n", | ||
"\n", | ||
"l = RestrictionLayer(unsafe)\n", | ||
"l.activate()\n", | ||
"\n", | ||
"image = np.random.random((4000, 4000))\n", | ||
"sobel(image)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"#### Degree of the \"psutil\" node " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 9, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"{'in_degree': 10, 'out_degree': 1}" | ||
] | ||
}, | ||
"execution_count": 9, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"v.get_degree(vulnerables[1])" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"#### List of Public Nodes that have a path to vulnerable \"setuptools\"" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 10, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"[{'bz2 - setuptools': True},\n", | ||
" {'dis - setuptools': True},\n", | ||
" {'heapq - setuptools': True},\n", | ||
" {'dataclasses - setuptools': True},\n", | ||
" {'collections - setuptools': True},\n", | ||
" {'lzma - setuptools': True},\n", | ||
" {'codecs - setuptools': True},\n", | ||
" {'errno - setuptools': True},\n", | ||
" {'fcntl - setuptools': True},\n", | ||
" {'math - setuptools': True},\n", | ||
" {'enum - setuptools': True},\n", | ||
" {'io - setuptools': True},\n", | ||
" {'email - setuptools': True},\n", | ||
" {'importlib - setuptools': True},\n", | ||
" {'difflib - setuptools': True},\n", | ||
" {'getopt - setuptools': True},\n", | ||
" {'copy - setuptools': True},\n", | ||
" {'base64 - setuptools': True},\n", | ||
" {'doctest - setuptools': True},\n", | ||
" {'argparse - setuptools': True}]" | ||
] | ||
}, | ||
"execution_count": 10, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"# Show only the first 20 entries for demonstration.\n", | ||
"v.get_vulnerable_public_nodes(vulnerables[2])[0: 20]" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.10.12" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |