Skip to content

Commit dfdbc45

Browse files
committed
Add support for OWASP Top 10 resources and update test cases for consistency
1 parent 0a17895 commit dfdbc45

9 files changed

Lines changed: 115 additions & 28 deletions

application/cmd/cre_main.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,54 @@ def run(args: argparse.Namespace) -> None: # pragma: no cover
909909
BaseParser().register_resource(
910910
secure_headers.SecureHeaders, db_connection_str=args.cache_file
911911
)
912+
if getattr(args, "owasp_top10_2025_in", False):
913+
from application.utils.external_project_parsers.parsers import owasp_top10_2025
914+
915+
BaseParser().register_resource(
916+
owasp_top10_2025.OwaspTop10_2025, db_connection_str=args.cache_file
917+
)
918+
if getattr(args, "owasp_api_top10_2023_in", False):
919+
from application.utils.external_project_parsers.parsers import (
920+
owasp_api_top10_2023,
921+
)
922+
923+
BaseParser().register_resource(
924+
owasp_api_top10_2023.OwaspApiTop10_2023,
925+
db_connection_str=args.cache_file,
926+
)
927+
if getattr(args, "owasp_kubernetes_top10_2022_in", False):
928+
from application.utils.external_project_parsers.parsers import (
929+
owasp_kubernetes_top10_2022,
930+
)
931+
932+
BaseParser().register_resource(
933+
owasp_kubernetes_top10_2022.OwaspKubernetesTop10_2022,
934+
db_connection_str=args.cache_file,
935+
)
936+
if getattr(args, "owasp_kubernetes_top10_2025_in", False):
937+
from application.utils.external_project_parsers.parsers import (
938+
owasp_kubernetes_top10_2025,
939+
)
940+
941+
BaseParser().register_resource(
942+
owasp_kubernetes_top10_2025.OwaspKubernetesTop10_2025,
943+
db_connection_str=args.cache_file,
944+
)
945+
if getattr(args, "owasp_llm_top10_2025_in", False):
946+
from application.utils.external_project_parsers.parsers import (
947+
owasp_llm_top10_2025,
948+
)
949+
950+
BaseParser().register_resource(
951+
owasp_llm_top10_2025.OwaspLlmTop10_2025,
952+
db_connection_str=args.cache_file,
953+
)
954+
if getattr(args, "owasp_aisvs_in", False):
955+
from application.utils.external_project_parsers.parsers import owasp_aisvs
956+
957+
BaseParser().register_resource(
958+
owasp_aisvs.OwaspAisvs, db_connection_str=args.cache_file
959+
)
912960
if args.pci_dss_4_in:
913961
from application.utils.external_project_parsers.parsers import pci_dss
914962

application/tests/owasp_aisvs_parser_test.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,22 @@ def test_parse(self) -> None:
4545
"Training Data Governance & Bias Management", entries[0].section
4646
)
4747
self.assertEqual(
48-
"https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C01-Training-Data-Governance.md",
48+
"https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C01-Training-Data-Integrity-and-Traceability.md",
4949
entries[0].hyperlink,
5050
)
5151
self.assertEqual(
52-
["227-045", "307-507"], [l.document.id for l in entries[0].links]
52+
["227-045", "307-507"],
53+
[link.document.id for link in entries[0].links],
5354
)
5455
self.assertEqual("AISVS14", entries[-1].sectionID)
5556
self.assertEqual(
5657
"Human Oversight, Accountability & Governance", entries[-1].section
5758
)
5859
self.assertEqual(
59-
"https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C14-Human-Oversight.md",
60+
"https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C14-Human-Oversight.md",
6061
entries[-1].hyperlink,
6162
)
62-
self.assertEqual(["162-655"], [l.document.id for l in entries[-1].links])
63+
self.assertEqual(
64+
["162-655"],
65+
[link.document.id for link in entries[-1].links],
66+
)

application/tests/owasp_api_top10_2023_parser_test.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ def test_parse(self) -> None:
3737
self.assertEqual("API1", entries[0].sectionID)
3838
self.assertEqual("Broken Object Level Authorization", entries[0].section)
3939
self.assertEqual(
40-
["304-667", "724-770"], [l.document.id for l in entries[0].links]
40+
["304-667", "724-770"],
41+
[link.document.id for link in entries[0].links],
4142
)
4243
self.assertEqual("API10", entries[-1].sectionID)
43-
self.assertEqual(["715-223"], [l.document.id for l in entries[-1].links])
44+
self.assertEqual(
45+
["715-223"],
46+
[link.document.id for link in entries[-1].links],
47+
)

application/tests/owasp_kubernetes_top10_2022_parser_test.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,18 @@ def test_parse(self) -> None:
3939
self.assertEqual("K01", entries[0].sectionID)
4040
self.assertEqual("Insecure Workload Configurations", entries[0].section)
4141
self.assertEqual(
42-
["233-748", "486-813"], [l.document.id for l in entries[0].links]
42+
["233-748", "486-813"],
43+
[link.document.id for link in entries[0].links],
44+
)
45+
# K09 intentionally shares the same configuration-focused CRE ids as K01
46+
# in this dataset; K10 separately covers outdated/vulnerable components.
47+
self.assertEqual("K09", entries[8].sectionID)
48+
self.assertEqual(
49+
["233-748", "486-813"],
50+
[link.document.id for link in entries[8].links],
4351
)
4452
self.assertEqual("K10", entries[-1].sectionID)
45-
self.assertEqual(["053-751"], [l.document.id for l in entries[-1].links])
53+
self.assertEqual(
54+
["053-751"],
55+
[link.document.id for link in entries[-1].links],
56+
)

application/tests/owasp_kubernetes_top10_2025_parser_test.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,13 @@ def test_parse(self) -> None:
4343
self.assertEqual("K01", entries[0].sectionID)
4444
self.assertEqual("Insecure Workload Configurations", entries[0].section)
4545
self.assertEqual(
46-
["233-748", "486-813"], [l.document.id for l in entries[0].links]
46+
["233-748", "486-813"],
47+
[link.document.id for link in entries[0].links],
4748
)
4849
self.assertEqual("K10", entries[-1].sectionID)
4950
self.assertEqual(
5051
["148-420", "402-706", "843-841"],
51-
[l.document.id for l in entries[-1].links],
52+
[link.document.id for link in entries[-1].links],
5253
)
5354

5455
def test_parse_falls_back_to_2022_mapping_when_2025_links_missing(self) -> None:

application/tests/owasp_llm_top10_2025_parser_test.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,12 @@ def test_parse(self) -> None:
3838
self.assertEqual("LLM01", entries[0].sectionID)
3939
self.assertEqual("Prompt Injection", entries[0].section)
4040
self.assertEqual(
41-
["161-451", "760-764"], [l.document.id for l in entries[0].links]
41+
["161-451", "760-764"],
42+
[link.document.id for link in entries[0].links],
4243
)
43-
self.assertEqual(["064-808"], [l.document.id for l in entries[4].links])
44+
self.assertEqual(["064-808"], [link.document.id for link in entries[4].links])
4445
self.assertEqual("LLM10", entries[-1].sectionID)
45-
self.assertEqual(["623-550"], [l.document.id for l in entries[-1].links])
46+
self.assertEqual(
47+
["623-550"],
48+
[link.document.id for link in entries[-1].links],
49+
)

application/utils/external_project_parsers/data/owasp_aisvs_1_0.json

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,85 +2,85 @@
22
{
33
"section_id": "AISVS1",
44
"section": "Training Data Governance & Bias Management",
5-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C01-Training-Data-Governance.md",
5+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C01-Training-Data-Integrity-and-Traceability.md",
66
"cre_ids": ["227-045", "307-507"]
77
},
88
{
99
"section_id": "AISVS2",
1010
"section": "User Input Validation",
11-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C02-User-Input-Validation.md",
11+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C02-Input-Validation.md",
1212
"cre_ids": ["031-447", "760-764"]
1313
},
1414
{
1515
"section_id": "AISVS3",
1616
"section": "Model Lifecycle Management & Change Control",
17-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C03-Model-Lifecycle-Management.md",
17+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C03-Model-Lifecycle-Management.md",
1818
"cre_ids": ["148-853", "613-285"]
1919
},
2020
{
2121
"section_id": "AISVS4",
2222
"section": "Infrastructure, Configuration & Deployment Security",
23-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C04-Infrastructure.md",
23+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C04-Infrastructure.md",
2424
"cre_ids": ["233-748", "486-813"]
2525
},
2626
{
2727
"section_id": "AISVS5",
2828
"section": "Access Control & Identity for AI Components & Users",
29-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C05-Access-Control-and-Identity.md",
29+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C05-Access-Control-and-Identity.md",
3030
"cre_ids": ["633-428", "724-770"]
3131
},
3232
{
3333
"section_id": "AISVS6",
3434
"section": "Supply Chain Security for Models, Frameworks & Data",
35-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C06-Supply-Chain.md",
35+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C06-Supply-Chain.md",
3636
"cre_ids": ["613-285", "613-287", "863-521"]
3737
},
3838
{
3939
"section_id": "AISVS7",
4040
"section": "Model Behavior, Output Control & Safety Assurance",
41-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C07-Model-Behavior.md",
41+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C07-Model-Behavior.md",
4242
"cre_ids": ["064-808", "141-555"]
4343
},
4444
{
4545
"section_id": "AISVS8",
4646
"section": "Memory, Embeddings & Vector Database Security",
47-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C08-Memory-Embeddings-and-Vector-Database.md",
47+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C08-Memory-Embeddings-and-Vector-Database.md",
4848
"cre_ids": ["126-668", "538-770"]
4949
},
5050
{
5151
"section_id": "AISVS9",
5252
"section": "Autonomous Orchestration & Agentic Action Security",
53-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C09-Orchestration-and-Agentic-Action.md",
53+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C09-Orchestration-and-Agentic-Action.md",
5454
"cre_ids": ["117-371", "650-560"]
5555
},
5656
{
5757
"section_id": "AISVS10",
5858
"section": "Model Context Protocol (MCP) Security",
59-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C10-MCP-Security.md",
59+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C10-MCP-Security.md",
6060
"cre_ids": ["307-507", "715-223"]
6161
},
6262
{
6363
"section_id": "AISVS11",
6464
"section": "Adversarial Robustness & Privacy Defense",
65-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C11-Adversarial-Robustness.md",
65+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C11-Adversarial-Robustness.md",
6666
"cre_ids": ["141-555", "623-550"]
6767
},
6868
{
6969
"section_id": "AISVS12",
7070
"section": "Privacy Protection & Personal Data Management",
71-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C12-Privacy.md",
71+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C12-Privacy.md",
7272
"cre_ids": ["126-668", "227-045", "482-866"]
7373
},
7474
{
7575
"section_id": "AISVS13",
7676
"section": "Monitoring, Logging & Anomaly Detection",
77-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C13-Monitoring-and-Logging.md",
77+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C13-Monitoring-and-Logging.md",
7878
"cre_ids": ["058-083", "148-420", "402-706", "843-841"]
7979
},
8080
{
8181
"section_id": "AISVS14",
8282
"section": "Human Oversight, Accountability & Governance",
83-
"hyperlink": "https://github.com/OWASP/AISVS/tree/main/1.0/en/0x10-C14-Human-Oversight.md",
83+
"hyperlink": "https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C14-Human-Oversight.md",
8484
"cre_ids": ["162-655", "766-162"]
8585
}
8686
]

application/utils/external_project_parsers/parsers/cheatsheets_parser.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,14 @@ def register_supplemental_cheatsheets(self, cache: db.Node_collection):
123123
ltype=defs.LinkTypes.AutomaticallyLinkedTo,
124124
)
125125
)
126-
except Exception:
126+
except Exception as exc:
127+
logger.warning(
128+
"Failed to add supplemental cheatsheet link for cre_id=%s cre=%s section=%s: %s",
129+
cre_id,
130+
getattr(cre, "id", None),
131+
entry.get("section"),
132+
exc,
133+
)
127134
continue
128135
if cs.links:
129136
standard_entries.append(cs)

scripts/update-cheatsheets.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ if ! python -c "import flask" >/dev/null 2>&1; then
1515
pip install -r "$ROOT_DIR/requirements.txt"
1616
fi
1717

18+
BACKUP_FILE="${DB_PATH}.$(date +%Y%m%d%H%M%S).bak"
19+
cp "$DB_PATH" "$BACKUP_FILE"
20+
if [[ ! -f "$BACKUP_FILE" ]]; then
21+
echo "Failed to create backup at $BACKUP_FILE" >&2
22+
exit 1
23+
fi
24+
echo "Created backup at $BACKUP_FILE"
25+
1826
CRE_NO_CALCULATE_GAP_ANALYSIS=1 \
1927
CRE_NO_GEN_EMBEDDINGS=1 \
2028
python "$ROOT_DIR/cre.py" --cheatsheets_in --cache_file "$DB_PATH"

0 commit comments

Comments
 (0)