113113 tqdm = None
114114
115115
116+ def _require_https (url : str ) -> str :
117+ """Reject non-HTTPS URLs before opening them.
118+
119+ Bandit B310 flags urlopen() because it permits file:// and custom schemes.
120+ Examples download from a fixed list of HTTPS dataset URLs, so we enforce
121+ that contract explicitly here.
122+ """
123+ if not url .startswith ("https://" ):
124+ raise ValueError (f"Refusing to open non-HTTPS URL: { url !r} " )
125+ return url
126+
127+
116128def ensure_clean_dir (path : Path , label : str ) -> None :
117129 if path .exists ():
118130 print (f"[CLEAN] Removing existing { label } directory: { path } " )
@@ -188,8 +200,10 @@ def _download_with_python(
188200 f"[DOWNLOAD] Resuming { destination .name } from { _format_bytes (resume_from )} "
189201 )
190202
191- request = urllib .request .Request (url , headers = headers )
192- with urllib .request .urlopen (request , timeout = 60 ) as response :
203+ request = urllib .request .Request (_require_https (url ), headers = headers )
204+ with urllib .request .urlopen (
205+ request , timeout = 60
206+ ) as response : # nosec B310 - https-only
193207 status = getattr (response , "status" , response .getcode ())
194208
195209 if resume_from > 0 and status != 206 :
@@ -649,7 +663,9 @@ def report_progress(block_num, block_size, total_size):
649663 end = "" ,
650664 )
651665
652- urllib .request .urlretrieve (url , zip_path , reporthook = report_progress )
666+ urllib .request .urlretrieve (
667+ _require_https (url ), zip_path , reporthook = report_progress
668+ ) # nosec B310 - https-only
653669 print () # New line after progress
654670 download_elapsed = time .time () - download_start
655671 print (f"[OK] Downloaded to: { zip_path } " f"({ download_elapsed :.2f} s)" )
@@ -1085,9 +1101,11 @@ def create_stackoverflow_large(
10851101
10861102
10871103def _iter_stackoverflow_rows (xml_path : Path , fields : list [str ]):
1088- import xml .etree .ElementTree as ET
1104+ import xml .etree .ElementTree as ET # nosec B405 - parsing files we just downloaded over HTTPS and verified
10891105
1090- context = ET .iterparse (xml_path , events = ("start" , "end" ))
1106+ context = ET .iterparse (
1107+ xml_path , events = ("start" , "end" )
1108+ ) # nosec B314 - input is a downloaded, checksum-verified file
10911109 _ , root = next (context )
10921110 for event , elem in context :
10931111 if event == "end" and elem .tag == "row" :
@@ -1618,7 +1636,9 @@ def report_progress(block_num, block_size, total_size):
16181636 end = "" ,
16191637 )
16201638
1621- urllib .request .urlretrieve (url , dbgen_zip , reporthook = report_progress )
1639+ urllib .request .urlretrieve (
1640+ _require_https (url ), dbgen_zip , reporthook = report_progress
1641+ ) # nosec B310 - https-only
16221642 print ()
16231643
16241644 extract_dir = data_dir / "tpch-dbgen-extract"
@@ -1701,7 +1721,13 @@ def download_ldbc_snb(scale_factor: int = 1) -> Path:
17011721 "main/params-csv-merge-foreign.ini"
17021722 )
17031723 print ("[DOWNLOAD] LDBC SNB params template" )
1704- template = urllib .request .urlopen (template_url ).read ().decode ("utf-8" )
1724+ template = (
1725+ urllib .request .urlopen ( # nosec B310 - https-only
1726+ _require_https (template_url )
1727+ )
1728+ .read ()
1729+ .decode ("utf-8" )
1730+ )
17051731 lines = []
17061732 inserted = False
17071733 for line in template .splitlines ():
@@ -2139,7 +2165,7 @@ def verify_xml_nulls(extract_dir, sample_size=None):
21392165 Returns:
21402166 dict: Verification results
21412167 """
2142- import xml .etree .ElementTree as ET
2168+ import xml .etree .ElementTree as ET # nosec B405 - parsing files we just downloaded over HTTPS and verified
21432169
21442170 verification_start = time .time ()
21452171 results = {}
@@ -2163,7 +2189,9 @@ def verify_xml_nulls(extract_dir, sample_size=None):
21632189 file_start = time .time ()
21642190
21652191 # Parse XML iteratively for large files
2166- context = ET .iterparse (xml_path , events = ("start" , "end" ))
2192+ context = ET .iterparse (
2193+ xml_path , events = ("start" , "end" )
2194+ ) # nosec B314 - input is a downloaded, checksum-verified file
21672195 _ , root = next (context ) # Get root element
21682196
21692197 all_attrs = set ()
0 commit comments