@@ -34,28 +34,37 @@ def _extract_onion_host(self, value: str) -> str:
3434 if not host .endswith (".onion" ):
3535 raise ValueError ("Not a .onion host" )
3636 if not ONION_RE .match (host ):
37- pass
37+ raise ValueError ( f"Invalid .onion domain format: { host } " )
3838 return host
3939
4040 def _load_tag_descriptions (self ):
4141 """Load tag descriptions from machinetag.json"""
4242 machinetag_path = os .path .join (os .path .dirname (__file__ ), 'machinetag.json' )
4343 if not os .path .exists (machinetag_path ):
44+ # Log warning but continue without tag descriptions
4445 return {}
4546
46- with open (machinetag_path , 'r' , encoding = 'utf-8' ) as f :
47- self .machinetag_data = json .load (f )
47+ try :
48+ with open (machinetag_path , 'r' , encoding = 'utf-8' ) as f :
49+ self .machinetag_data = json .load (f )
50+ except (IOError , json .JSONDecodeError ) as e :
51+ # Log warning and continue without tag descriptions
52+ return {}
4853
4954 descriptions = {}
50- for value_info in self .machinetag_data ['values' ]:
51- predicate = value_info ['predicate' ]
52- for entry in value_info ['entry' ]:
53- key = f"dark-web:{ predicate } ={ entry ['value' ]} "
54- descriptions [key ] = {
55- 'description' : entry ['description' ],
56- 'expanded' : entry ['expanded' ],
57- 'value' : entry ['value' ]
58- }
55+ try :
56+ for value_info in self .machinetag_data ['values' ]:
57+ predicate = value_info ['predicate' ]
58+ for entry in value_info ['entry' ]:
59+ key = f"dark-web:{ predicate } ={ entry ['value' ]} "
60+ descriptions [key ] = {
61+ 'description' : entry ['description' ],
62+ 'expanded' : entry ['expanded' ],
63+ 'value' : entry ['value' ]
64+ }
65+ except (KeyError , TypeError ) as e :
66+ # Return empty dict if machinetag structure is unexpected
67+ return {}
5968
6069 return descriptions
6170
@@ -102,12 +111,39 @@ def _enrich_tags(self, tags):
102111
103112 def run (self ):
104113 try :
105- onion = self ._extract_onion_host (self .get_data ())
114+ # Extract and validate onion host
115+ try :
116+ onion = self ._extract_onion_host (self .get_data ())
117+ except ValueError as e :
118+ self .error (f"Invalid onion domain: { str (e )} " )
119+ return
120+ except Exception as e :
121+ self .error (f"Error processing input data: { str (e )} " )
122+ return
123+
124+ # Build API URL
106125 url = f"{ self .base_url .rstrip ('/' )} /api/lookup/{ onion } "
107- r = requests .get (url , timeout = 3 , verify = self .verify_tls )
126+
127+ # Make API request
128+ try :
129+ r = requests .get (url , timeout = self .timeout , verify = self .verify_tls )
130+ except requests .exceptions .ConnectTimeout :
131+ self .error (f"Connection timeout to { self .base_url } " )
132+ return
133+ except requests .exceptions .ConnectionError :
134+ self .error (f"Connection failed to { self .base_url } " )
135+ return
136+ except requests .exceptions .RequestException as e :
137+ self .error (f"Request failed: { str (e )} " )
138+ return
108139
109140 if r .status_code == 200 :
110- resp = r .json ()
141+ try :
142+ resp = r .json ()
143+ except ValueError as e :
144+ self .error (f"Invalid JSON response: { str (e )} " )
145+ return
146+
111147 # API returns [{"error": "Invalid Domain"}, 404] for non-existent onions
112148 if isinstance (resp , list ) and len (resp ) == 2 and isinstance (resp [0 ], dict ) and "error" in resp [0 ]:
113149 self .error ("Onion service not found" )
@@ -117,14 +153,18 @@ def run(self):
117153 # resp["tags"].append(self.csam_tag)
118154 # Add enriched tags with analyst-friendly descriptions
119155 if isinstance (resp , dict ) and "tags" in resp and isinstance (resp ["tags" ], list ):
120- resp ["tags_enriched" ] = self ._enrich_tags (resp ["tags" ])
121- resp ["tags_sanitized" ] = self ._create_sanitized_tags (resp ["tags" ])
156+ try :
157+ resp ["tags_enriched" ] = self ._enrich_tags (resp ["tags" ])
158+ resp ["tags_sanitized" ] = self ._create_sanitized_tags (resp ["tags" ])
159+ except Exception as e :
160+ # Continue even if tag enrichment fails
161+ pass
122162 self .report (resp )
123163 else :
124- self .error ("API request failed" )
164+ self .error (f "API request failed with status code { r . status_code } : { r . text } " )
125165
126- except Exception :
127- self .error ("Failed to process onion lookup" )
166+ except Exception as e :
167+ self .error (f"Unexpected error in onion lookup: { str ( e ) } " )
128168
129169 def operations (self , raw ):
130170 ops = []
0 commit comments