Coverage for graphqler / fuzzer / idor_fuzzer.py: 33%

27 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-18 23:20 -0400

1"""Insecure direct object reference fuzzer""" 

2 

3from graphqler.fuzzer.fuzzer import Fuzzer 

4from graphqler.graph import Node 

5from graphqler.utils.logging_utils import Logger 

6from graphqler.utils.objects_bucket import ObjectsBucket 

7from graphqler.fuzzer.engine.types.result import ResultEnum 

8 

9 

10class IDORFuzzer(Fuzzer): 

11 def __init__(self, path: str, url: str, objects_bucket: ObjectsBucket): 

12 """Iniitializes the IDOR fuzzer 

13 

14 Args: 

15 path (str): The path to save the IDOR fuzzer 

16 url (str): The URL 

17 objects_bucket (dict): The objects bucket from a previous run 

18 """ 

19 super().__init__(path, url) 

20 self.objects_bucket = objects_bucket 

21 

22 # Override the default logger 

23 self.logger = Logger().get_idor_logger() 

24 self.fengine.logger = self.logger 

25 

26 def run(self): 

27 """Runs the fuzzer 

28 

29 Returns: 

30 dict: The objects bucket 

31 """ 

32 self.logger.info("Starting IDOR Fuzzer") 

33 nodes_to_check: list[Node] = list(self.dependency_graph.nodes) 

34 possible_idor_nodes: list[Node] = [] 

35 

36 for node in nodes_to_check: 

37 result = self.check_node(node) 

38 if result: 

39 possible_idor_nodes.append(node) 

40 

41 self.logger.info(f"Possible IDOR nodes: {possible_idor_nodes}") 

42 self.objects_bucket.save() 

43 

44 def check_node(self, node: Node) -> bool: 

45 """Checks if a node has a possible IDOR vulnerability, if it does, return True, else False 

46 

47 Args: 

48 node (Node): The node to be fuzzed 

49 

50 Returns: 

51 bool: True if has suspected IDOR vulenrablity, False otherwise 

52 """ 

53 if node.graphql_type == "Query" or node.graphql_type == "Mutation": 

54 graphql_response, result = self.fengine.run_minimal_payload(node.name, self.objects_bucket, node.graphql_type, check_hard_depends_on=False) 

55 if result.result_enum == ResultEnum.HAS_DATA_SUCCESS or result.success: 

56 return True 

57 return False