From cae0b716950590ffb47b9169ed5758e487ab2936 Mon Sep 17 00:00:00 2001 From: Gude5 Date: Tue, 16 Sep 2025 09:23:04 +0200 Subject: [PATCH 1/4] chore: modified function to prevent it from key errors --- valhallaAPI/valhalla.py | 43 +++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/valhallaAPI/valhalla.py b/valhallaAPI/valhalla.py index 5e6b334..6f43b85 100644 --- a/valhallaAPI/valhalla.py +++ b/valhallaAPI/valhalla.py @@ -227,27 +227,28 @@ def get_rules_json(self, product="", max_version="", modules=[], with_crypto=Tru rules_response = json.loads(r.text) # Filter ------------------------------------------------------ - # Product filtering - if product: - (max_version, modules, with_crypto) = get_product_requirements(product=product) - # Tag filtering - if len(tags) > 0: - rules_response['rules'] = filter_tags(rules_response['rules'], tags=tags) - # Score - if score > 0: - rules_response['rules'] = filter_score(rules_response['rules'], minimum_score=score) - # Search string - if search: - rules_response['rules'] = filter_search(rules_response['rules'], query=search) - # Custom filtering - if max_version or len(modules) > 0 or with_crypto is not True: - rules_response['rules'] = filter_requirements(rules_response['rules'], - sup_ver_string=max_version, - sup_modules=modules, - with_crypto=with_crypto) - # Public rules filter - if private_only: - rules_response['rules'] = filter_privateonly(rules_response['rules']) + if 'rules' in rules_response: + # Product filtering + if product: + (max_version, modules, with_crypto) = get_product_requirements(product=product) + # Tag filtering + if len(tags) > 0: + rules_response['rules'] = filter_tags(rules_response['rules'], tags=tags) + # Score + if score > 0: + rules_response['rules'] = filter_score(rules_response['rules'], minimum_score=score) + # Search string + if search: + rules_response['rules'] = filter_search(rules_response['rules'], query=search) + # Custom filtering + if max_version or len(modules) > 0 or with_crypto is not True: + rules_response['rules'] = filter_requirements(rules_response['rules'], + sup_ver_string=max_version, + sup_modules=modules, + with_crypto=with_crypto) + # Public rules filter + if private_only: + rules_response['rules'] = filter_privateonly(rules_response['rules']) # Return filtered set return rules_response From 9d5935a5cd2d10cb96d6398a853059b7c6648caf Mon Sep 17 00:00:00 2001 From: Gude5 Date: Tue, 16 Sep 2025 09:33:39 +0200 Subject: [PATCH 2/4] chore: added test --- tests/test_basic.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_basic.py b/tests/test_basic.py index 674e44e..8a9330a 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -202,3 +202,14 @@ def test_demo_sigma_rules_json(): v = ValhallaAPI(api_key=DEMO_KEY) response = v.get_sigma_rules_json() assert len(response['rules']) > 0 + +def test_get_rule_info_invalid(): + """ + Retrieves no rules since key is invalid + :return: + """ + v = ValhallaAPI(api_key=INVALID_KEY) + response = v.get_rules_json() + assert response['status'] == 'error' + response2 = v.get_rules_json(score=75) + assert response2['status'] == 'error' \ No newline at end of file From 7d4f4a56db55aa8bbad331a108d7c9c8aeb0b14d Mon Sep 17 00:00:00 2001 From: Gude5 Date: Wed, 17 Sep 2025 12:31:58 +0200 Subject: [PATCH 3/4] update: updated readme, script and test due to deprecated demo key --- README.md | 2 ++ tests/test_basic.py | 72 ++++++++++++++++++++--------------------- valhallaAPI/valhalla.py | 8 ++--- 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 611222e..43d29a2 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ There are 2 extra functions for special lookups in the Valhalla database (for cu ## Demo Access +> Important: Teh dem API key is not available and demo access is not possible anymore. Hence, the following section and everything regarding the given demo API key is outdated. + There is a demo API key that can be used for testing purposes. ``` diff --git a/tests/test_basic.py b/tests/test_basic.py index 8a9330a..31bab91 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -4,7 +4,8 @@ from valhallaAPI.valhalla import ValhallaAPI -DEMO_KEY = "1111111111111111111111111111111111111111111111111111111111111111" +# Demo key is deprecated, but still works for testing purposes +DEPRECATED_DEMO_KEY = "1111111111111111111111111111111111111111111111111111111111111111" INVALID_KEY = "invalid" RULES_TEXT = "VALHALLA YARA RULE SET" RULE_INFO_TEST = "Casing_Anomaly_ByPass" # Only rule info allowed for DEMO user @@ -26,7 +27,7 @@ def test_status(): Retrieves the API status :return: """ - v = ValhallaAPI(api_key=DEMO_KEY) + v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) status = v.get_status() assert status["status"] == "green" @@ -36,9 +37,8 @@ def test_subscription(): Retrieves the subscription status of the current user :return: """ - v = ValhallaAPI() + v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) response = v.get_subscription() - print(response) assert len(response) == 5 assert response["subscription"] == "limited" assert response["tags"] == ['DEMO'] @@ -49,7 +49,7 @@ def test_demo_rules_json(): Retrieves the demo rules from the rule feed :return: """ - v = ValhallaAPI(api_key=DEMO_KEY) + v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) rules_response = v.get_rules_json() assert len(rules_response['rules']) > 0 @@ -59,12 +59,11 @@ def test_demo_rule_info(): Retrieves the demo rule info :return: """ - v = ValhallaAPI(api_key=DEMO_KEY) + v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) rules_response1 = v.get_rule_info(RULE_INFO_DISALLOWED) assert 'rule_matches' not in rules_response1 rules_response2 = v.get_rule_info(RULE_INFO_TEST) - assert 'rule_matches' in rules_response2 - assert len(rules_response2['rule_matches']) > 0 + assert 'rule_matches' not in rules_response2 def test_demo_rules_product_limited(): @@ -72,7 +71,7 @@ def test_demo_rules_product_limited(): Retrieves the demo rules from the rule feed with a product set :return: """ - v = ValhallaAPI(api_key=DEMO_KEY) + v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) rules_response = v.get_rules_json() rules_response_limited = v.get_rules_json(product="DummyTest") assert len(rules_response['rules']) > 0 @@ -86,7 +85,7 @@ def test_demo_rules_custom_limited(): Retrieves the demo rules from the rule feed with custom expressions :return: """ - v = ValhallaAPI(api_key=DEMO_KEY) + v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) rules_response1 = v.get_rules_json(product="DummyTest") rules_response2 = v.get_rules_json(max_version="3.2.0", modules=['pe']) rules_response3 = v.get_rules_json(max_version="3.2.0", modules=['pe'], with_crypto=False) @@ -101,7 +100,7 @@ def test_demo_rules_tag_limited(): Retrieves the demo rules from the rule feed with custom expressions :return: """ - v = ValhallaAPI(api_key=DEMO_KEY) + v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) rules_response1 = v.get_rules_json() rules_response2 = v.get_rules_json(tags=['APT']) assert len(rules_response1['rules']) > 0 @@ -114,7 +113,7 @@ def test_demo_rules_score_limited(): Retrieves the demo rules from the rule feed with custom expressions :return: """ - v = ValhallaAPI(api_key=DEMO_KEY) + v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) rules_response1 = v.get_rules_json() rules_response2 = v.get_rules_json(score=80) assert len(rules_response1['rules']) > 0 @@ -127,7 +126,7 @@ def test_demo_rules_search_limited(): Retrieves the demo rules from the rule feed with custom expressions :return: """ - v = ValhallaAPI(api_key=DEMO_KEY) + v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) rules_response1 = v.get_rules_json() rules_response2 = v.get_rules_json(search="Mimikatz") assert len(rules_response1['rules']) > 1 @@ -140,7 +139,7 @@ def test_demo_rules_combo_limited(): Retrieves the demo rules from the rule feed with custom expressions :return: """ - v = ValhallaAPI(api_key=DEMO_KEY) + v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) rules_response1 = v.get_rules_json() rules_response2 = v.get_rules_json(score=60) rules_response3 = v.get_rules_json(tags=['SUSP'], score=60) @@ -156,7 +155,7 @@ def test_demo_rules_text(): Retrieves the demo rules from the rule feed :return: """ - v = ValhallaAPI(api_key=DEMO_KEY) + v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) response = v.get_rules_text() assert RULES_TEXT in response assert len(response) > 500 @@ -172,26 +171,27 @@ def test_invalid_key(): v.get_rules_text() -def test_get_rule_info(): - """ - Trying to retrieve info for a certain rule (the only one accessible with DEMO key) - :return: - """ - v = ValhallaAPI(api_key=DEMO_KEY) - response = v.get_rule_info('Casing_Anomaly_ByPass') - assert len(response) > 1 - assert len(response['rule_matches']) > 0 - - -def test_get_hash_info(): - """ - Trying to retrieve info for a certain hash (the only one accessible with DEMO key) - :return: - """ - v = ValhallaAPI(api_key=DEMO_KEY) - response = v.get_hash_info('8a883a74702f83a273e6c292c672f1144fd1cce8ee126cd90c95131e870744af') - assert len(response) > 1 - assert len(response['results']) > 0 +# Remove test since demo key is deprecated +#def test_get_rule_info(): +# """ +# Trying to retrieve info for a certain rule (the only one accessible with DEMO key) +# :return: +# """ +# v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) +# response = v.get_rule_info('Casing_Anomaly_ByPass') +# assert len(response) > 1 +# assert len(response['rule_matches']) > 0 +# +# +#def test_get_hash_info(): +# """ +# Trying to retrieve info for a certain hash (the only one accessible with DEMO key) +# :return: +# """ +# v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) +# response = v.get_hash_info('8a883a74702f83a273e6c292c672f1144fd1cce8ee126cd90c95131e870744af') +# assert len(response) > 1 +# assert len(response['results']) > 0 def test_demo_sigma_rules_json(): @@ -199,7 +199,7 @@ def test_demo_sigma_rules_json(): Retrieves the demo rules from the sigma rule feed :return: """ - v = ValhallaAPI(api_key=DEMO_KEY) + v = ValhallaAPI(api_key=DEPRECATED_DEMO_KEY) response = v.get_sigma_rules_json() assert len(response['rules']) > 0 diff --git a/valhallaAPI/valhalla.py b/valhallaAPI/valhalla.py index 6f43b85..acc0322 100644 --- a/valhallaAPI/valhalla.py +++ b/valhallaAPI/valhalla.py @@ -46,7 +46,7 @@ class ValhallaAPI(object): PRODUCT_IDENTIFIER = ['FireEyeAX', 'FireEyeNX', 'FireEyeEX', 'CarbonBlack', 'Tanium', 'Tenable', 'SymantecMAA', 'osquery', 'GRR', 'McAfeeATD3', 'McAfeeATD4'] - DEMO_KEY = "1111111111111111111111111111111111111111111111111111111111111111" + # DEMO_KEY = "1111111111111111111111111111111111111111111111111111111111111111" DEFAULT_OUTPUT_FILE = 'valhalla-rules.yar' # Cached info @@ -57,9 +57,9 @@ def __init__(self, api_key=""): Initializes the API client object :param api_key: """ - # Demo API key if no API key was given - if api_key == "": - api_key = self.DEMO_KEY + # Demo API key if no API key was given -> empty API key if no API key was given + # if api_key == "": + # api_key = self.DEMO_KEY # API Key self.api_key = api_key From 30b0b6bdbaf5ecd2b3ea738cbfb98e7cc24558cd Mon Sep 17 00:00:00 2001 From: Gude5 <76428540+Gude5@users.noreply.github.com> Date: Fri, 26 Sep 2025 07:29:41 +0200 Subject: [PATCH 4/4] Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 43d29a2..7be4b93 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ There are 2 extra functions for special lookups in the Valhalla database (for cu ## Demo Access -> Important: Teh dem API key is not available and demo access is not possible anymore. Hence, the following section and everything regarding the given demo API key is outdated. +> Important: The demo API key is not available and demo access is not possible anymore. Hence, the following section and everything regarding the given demo API key is outdated. There is a demo API key that can be used for testing purposes.