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
Exemple #3
0
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')
            })