packages feed

nixpkgs-update-0.3.0: src/NVDRules.hs

{-# LANGUAGE OverloadedStrings #-}

module NVDRules where

import CVE (CPE (..), CPEMatch (..), CVE (..))
import Data.Char (isDigit)
import qualified Data.Text as T
import OurPrelude
import Text.Regex.Applicative.Text (RE', anySym, many, psym, (=~))
import Utils (Boundary (..), ProductID, Version, VersionMatcher (..))

-- Return False to discard CVE
filter :: CVE -> CPEMatch -> ProductID -> Version -> Bool
filter _ cpeMatch "socat" v
  | cpeUpdatePresentAndNotPartOfVersion cpeMatch v = False -- TODO consider if this rule should be applied to all packages
filter _ cpeMatch "uzbl" v
  | isNothing (v =~ yearRegex)
      && "2009.12.22" `anyVersionInfixOf` cpeMatchVersionMatcher cpeMatch =
    False
  | isNothing (v =~ yearRegex)
      && "2010.04.03" `anyVersionInfixOf` cpeMatchVersionMatcher cpeMatch =
    False
filter _ cpeMatch "go" v
  | "." `T.isInfixOf` v
      && "-" `anyVersionInfixOf` cpeMatchVersionMatcher cpeMatch =
    False
filter _ cpeMatch "terraform" _
  | cpeTargetSoftware (cpeMatchCPE cpeMatch) == Just "aws" = False
filter cve _ "tor" _
  | cveID cve == "CVE-2017-16541" = False
filter _ cpeMatch "arena" _
  | cpeVendor (cpeMatchCPE cpeMatch) == Just "rockwellautomation"
      || cpeVendor (cpeMatchCPE cpeMatch) == Just "openforis" =
    False
filter _ cpeMatch "thrift" _
  | cpeVendor (cpeMatchCPE cpeMatch) == Just "facebook" = False
filter _ cpeMatch "kanboard" _
  | cpeTargetSoftware (cpeMatchCPE cpeMatch) == Just "jenkins" = False
filter _cve _match _productID _version = True

anyVersionInfixOf :: Text -> VersionMatcher -> Bool
anyVersionInfixOf t (SingleMatcher v) = t `T.isInfixOf` v
anyVersionInfixOf t (RangeMatcher (Including v1) (Including v2)) =
  t `T.isInfixOf` v1 || t `T.isInfixOf` v2
anyVersionInfixOf t (RangeMatcher (Excluding v1) (Excluding v2)) =
  t `T.isInfixOf` v1 || t `T.isInfixOf` v2
anyVersionInfixOf t (RangeMatcher (Including v1) (Excluding v2)) =
  t `T.isInfixOf` v1 || t `T.isInfixOf` v2
anyVersionInfixOf t (RangeMatcher (Excluding v1) (Including v2)) =
  t `T.isInfixOf` v1 || t `T.isInfixOf` v2
anyVersionInfixOf t (RangeMatcher Unbounded (Including v)) = t `T.isInfixOf` v
anyVersionInfixOf t (RangeMatcher Unbounded (Excluding v)) = t `T.isInfixOf` v
anyVersionInfixOf t (RangeMatcher (Including v) Unbounded) = t `T.isInfixOf` v
anyVersionInfixOf t (RangeMatcher (Excluding v) Unbounded) = t `T.isInfixOf` v
anyVersionInfixOf _ (RangeMatcher Unbounded Unbounded) = False

-- Four digits at the start followed by any number of anything else
yearRegex :: RE' ()
yearRegex =
  void $
    psym isDigit <* psym isDigit <* psym isDigit <* psym isDigit <* many anySym

cpeUpdatePresentAndNotPartOfVersion :: CPEMatch -> Version -> Bool
cpeUpdatePresentAndNotPartOfVersion cpeMatch v =
  maybe
    False
    (\update -> not (update `T.isInfixOf` v))
    (cpeUpdate (cpeMatchCPE cpeMatch))