diff --git a/boostsec/registry_validator/schema.py b/boostsec/registry_validator/schema.py index 587681d..d93875a 100644 --- a/boostsec/registry_validator/schema.py +++ b/boostsec/registry_validator/schema.py @@ -58,6 +58,8 @@ class RuleSchema(BaseModel): categories: list[str] ref: AnyHttpUrl + recommended: bool = False + class Config: """Config.""" diff --git a/boostsec/registry_validator/upload_rules_db.py b/boostsec/registry_validator/upload_rules_db.py index 253b22b..704d35b 100644 --- a/boostsec/registry_validator/upload_rules_db.py +++ b/boostsec/registry_validator/upload_rules_db.py @@ -105,6 +105,7 @@ def load_scanners(scanners_path: Path, updated_ns: set[str]) -> list[ScannerName rules_db_yaml = yaml.safe_load(rules_path.read_text()) rules = RulesDbSchema.parse_obj(rules_db_yaml) + scanners.append( ScannerNamespace( namespace=namespace, @@ -260,6 +261,7 @@ def upload_rules_db( "name": rule.name, "prettyName": rule.pretty_name, "ref": rule.ref, + "recommended": rule.recommended, } for rule in rules.values() ], @@ -294,10 +296,12 @@ def main( scanners = load_scanners(config.scanners_path, updated_ns) server_scanners = load_scanners(config.server_side_scanners_path, updated_ns) scanners = scanners + server_scanners + rules_realm = load_rules_realm(config.rules_realm_path, updated_ns) namespace_cache = make_namespace_cache(scanners, rules_realm, server_scanners) scanners_to_update = get_updated_scanners(scanners, namespace_cache) + if len(scanners_to_update) == 0: print("No module rules to update.") return None diff --git a/tests/integration/samples/scanners/boostsecurityio/simple-scanner/rules.yaml b/tests/integration/samples/scanners/boostsecurityio/simple-scanner/rules.yaml index aaf86e7..ebbc46d 100644 --- a/tests/integration/samples/scanners/boostsecurityio/simple-scanner/rules.yaml +++ b/tests/integration/samples/scanners/boostsecurityio/simple-scanner/rules.yaml @@ -8,6 +8,7 @@ rules: name: my-rule-1 pretty_name: My rule 1 ref: "http://my.link.com" + recommended: true my-rule-2: categories: - ALL @@ -17,3 +18,4 @@ rules: name: my-rule-2 pretty_name: My rule 2 ref: "http://my.link.com" + \ No newline at end of file diff --git a/tests/integration/samples/server-side-scanners/boostsecurityio/simple-scanner/rules.yaml b/tests/integration/samples/server-side-scanners/boostsecurityio/simple-scanner/rules.yaml index aaf86e7..cde55ee 100644 --- a/tests/integration/samples/server-side-scanners/boostsecurityio/simple-scanner/rules.yaml +++ b/tests/integration/samples/server-side-scanners/boostsecurityio/simple-scanner/rules.yaml @@ -8,6 +8,7 @@ rules: name: my-rule-1 pretty_name: My rule 1 ref: "http://my.link.com" + recommended: True my-rule-2: categories: - ALL @@ -17,3 +18,4 @@ rules: name: my-rule-2 pretty_name: My rule 2 ref: "http://my.link.com" + recommended: False diff --git a/tests/integration/samples/server-side-scanners/boostsecurityio/simple-server-scanner/rules.yaml b/tests/integration/samples/server-side-scanners/boostsecurityio/simple-server-scanner/rules.yaml index aaf86e7..cc9b5e9 100644 --- a/tests/integration/samples/server-side-scanners/boostsecurityio/simple-server-scanner/rules.yaml +++ b/tests/integration/samples/server-side-scanners/boostsecurityio/simple-server-scanner/rules.yaml @@ -8,6 +8,7 @@ rules: name: my-rule-1 pretty_name: My rule 1 ref: "http://my.link.com" + recommended: True my-rule-2: categories: - ALL diff --git a/tests/integration/test_upload_rules_db.py b/tests/integration/test_upload_rules_db.py index 8be7987..94f78f9 100644 --- a/tests/integration/test_upload_rules_db.py +++ b/tests/integration/test_upload_rules_db.py @@ -108,6 +108,7 @@ def test_main_simple_scanner( "name": "my-rule-1", "prettyName": "My rule 1", "ref": "http://my.link.com", + "recommended": True, }, { "categories": ["ALL", "category-2"], @@ -117,7 +118,9 @@ def test_main_simple_scanner( "name": "my-rule-2", "prettyName": "My rule 2", "ref": "http://my.link.com", + "recommended": False, }, + ], } } @@ -188,6 +191,7 @@ def test_main_only_import( "name": "CWE-1004", "prettyName": "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag", "ref": "https://cwe.mitre.org/data/definitions/1004.html", + "recommended": False, }, { "categories": ["ALL", "boost-hardened"], @@ -200,6 +204,7 @@ def test_main_only_import( "Homoglyphs Presented to User" ), "ref": "https://cwe.mitre.org/data/definitions/1007.html", + "recommended": False, }, { "categories": ["ALL", "category-1"], @@ -209,6 +214,7 @@ def test_main_only_import( "name": "my-rule-1", "prettyName": "My rule 1", "ref": "http://my.link.com", + "recommended": True, }, { "categories": ["ALL", "category-2"], @@ -218,6 +224,7 @@ def test_main_only_import( "name": "my-rule-2", "prettyName": "My rule 2", "ref": "http://my.link.com", + "recommended": False, }, { "categories": ["ALL", "boost-hardened"], @@ -229,6 +236,7 @@ def test_main_only_import( "CWE-UNKNOWN - Original rule did not map to a known CWE rule" ), "ref": "https://cwe.mitre.org/", + "recommended": False, }, ], } @@ -291,6 +299,7 @@ def test_main_rule_update_trigger_upload( "name": "CWE-1004", "prettyName": "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag", "ref": "https://cwe.mitre.org/data/definitions/1004.html", + "recommended": False, }, { "categories": ["ALL", "boost-hardened"], @@ -303,6 +312,7 @@ def test_main_rule_update_trigger_upload( "Homoglyphs Presented to User" ), "ref": "https://cwe.mitre.org/data/definitions/1007.html", + "recommended": False, }, { "categories": ["ALL", "category-1"], @@ -312,6 +322,7 @@ def test_main_rule_update_trigger_upload( "name": "my-rule-1", "prettyName": "My rule 1", "ref": "http://my.link.com", + "recommended": True, }, { "categories": ["ALL", "category-2"], @@ -321,6 +332,7 @@ def test_main_rule_update_trigger_upload( "name": "my-rule-2", "prettyName": "My rule 2", "ref": "http://my.link.com", + "recommended": False, }, { "categories": ["ALL", "boost-hardened"], @@ -332,6 +344,7 @@ def test_main_rule_update_trigger_upload( "CWE-UNKNOWN - Original rule did not map to a known CWE rule" ), "ref": "https://cwe.mitre.org/", + "recommended": False, }, ], } @@ -386,6 +399,7 @@ def test_main_rule_import_overload( "name": "CWE-1004", "prettyName": "CWE-1004: Overload", "ref": "https://cwe.mitre.org/data/definitions/1004.html", + "recommended": False, }, { "categories": ["ALL", "boost-hardened"], @@ -398,6 +412,7 @@ def test_main_rule_import_overload( "of Homoglyphs Presented to User" ), "ref": "https://cwe.mitre.org/data/definitions/1007.html", + "recommended": False, }, { "categories": ["ALL"], @@ -407,6 +422,7 @@ def test_main_rule_import_overload( "name": "CWE-OVERLOAD", "prettyName": "CWE-OVERLOAD - Overload", "ref": "https://cwe.mitre.org/", + "recommended": False, }, ], } @@ -465,6 +481,7 @@ def test_main_with_placeholder( "name": "my-rule-1", "prettyName": "My rule 1", "ref": f"{doc_url}/a/b/c", + "recommended": False, }, { "categories": ["ALL", "category-2"], @@ -474,6 +491,7 @@ def test_main_with_placeholder( "name": "my-rule-2", "prettyName": "My rule 2", "ref": f"{doc_url}/d/e/f", + "recommended": False, }, ], }, diff --git a/tests/unit/scanner/test_upload_rules_db.py b/tests/unit/scanner/test_upload_rules_db.py index 8d4e82a..b393363 100644 --- a/tests/unit/scanner/test_upload_rules_db.py +++ b/tests/unit/scanner/test_upload_rules_db.py @@ -320,6 +320,7 @@ def has_auth_token(request: Any) -> bool: "name": rule.name, "prettyName": rule.pretty_name, "ref": rule.ref, + "recommended": rule.recommended } for rule in rules ],