@@ -787,11 +787,8 @@ class TM:
787787 )
788788 name = varString ("" , required = True , doc = "Model name" )
789789 description = varString ("" , required = True , doc = "Model description" )
790- threatsFile = varString (
791- os .path .dirname (__file__ ) + "/threatlib/threats.json" ,
792- onSet = lambda i , v : i ._init_threats (),
793- doc = "JSON file with custom threats" ,
794- )
790+ threatsFile = varStrings ("" )
791+ threatsFileInit = False
795792 isOrdered = varBool (False , doc = "Automatically order all Dataflows" )
796793 mergeResponses = varBool (False , doc = "Merge response edges in DFDs" )
797794 ignoreUnused = varBool (False , doc = "Ignore elements not used in any Dataflow" )
@@ -838,16 +835,19 @@ def _init_threats(self):
838835 self ._add_threats ()
839836
840837 def _add_threats (self ):
841- try :
842- with open (self .threatsFile , "r" , encoding = "utf8" ) as threat_file :
843- threats_json = json .load (threat_file )
844- except (FileNotFoundError , PermissionError , IsADirectoryError ) as e :
845- raise UIError (
846- e , f"while trying to open the the threat file ({ self .threatsFile } )."
838+
839+ for threat_file_path in self .threatsFile :
840+ try :
841+ with open (self .threatsFile , "r" , encoding = "utf8" ) as threat_file :
842+ threats_json = json .load (threat_file )
843+ except (FileNotFoundError , PermissionError , IsADirectoryError ) as e :
844+ raise UIError (
845+ e , f"while trying to open the the threat file ({ self .threatsFile } )."
847846 )
848- active_threats = (threat for threat in threats_json if "DEPRECATED" not in threat )
849- for threat in active_threats :
850- TM ._threats .append (Threat (** threat ))
847+
848+ active_threats = (threat for threat in threats_json if "DEPRECATED" not in threat )
849+ for threat in active_threats :
850+ TM ._threats .append (Threat (** threat ))
851851
852852 def resolve (self ):
853853 finding_count = 0
@@ -1129,6 +1129,19 @@ def _process(self):
11291129 result = get_args ()
11301130 logging .basicConfig (level = logging .INFO , format = "%(levelname)s: %(message)s" )
11311131
1132+ # delaying loading of threats to accomodate multiple threat files in the
1133+ # command line
1134+ if self .threatsFileInit == False :
1135+ tfs = [os .path .dirname (__file__ ) + "/threatlib/threats.json" ]
1136+ if result .threat_files :
1137+ tfs .extend (result .threat_files )
1138+ self .threatsFile = varStrings (
1139+ tfs ,
1140+ onSet = lambda i , v : i ._init_threats (),
1141+ doc = "JSON file with custom threats" ,
1142+ )
1143+ self .threatsFileInit = True
1144+
11321145 if result .debug :
11331146 logger .setLevel (logging .DEBUG )
11341147
@@ -1178,6 +1191,7 @@ def _process(self):
11781191 if result .stale_days is not None :
11791192 print (self ._stale (result .stale_days ))
11801193
1194+
11811195 def _stale (self , days ):
11821196 try :
11831197 base_path = os .path .dirname (sys .argv [0 ])
@@ -2158,6 +2172,11 @@ def get_args():
21582172 help = """checks if the delta between the TM script and the code described by it is bigger than the specified value in days""" ,
21592173 type = int ,
21602174 )
2175+ _parser .add_argument (
2176+ "--threat-files" ,
2177+ nargs = "+" ,
2178+ help = "Files containing libraries of threats."
2179+ )
21612180
21622181 _args = _parser .parse_args ()
21632182 return _args
0 commit comments