Skip to content

Commit

Permalink
generate directive (#3)
Browse files Browse the repository at this point in the history
* Use generate directive

* Readme update

* Temp commit
  • Loading branch information
Prabhu Subramanian authored Dec 27, 2022
1 parent a7c5cbf commit 69c4488
Show file tree
Hide file tree
Showing 13 changed files with 3,593 additions and 3,548 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/pythonpublish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ on:
push:
branches:
- main
- feature/*
tags:
- 'v*'
workflow_dispatch:

env:
REGISTRY: ghcr.iopy
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
Expand All @@ -32,6 +31,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/')
run: |
poetry install --no-cache --without dev
poetry run pytest
poetry publish --build --username $PYPI_USERNAME --password $PYPI_PASSWORD
env:
PYPI_USERNAME: ${{ secrets.PYPI_USERNAME }}
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@ curl -F 'file=@/tmp/bom.json' http://0.0.0.0:9000/import -H "Authorization: Bear
## Cloud Setup

Refer to the instructions under [contrib](contrib/microk8s/INSTALL.md) to setup a microk8s cluster with threat-db and dgraph.

## Discord support

The developers could be reached via the [discord](https://discord.gg/DCNxzaeUpd) channel.
4 changes: 2 additions & 2 deletions contrib/microk8s/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ dev-db-dgraph-zero-2 1/1 Running 0 29m
dev-db-dgraph-alpha-2 1/1 Running 0 29m
```

````
```
$ microk8s kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.152.183.1 <none> 443/TCP 52m
Expand Down Expand Up @@ -397,4 +397,4 @@ Check pod limits
microk8s kubectl get pods dev-db-dgraph-zero-0 -o jsonpath='{range .spec.containers[*]}{"Container Name: "}{.name}{"\n"}{"Requests:"}{.resources.requests}{"\n"}{"Limits:"}{.resources.limits}{"\n"}{end}'
```

````

Binary file modified docs/ThreatDB.pdf
Binary file not shown.
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ classifiers = [
"Intended Audience :: System Administrators",
"Topic :: Utilities",
"Topic :: Security",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
Expand Down
29 changes: 29 additions & 0 deletions queries-graphql.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@

## Aggregate queries

Count of BoM, Component and Vulnerability

```
query {
aggregateBom {
count
}
}
```

```
query {
aggregateComponent {
count
}
}
```

```
query {
aggregateVulnerability {
count
}
}
```

# Get component by purl

```
Expand Down
1 change: 1 addition & 0 deletions tests/data/NodeGoat/sbom-nodejs.vex.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions tests/data/NodeGoat/sbom-yaml-manifest.vex.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions tests/data/sbom-universal.vex.json

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions tests/test_loader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import os

import threat_db.loader as loader


def test_get_pkg_vulns():
parsed_obj = loader.get_pkg_vulns_json(
os.path.join(
os.path.dirname(__file__), "data", "NodeGoat", "sbom-nodejs.vex.json"
)
)
assert (
parsed_obj["serial_number"] == "urn:uuid:25223366-1379-41f4-8abf-3a4e11d6548f"
)
assert parsed_obj["metadata"]
assert len(parsed_obj["components"]) == 1080
assert len(parsed_obj["services"]) == 0
assert len(parsed_obj["vulnerabilities"]) == 99

parsed_obj = loader.get_pkg_vulns_json(
os.path.join(
os.path.dirname(__file__), "data", "NodeGoat", "sbom-yaml-manifest.vex.json"
)
)
assert (
parsed_obj["serial_number"] == "urn:uuid:1a1ffcb3-2c26-43af-8032-d312627ab9f8"
)
assert parsed_obj["metadata"]
assert len(parsed_obj["components"]) == 207
assert len(parsed_obj["services"]) == 2
assert len(parsed_obj["vulnerabilities"]) == 11
44 changes: 39 additions & 5 deletions threat_db/base-schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ List of roles
"""
roles: [UserRole]
"""
Is this a bot user for automation?
"""
isBot: Boolean
"""
Is this user account disabled?
"""
disabled: Boolean
Expand Down Expand Up @@ -115,7 +119,13 @@ Is this role disabled?
"""
Results from a scan
"""
type ScanResult @withSubscription {
type ScanResult @generate(
mutation: {
add: true,
delete: false
},
subscription: true
) {
"""
Unique ID such as UUID or ULID
"""
Expand Down Expand Up @@ -189,7 +199,13 @@ Direct pdf report url for this scan result
"""
Scan of an application
"""
type Scan {
type Scan @generate(
mutation: {
add: true,
delete: false
},
subscription: false
) {
"""
Unique ID such as UUID or ULID
"""
Expand Down Expand Up @@ -287,7 +303,13 @@ VCS Commit Hash
"""
Represents an application
"""
type Application @withSubscription {
type Application @generate(
mutation: {
add: true,
delete: false
},
subscription: true
) {
"""
Unique ID such as UUID or ULID
"""
Expand Down Expand Up @@ -353,6 +375,10 @@ Modified date
"""
modified: DateTime! @search
"""
For application groups, there could be dependent sub-applications
"""
subApplications: [Application]
"""
List of teams
"""
teams: [Team]
Expand Down Expand Up @@ -572,7 +598,13 @@ List of properties
"""
Bom type
"""
type Bom {
type Bom @generate(
mutation: {
add: true,
delete: false
},
subscription: false
) {
"""
Serial number
"""
Expand Down Expand Up @@ -805,7 +837,9 @@ Details for the state
"""
Vulnerability type
"""
type Vulnerability @withSubscription {
type Vulnerability @generate(
subscription: true
) {
"""
Unique reference within a BoM
"""
Expand Down
35 changes: 20 additions & 15 deletions threat_db/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,18 @@ def cleanup_license_string(license_str):
def get_pkg_vulns_json(jsonfile):
"""Method to extract packages from a bom json file"""
if not os.path.exists(jsonfile):
return None, None, None, None
return {}
with open(jsonfile) as fp:
try:
bom_data = orjson.loads(fp.read())
if bom_data:
return get_pkg_vulns_from_bom(bom_data)
except Exception:
return None, None, None, None
return {}


def get_pkg_vulns_from_bom(bom_data):
pkgs = []
components = []
serial_number = None
metadata = {}
metadata = bom_data.get("metadata")
Expand Down Expand Up @@ -94,7 +94,7 @@ def get_pkg_vulns_from_bom(bom_data):
"appearsIn": [{"serialNumber": serial_number}],
}
del fcomp["bom-ref"]
pkgs.append(fcomp)
components.append(fcomp)
for avuln in bom_data.get("vulnerabilities", []):
bomRef = avuln.get("bom-ref")
if added_vkeys.get(bomRef):
Expand Down Expand Up @@ -128,7 +128,14 @@ def get_pkg_vulns_from_bom(bom_data):
del fvuln["bom-ref"]
vulnerabilities.append(fvuln)
added_vkeys[bomRef] = True
return (serial_number, metadata, pkgs, vulnerabilities)
return {
"serial_number": serial_number,
"metadata": metadata,
"components": components,
"services": bom_data.get("services", []),
"vulnerabilities": vulnerabilities,
"bom_data": bom_data,
}


def process_vex(client, data_dir, remove_on_success=False):
Expand All @@ -140,23 +147,20 @@ def process_vex(client, data_dir, remove_on_success=False):


def process_vex_file(client, jsonf):
parsed_obj = {}
if isinstance(jsonf, SpooledTemporaryFile):
try:
(
serial_number,
metadata,
components,
vulnerabilities,
) = get_pkg_vulns_from_bom(orjson.loads(jsonf.read()))
parsed_obj = get_pkg_vulns_from_bom(orjson.loads(jsonf.read()))
except Exception as ex:
LOG.warn("Exception while converting to json from tempfile")
LOG.exception(ex)
return False
else:
LOG.debug(f"Processing {jsonf}")
(serial_number, metadata, components, vulnerabilities) = get_pkg_vulns_json(
jsonf
)
parsed_obj = get_pkg_vulns_json(jsonf)
serial_number = parsed_obj.get("serial_number")
components = parsed_obj.get("components")
metadata = parsed_obj.get("metadata")
if serial_number and components:
LOG.info(f"Creating Bom with {len(components)} components from {jsonf}")
root_component = metadata.get("component", None)
Expand All @@ -175,7 +179,8 @@ def process_vex_file(client, jsonf):
"component": root_component,
},
"components": components,
"vulnerabilities": vulnerabilities,
"services": parsed_obj.get("services"),
"vulnerabilities": parsed_obj.get("vulnerabilities"),
}
],
)
Expand Down
Loading

0 comments on commit 69c4488

Please sign in to comment.