Skip to content

Commit d593747

Browse files
committed
Add OWASP Kubernetes importer support
1 parent 7c97a76 commit d593747

6 files changed

Lines changed: 408 additions & 0 deletions
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import unittest
2+
3+
from application import create_app, sqla # type: ignore
4+
from application.database import db
5+
from application.defs import cre_defs as defs
6+
from application.prompt_client import prompt_client
7+
from application.utils.external_project_parsers.parsers import (
8+
owasp_kubernetes_top10_2022,
9+
)
10+
11+
12+
class TestOwaspKubernetesTop10_2022Parser(unittest.TestCase):
13+
def tearDown(self) -> None:
14+
sqla.session.remove()
15+
sqla.drop_all()
16+
self.app_context.pop()
17+
18+
def setUp(self) -> None:
19+
self.app = create_app(mode="test")
20+
self.app_context = self.app.app_context()
21+
self.app_context.push()
22+
sqla.create_all()
23+
self.collection = db.Node_collection()
24+
25+
def test_parse(self) -> None:
26+
for cre_id, name in [
27+
("233-748", "Configuration hardening"),
28+
("486-813", "Configuration"),
29+
("053-751", "Force build pipeline to check outdated/insecure components"),
30+
]:
31+
self.collection.add_cre(defs.CRE(id=cre_id, name=name, description=""))
32+
33+
result = owasp_kubernetes_top10_2022.OwaspKubernetesTop10_2022().parse(
34+
self.collection, prompt_client.PromptHandler(database=self.collection)
35+
)
36+
37+
entries = result.results["OWASP Kubernetes Top Ten 2022"]
38+
self.assertEqual(10, len(entries))
39+
self.assertEqual("K01", entries[0].sectionID)
40+
self.assertEqual("Insecure Workload Configurations", entries[0].section)
41+
self.assertEqual(
42+
["233-748", "486-813"], [l.document.id for l in entries[0].links]
43+
)
44+
self.assertEqual("K10", entries[-1].sectionID)
45+
self.assertEqual(["053-751"], [l.document.id for l in entries[-1].links])
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import unittest
2+
import tempfile
3+
from pathlib import Path
4+
5+
from application import create_app, sqla # type: ignore
6+
from application.database import db
7+
from application.defs import cre_defs as defs
8+
from application.prompt_client import prompt_client
9+
from application.utils.external_project_parsers.parsers import (
10+
owasp_kubernetes_top10_2025,
11+
)
12+
13+
14+
class TestOwaspKubernetesTop10_2025Parser(unittest.TestCase):
15+
def tearDown(self) -> None:
16+
sqla.session.remove()
17+
sqla.drop_all()
18+
self.app_context.pop()
19+
20+
def setUp(self) -> None:
21+
self.app = create_app(mode="test")
22+
self.app_context = self.app.app_context()
23+
self.app_context.push()
24+
sqla.create_all()
25+
self.collection = db.Node_collection()
26+
27+
def test_parse(self) -> None:
28+
for cre_id, name in [
29+
("233-748", "Configuration hardening"),
30+
("486-813", "Configuration"),
31+
("148-420", "Log integrity"),
32+
("402-706", "Log relevant"),
33+
("843-841", "Log discretely"),
34+
]:
35+
self.collection.add_cre(defs.CRE(id=cre_id, name=name, description=""))
36+
37+
result = owasp_kubernetes_top10_2025.OwaspKubernetesTop10_2025().parse(
38+
self.collection, prompt_client.PromptHandler(database=self.collection)
39+
)
40+
41+
entries = result.results["OWASP Kubernetes Top Ten 2025 (Draft)"]
42+
self.assertEqual(10, len(entries))
43+
self.assertEqual("K01", entries[0].sectionID)
44+
self.assertEqual("Insecure Workload Configurations", entries[0].section)
45+
self.assertEqual(
46+
["233-748", "486-813"], [l.document.id for l in entries[0].links]
47+
)
48+
self.assertEqual("K10", entries[-1].sectionID)
49+
self.assertEqual(
50+
["148-420", "402-706", "843-841"],
51+
[l.document.id for l in entries[-1].links],
52+
)
53+
54+
def test_parse_falls_back_to_2022_mapping_when_2025_links_missing(self) -> None:
55+
self.collection.add_cre(
56+
defs.CRE(id="148-420", name="Log integrity", description="")
57+
)
58+
59+
with tempfile.TemporaryDirectory() as tmpdir:
60+
tmp_path = Path(tmpdir)
61+
current_file = tmp_path / "k8s_2025.json"
62+
fallback_file = tmp_path / "k8s_2022.json"
63+
current_file.write_text(
64+
"""
65+
[
66+
{
67+
"section_id": "K10",
68+
"section": "Inadequate Logging And Monitoring",
69+
"hyperlink": "https://example.com/k10",
70+
"cre_ids": ["999-999"],
71+
"fallback_section_ids": ["K05"]
72+
}
73+
]
74+
""".strip(),
75+
encoding="utf-8",
76+
)
77+
fallback_file.write_text(
78+
"""
79+
[
80+
{
81+
"section_id": "K05",
82+
"section": "Inadequate Logging and Monitoring",
83+
"hyperlink": "https://example.com/k05",
84+
"cre_ids": ["148-420"]
85+
}
86+
]
87+
""".strip(),
88+
encoding="utf-8",
89+
)
90+
91+
parser = owasp_kubernetes_top10_2025.OwaspKubernetesTop10_2025()
92+
parser.data_file = current_file
93+
parser.fallback_data_file = fallback_file
94+
95+
result = parser.parse(
96+
self.collection,
97+
prompt_client.PromptHandler(database=self.collection),
98+
)
99+
100+
entries = result.results["OWASP Kubernetes Top Ten 2025 (Draft)"]
101+
self.assertEqual(1, len(entries))
102+
self.assertEqual(["148-420"], [link.document.id for link in entries[0].links])
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
[
2+
{
3+
"section_id": "K01",
4+
"section": "Insecure Workload Configurations",
5+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/2022/en/src/K01-insecure-workload-configurations",
6+
"cre_ids": ["233-748", "486-813"]
7+
},
8+
{
9+
"section_id": "K02",
10+
"section": "Supply Chain Vulnerabilities",
11+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/2022/en/src/K02-supply-chain-vulnerabilities",
12+
"cre_ids": ["613-285", "613-287"]
13+
},
14+
{
15+
"section_id": "K03",
16+
"section": "Overly Permissive RBAC Configurations",
17+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/2022/en/src/K03-overly-permissive-rbac-configurations",
18+
"cre_ids": ["128-128", "724-770"]
19+
},
20+
{
21+
"section_id": "K04",
22+
"section": "Lack of Centralized Policy Enforcement",
23+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/2022/en/src/K04-lack-of-centralized-policy-enforcement",
24+
"cre_ids": ["117-371"]
25+
},
26+
{
27+
"section_id": "K05",
28+
"section": "Inadequate Logging and Monitoring",
29+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/2022/en/src/K05-inadequate-logging-and-monitoring",
30+
"cre_ids": ["058-083", "148-420", "402-706", "843-841"]
31+
},
32+
{
33+
"section_id": "K06",
34+
"section": "Broken Authentication Mechanisms",
35+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/2022/en/src/K06-broken-authentication-mechanisms",
36+
"cre_ids": ["177-260", "586-842", "633-428"]
37+
},
38+
{
39+
"section_id": "K07",
40+
"section": "Missing Network Segmentation Controls",
41+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/2022/en/src/K07-missing-network-segmentation-controls",
42+
"cre_ids": ["132-146", "467-784", "515-021"]
43+
},
44+
{
45+
"section_id": "K08",
46+
"section": "Secrets Management Failures",
47+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/2022/en/src/K08-secrets-management-failures",
48+
"cre_ids": ["340-375", "774-888", "813-610"]
49+
},
50+
{
51+
"section_id": "K09",
52+
"section": "Misconfigured Cluster Components",
53+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/2022/en/src/K09-misconfigured-cluster-components",
54+
"cre_ids": ["233-748", "486-813"]
55+
},
56+
{
57+
"section_id": "K10",
58+
"section": "Outdated and Vulnerable Kubernetes Components",
59+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/2022/en/src/K10-outdated-and-vulnerable-kubernetes-components",
60+
"cre_ids": ["053-751", "715-334", "863-521"]
61+
}
62+
]
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
[
2+
{
3+
"section_id": "K01",
4+
"section": "Insecure Workload Configurations",
5+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/",
6+
"cre_ids": ["233-748", "486-813"],
7+
"fallback_section_ids": ["K01"]
8+
},
9+
{
10+
"section_id": "K02",
11+
"section": "Overly Permissive Authorization Configurations",
12+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/",
13+
"cre_ids": ["128-128", "724-770"],
14+
"fallback_section_ids": ["K03"]
15+
},
16+
{
17+
"section_id": "K03",
18+
"section": "Secrets Management Failures",
19+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/",
20+
"cre_ids": ["340-375", "774-888", "813-610"],
21+
"fallback_section_ids": ["K08"]
22+
},
23+
{
24+
"section_id": "K04",
25+
"section": "Lack Of Cluster Level Policy Enforcement",
26+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/",
27+
"cre_ids": ["117-371"],
28+
"fallback_section_ids": ["K04"]
29+
},
30+
{
31+
"section_id": "K05",
32+
"section": "Missing Network Segmentation Controls",
33+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/",
34+
"cre_ids": ["132-146", "467-784", "515-021"],
35+
"fallback_section_ids": ["K07"]
36+
},
37+
{
38+
"section_id": "K06",
39+
"section": "Overly Exposed Kubernetes Components",
40+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/",
41+
"cre_ids": ["152-725", "640-364"],
42+
"fallback_section_ids": ["K09"]
43+
},
44+
{
45+
"section_id": "K07",
46+
"section": "Misconfigured And Vulnerable Cluster Components",
47+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/",
48+
"cre_ids": ["053-751", "233-748", "486-813", "715-334"],
49+
"fallback_section_ids": ["K09", "K10"]
50+
},
51+
{
52+
"section_id": "K08",
53+
"section": "Cluster To Cloud Lateral Movement",
54+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/",
55+
"cre_ids": ["132-146", "640-364", "724-770"],
56+
"fallback_section_ids": ["K03", "K07"]
57+
},
58+
{
59+
"section_id": "K09",
60+
"section": "Broken Authentication Mechanisms",
61+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/",
62+
"cre_ids": ["177-260", "586-842", "633-428"],
63+
"fallback_section_ids": ["K06"]
64+
},
65+
{
66+
"section_id": "K10",
67+
"section": "Inadequate Logging And Monitoring",
68+
"hyperlink": "https://owasp.org/www-project-kubernetes-top-ten/",
69+
"cre_ids": ["058-083", "148-420", "402-706", "843-841"],
70+
"fallback_section_ids": ["K05"]
71+
}
72+
]
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import json
2+
from pathlib import Path
3+
4+
from application.database import db
5+
from application.defs import cre_defs as defs
6+
from application.prompt_client import prompt_client
7+
from application.utils.external_project_parsers.base_parser_defs import (
8+
ParseResult,
9+
ParserInterface,
10+
)
11+
12+
13+
class OwaspKubernetesTop10_2022(ParserInterface):
14+
name = "OWASP Kubernetes Top Ten 2022"
15+
data_file = (
16+
Path(__file__).resolve().parent.parent
17+
/ "data"
18+
/ "owasp_kubernetes_top10_2022.json"
19+
)
20+
21+
def parse(self, cache: db.Node_collection, ph: prompt_client.PromptHandler):
22+
with self.data_file.open("r", encoding="utf-8") as handle:
23+
raw_entries = json.load(handle)
24+
25+
entries = []
26+
for entry in raw_entries:
27+
standard = defs.Standard(
28+
name=self.name,
29+
sectionID=entry["section_id"],
30+
section=entry["section"],
31+
hyperlink=entry["hyperlink"],
32+
)
33+
for cre_id in entry.get("cre_ids", []):
34+
cres = cache.get_CREs(external_id=cre_id)
35+
if not cres:
36+
continue
37+
standard.add_link(
38+
defs.Link(
39+
ltype=defs.LinkTypes.LinkedTo,
40+
document=cres[0].shallow_copy(),
41+
)
42+
)
43+
entries.append(standard)
44+
45+
return ParseResult(
46+
results={self.name: entries},
47+
calculate_gap_analysis=False,
48+
calculate_embeddings=False,
49+
)

0 commit comments

Comments
 (0)