class AbstractScannerRule(ModelBase): name = models.CharField( max_length=200, help_text=_('This is the exact name of the rule used by a scanner.'), ) scanner = models.PositiveSmallIntegerField(choices=SCANNERS.items()) action = models.PositiveSmallIntegerField(choices=ACTIONS.items(), default=NO_ACTION) is_active = models.BooleanField( default=True, help_text=_( 'When unchecked, the scanner results will not be bound to this ' 'rule and the action will not be executed.')) definition = models.TextField(null=True, blank=True) class Meta(ModelBase.Meta): abstract = True unique_together = ('name', 'scanner') def __str__(self): return self.name def clean(self): if self.scanner == YARA: self.clean_yara() def clean_yara(self): if not self.definition: raise ValidationError( {'definition': _('Yara rules should have a definition')}) if 'rule {}'.format(self.name) not in self.definition: raise ValidationError({ 'definition': _('The name of the rule in the definition should match ' 'the name of the scanner rule') }) if len(re.findall(r'rule\s+.+?\s+{', self.definition)) > 1: raise ValidationError({ 'definition': _('Only one Yara rule is allowed in the definition') }) try: yara.compile(source=self.definition) except yara.SyntaxError as syntaxError: raise ValidationError({ 'definition': _('The definition is not valid: %(error)s') % { 'error': syntaxError, } }) except Exception: raise ValidationError({ 'definition': _('An error occurred when compiling the definition') })
class ScannerRule(ModelBase): name = models.CharField( max_length=200, help_text=_('This is the exact name of the rule used by a scanner.'), ) scanner = models.PositiveSmallIntegerField(choices=SCANNERS.items()) action = models.PositiveSmallIntegerField(choices=ACTIONS.items(), default=NO_ACTION) is_active = models.BooleanField(default=True) class Meta: db_table = 'scanners_rules' unique_together = ('name', 'scanner') def __str__(self): return self.name
class AbstractScannerRule(ModelBase): name = models.CharField( max_length=200, help_text=_('This is the exact name of the rule used by a scanner.'), ) scanner = models.PositiveSmallIntegerField(choices=SCANNERS.items()) action = models.PositiveSmallIntegerField(choices=ACTIONS.items(), default=NO_ACTION) is_active = models.BooleanField( default=True, help_text=_( 'When unchecked, the scanner results will not be bound to this ' 'rule and the action will not be executed.'), ) definition = models.TextField(null=True, blank=True) class Meta(ModelBase.Meta): abstract = True unique_together = ('name', 'scanner') @classmethod def get_yara_externals(cls): """ Return a dict with the various external variables we inject in every yara rule automatically and their default values. """ return { 'is_json_file': False, 'is_manifest_file': False, 'is_locale_file': False, } def __str__(self): return self.name def clean(self): if self.scanner == YARA: self.clean_yara() def clean_yara(self): if not self.definition: raise ValidationError( {'definition': _('Yara rules should have a definition')}) if f'rule {self.name}' not in self.definition: raise ValidationError({ 'definition': _('The name of the rule in the definition should match ' 'the name of the scanner rule') }) if len(re.findall(r'rule\s+.+?\s+{', self.definition)) > 1: raise ValidationError({ 'definition': _('Only one Yara rule is allowed in the definition') }) try: yara.compile(source=self.definition, externals=self.get_yara_externals()) except yara.SyntaxError as syntaxError: raise ValidationError({ 'definition': _('The definition is not valid: %(error)s') % { 'error': syntaxError } }) except Exception: raise ValidationError({ 'definition': _('An error occurred when compiling the definition') })