Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions application/cmd/cre_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,56 @@ def run(args: argparse.Namespace) -> None: # pragma: no cover
BaseParser().register_resource(
secure_headers.SecureHeaders, db_connection_str=args.cache_file
)
if args.owasp_top10_2025_in:
from application.utils.external_project_parsers.parsers import owasp_top10_2025

BaseParser().register_resource(
owasp_top10_2025.OwaspTop10_2025,
db_connection_str=args.cache_file,
)
if args.owasp_api_top10_2023_in:
from application.utils.external_project_parsers.parsers import (
owasp_api_top10_2023,
)

BaseParser().register_resource(
owasp_api_top10_2023.OwaspApiTop10_2023,
db_connection_str=args.cache_file,
)
if args.owasp_kubernetes_top10_2022_in:
from application.utils.external_project_parsers.parsers import (
owasp_kubernetes_top10_2022,
)

BaseParser().register_resource(
owasp_kubernetes_top10_2022.OwaspKubernetesTop10_2022,
db_connection_str=args.cache_file,
)
if args.owasp_kubernetes_top10_2025_in:
from application.utils.external_project_parsers.parsers import (
owasp_kubernetes_top10_2025,
)

BaseParser().register_resource(
owasp_kubernetes_top10_2025.OwaspKubernetesTop10_2025,
db_connection_str=args.cache_file,
)
if args.owasp_llm_top10_2025_in:
from application.utils.external_project_parsers.parsers import (
owasp_llm_top10_2025,
)

BaseParser().register_resource(
owasp_llm_top10_2025.OwaspLlmTop10_2025,
db_connection_str=args.cache_file,
)
if args.owasp_aisvs_in:
from application.utils.external_project_parsers.parsers import owasp_aisvs

BaseParser().register_resource(
owasp_aisvs.OwaspAisvs,
db_connection_str=args.cache_file,
)
if args.pci_dss_4_in:
from application.utils.external_project_parsers.parsers import pci_dss

Expand Down
16 changes: 11 additions & 5 deletions application/tests/cheatsheets_parser_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ class Repo:
repo.working_dir = loc
cre = defs.CRE(name="blah", id="223-780")
self.collection.add_cre(cre)
with open(os.path.join(os.path.join(loc, "cheatsheets"), "cs.md"), "w") as mdf:
with open(
os.path.join(
os.path.join(loc, "cheatsheets"),
"Secrets_Management_Cheat_Sheet.md",
),
"w",
) as mdf:
mdf.write(cs)
mock_clone.return_value = repo
entries = cheatsheets_parser.Cheatsheets().parse(
Expand All @@ -45,22 +51,22 @@ class Repo:
# verify the external tagging convention, not just enum wiring.
expected = defs.Standard(
name="OWASP Cheat Sheets",
hyperlink="https://github.com/foo/bar/tree/master/cs.md",
hyperlink="https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html",
section="Secrets Management Cheat Sheet",
links=[defs.Link(document=cre, ltype=defs.LinkTypes.LinkedTo)],
links=[defs.Link(document=cre, ltype=defs.LinkTypes.AutomaticallyLinkedTo)],
tags=[
"family:guidance",
"subtype:cheatsheet",
"source:owasp_cheatsheets",
"audience:developer",
"maturity:stable",
"source:owasp_cheatsheets",
],
)
self.maxDiff = None
for name, nodes in entries.results.items():
self.assertEqual(name, parser.name)
self.assertEqual(len(nodes), 1)
self.assertCountEqual(expected.todict(), nodes[0].todict())
self.assertEqual(expected.todict(), nodes[0].todict())

cheatsheets_md = """ # Secrets Management Cheat Sheet

Expand Down
57 changes: 57 additions & 0 deletions application/tests/cre_main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import shutil
import tempfile
import unittest
from argparse import Namespace
from typing import Any, Dict, List
from unittest import mock
from unittest.mock import Mock, patch
Expand Down Expand Up @@ -35,6 +36,62 @@ def setUp(self) -> None:
sqla.create_all()
self.collection = db.Node_collection()

@patch.object(main, "BaseParser")
def test_run_registers_owasp_top10_2025_resource(self, base_parser_mock) -> None:
parser_instance = Mock()
base_parser_mock.return_value = parser_instance

args = Namespace(
export=False,
csv="",
add=False,
from_ai_exchange_csv=None,
from_spreadsheet=None,
delete_map_analysis_for="",
delete_resource="",
zap_in=False,
cheatsheets_in=False,
github_tools_in=False,
capec_in=False,
cwe_in=False,
csa_ccm_v4_in=False,
iso_27001_in=False,
owasp_secure_headers_in=False,
owasp_top10_2025_in=True,
owasp_api_top10_2023_in=False,
owasp_kubernetes_top10_2022_in=False,
owasp_kubernetes_top10_2025_in=False,
owasp_llm_top10_2025_in=False,
owasp_aisvs_in=False,
pci_dss_4_in=False,
juiceshop_in=False,
dsomm_in=False,
cloud_native_security_controls_in=False,
import_external_projects=False,
regenerate_embeddings=False,
generate_embeddings=False,
populate_neo4j_db=False,
start_worker=False,
preload_map_analysis_target_url="",
ga_backfill_missing=False,
ga_backfill_batch_size=200,
ga_backfill_poll_seconds=5,
ga_backfill_max_pairs=0,
ga_backfill_no_queue=False,
upstream_sync=False,
cache_file="standards_cache.sqlite",
)

main.run(args)

parser_instance.register_resource.assert_called_once()
resource_class = parser_instance.register_resource.call_args[0][0]
self.assertEqual(resource_class.__name__, "OwaspTop10_2025")
self.assertEqual(
parser_instance.register_resource.call_args.kwargs["db_connection_str"],
"standards_cache.sqlite",
)

@patch.object(main, "populate_neo4j_db")
@patch.object(main.gap_analysis, "perform")
@patch.object(redis, "connect")
Expand Down
66 changes: 66 additions & 0 deletions application/tests/owasp_aisvs_parser_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import unittest

from application import create_app, sqla # type: ignore
from application.database import db
from application.defs import cre_defs as defs
from application.prompt_client import prompt_client
from application.utils.external_project_parsers.parsers import owasp_aisvs


class TestOwaspAisvsParser(unittest.TestCase):
def tearDown(self) -> None:
sqla.session.remove()
sqla.drop_all()
self.app_context.pop()

def setUp(self) -> None:
self.app = create_app(mode="test")
self.app_context = self.app.app_context()
self.app_context.push()
sqla.create_all()
self.collection = db.Node_collection()

def test_parse(self) -> None:
for cre_id, name in [
("227-045", "Identify sensitive data and subject it to a policy"),
(
"307-507",
"Allow only trusted sources both build time and runtime; therefore perform integrity checks on all resources and code",
),
(
"162-655",
"Documentation of all components' business or security function",
),
]:
self.collection.add_cre(defs.CRE(id=cre_id, name=name, description=""))

result = owasp_aisvs.OwaspAisvs().parse(
self.collection, prompt_client.PromptHandler(database=self.collection)
)

entries = result.results["OWASP AI Security Verification Standard (AISVS)"]
self.assertEqual(14, len(entries))
self.assertEqual("AISVS1", entries[0].sectionID)
self.assertEqual(
"Training Data Governance & Bias Management", entries[0].section
)
self.assertEqual(
"https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C01-Training-Data-Governance.md",
entries[0].hyperlink,
)
self.assertEqual(
["227-045", "307-507"],
[link.document.id for link in entries[0].links],
)
self.assertEqual("AISVS14", entries[-1].sectionID)
self.assertEqual(
"Human Oversight, Accountability & Governance", entries[-1].section
)
self.assertEqual(
"https://github.com/OWASP/AISVS/blob/main/1.0/en/0x10-C14-Human-Oversight.md",
entries[-1].hyperlink,
)
self.assertEqual(
["162-655"],
[link.document.id for link in entries[-1].links],
)
43 changes: 43 additions & 0 deletions application/tests/owasp_api_top10_2023_parser_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import unittest

from application import create_app, sqla # type: ignore
from application.database import db
from application.defs import cre_defs as defs
from application.prompt_client import prompt_client
from application.utils.external_project_parsers.parsers import owasp_api_top10_2023


class TestOwaspApiTop10_2023Parser(unittest.TestCase):
def tearDown(self) -> None:
sqla.session.remove()
sqla.drop_all()
self.app_context.pop()

def setUp(self) -> None:
self.app = create_app(mode="test")
self.app_context = self.app.app_context()
self.app_context.push()
sqla.create_all()
self.collection = db.Node_collection()

def test_parse(self) -> None:
for cre_id, name in [
("304-667", "Protect API against unauthorized access/modification (IDOR)"),
("724-770", "Technical application access control"),
("715-223", "Ensure trusted origin of third party resources"),
]:
self.collection.add_cre(defs.CRE(id=cre_id, name=name, description=""))

result = owasp_api_top10_2023.OwaspApiTop10_2023().parse(
self.collection, prompt_client.PromptHandler(database=self.collection)
)

entries = result.results["OWASP API Security Top 10 2023"]
self.assertEqual(10, len(entries))
self.assertEqual("API1", entries[0].sectionID)
self.assertEqual("Broken Object Level Authorization", entries[0].section)
self.assertEqual(
["304-667", "724-770"], [link.document.id for link in entries[0].links]
)
self.assertEqual("API10", entries[-1].sectionID)
self.assertEqual(["715-223"], [link.document.id for link in entries[-1].links])
45 changes: 45 additions & 0 deletions application/tests/owasp_kubernetes_top10_2022_parser_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import unittest

from application import create_app, sqla # type: ignore
from application.database import db
from application.defs import cre_defs as defs
from application.prompt_client import prompt_client
from application.utils.external_project_parsers.parsers import (
owasp_kubernetes_top10_2022,
)


class TestOwaspKubernetesTop10_2022Parser(unittest.TestCase):
def tearDown(self) -> None:
sqla.session.remove()
sqla.drop_all()
self.app_context.pop()

def setUp(self) -> None:
self.app = create_app(mode="test")
self.app_context = self.app.app_context()
self.app_context.push()
sqla.create_all()
self.collection = db.Node_collection()

def test_parse(self) -> None:
for cre_id, name in [
("233-748", "Configuration hardening"),
("486-813", "Configuration"),
("053-751", "Force build pipeline to check outdated/insecure components"),
]:
self.collection.add_cre(defs.CRE(id=cre_id, name=name, description=""))

result = owasp_kubernetes_top10_2022.OwaspKubernetesTop10_2022().parse(
self.collection, prompt_client.PromptHandler(database=self.collection)
)

entries = result.results["OWASP Kubernetes Top Ten 2022"]
self.assertEqual(10, len(entries))
self.assertEqual("K01", entries[0].sectionID)
self.assertEqual("Insecure Workload Configurations", entries[0].section)
self.assertEqual(
["233-748", "486-813"], [link.document.id for link in entries[0].links]
)
self.assertEqual("K10", entries[-1].sectionID)
self.assertEqual(["053-751"], [link.document.id for link in entries[-1].links])
Loading
Loading