Skip to content

Commit 3d9785e

Browse files
Update hsec-tool to use the new CWE data and validation
1 parent 608c594 commit 3d9785e

File tree

7 files changed

+36
-14
lines changed

7 files changed

+36
-14
lines changed

.github/workflows/haskell-ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ jobs:
184184
echo "packages: $GITHUB_WORKSPACE/source/code/hsec-core" >> cabal.project
185185
echo "packages: $GITHUB_WORKSPACE/source/code/hsec-tools" >> cabal.project
186186
echo "packages: $GITHUB_WORKSPACE/source/code/cvss" >> cabal.project
187+
echo "packages: $GITHUB_WORKSPACE/source/code/cwe" >> cabal.project
187188
echo "packages: $GITHUB_WORKSPACE/source/code/osv" >> cabal.project
188189
cat cabal.project
189190
- name: sdist

cabal.project

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ packages: code/*/*.cabal
33
package hsec-core
44
package hsec-tools
55
package cvss
6+
package cwe
67
package osv

code/cwe/src/Security/CWE.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{-# LANGUAGE DerivingStrategies #-}
33
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
44
{-# LANGUAGE OverloadedStrings #-}
5-
module Security.CWE (CWEID, mkCWEID, cweNames, cweIds) where
5+
module Security.CWE (CWEID, unCWEID, mkCWEID, cweNames, cweIds) where
66

77
import Security.CWE.Data
88
import Data.Text (Text)
@@ -14,6 +14,10 @@ import Data.Bits
1414
newtype CWEID = CWEID Word
1515
deriving newtype (Eq, Ord, Show)
1616

17+
-- | Access the underlying data.
18+
unCWEID :: CWEID -> Word
19+
unCWEID (CWEID cwe) = cwe
20+
1721
mkCWEID :: (Integral a, Bits a) => a -> Maybe CWEID
1822
mkCWEID num = CWEID <$> toIntegralSized num
1923

code/hsec-core/src/Security/Advisories/Core/Advisory.hs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ module Security.Advisories.Core.Advisory
44
( Advisory(..)
55
-- * Supporting types
66
, Affected(..)
7-
, CWE(..)
7+
, CWEID
88
, Architecture(..)
99
, AffectedVersionRange(..)
1010
, OS(..)
1111
, Keyword(..)
1212
)
1313
where
1414

15+
import Security.CWE (CWEID)
1516
import Data.Text (Text)
1617
import Data.Time (ZonedTime)
1718
import Distribution.Types.Version (Version)
@@ -27,7 +28,7 @@ data Advisory = Advisory
2728
{ advisoryId :: HsecId
2829
, advisoryModified :: ZonedTime
2930
, advisoryPublished :: ZonedTime
30-
, advisoryCWEs :: [CWE]
31+
, advisoryCWEs :: [CWEID]
3132
, advisoryKeywords :: [Keyword]
3233
, advisoryAliases :: [Text]
3334
, advisoryRelated :: [Text]
@@ -54,9 +55,6 @@ data Affected = Affected
5455
}
5556
deriving stock (Show)
5657

57-
newtype CWE = CWE {unCWE :: Integer}
58-
deriving stock (Show)
59-
6058
data Architecture
6159
= AArch64
6260
| Alpha

code/hsec-tools/hsec-tools.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ library
4747
, commonmark-pandoc >=0.2 && <0.3
4848
, containers >=0.6 && <0.7
4949
, cvss
50+
, cwe
5051
, directory <2
5152
, extra ^>=1.7.5
5253
, filepath >=1.4 && <1.5

code/hsec-tools/src/Security/Advisories/Parse.hs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module Security.Advisories.Parse
1414
)
1515
where
1616

17+
import qualified Security.CWE as CWE
1718
import Data.Bifunctor (first)
1819
import Data.Foldable (toList)
1920
import Data.List (intercalate)
@@ -25,6 +26,7 @@ import GHC.Generics (Generic)
2526
import qualified Data.Map as Map
2627
import Data.Sequence (Seq((:<|)))
2728
import qualified Data.Text as T
29+
import qualified Data.Text.Read as T
2830
import qualified Data.Text.Lazy as T (toStrict)
2931
import Data.Time (ZonedTime(..), LocalTime (LocalTime), midnight, utc)
3032
import Distribution.Parsec (eitherParsec)
@@ -218,7 +220,7 @@ data AdvisoryMetadata = AdvisoryMetadata
218220
{ amdId :: HsecId
219221
, amdModified :: Maybe ZonedTime
220222
, amdPublished :: Maybe ZonedTime
221-
, amdCWEs :: [CWE]
223+
, amdCWEs :: [CWE.CWEID]
222224
, amdKeywords :: [Keyword]
223225
, amdAliases :: [T.Text]
224226
, amdRelated :: [T.Text]
@@ -317,11 +319,26 @@ instance Toml.FromValue HsecId where
317319
instance Toml.ToValue HsecId where
318320
toValue = Toml.toValue . printHsecId
319321

320-
instance Toml.FromValue CWE where
321-
fromValue v = CWE <$> Toml.fromValue v
322-
323-
instance Toml.ToValue CWE where
324-
toValue (CWE x) = Toml.toValue x
322+
instance Toml.FromValue CWE.CWEID where
323+
fromValue v = case v of
324+
-- Check if the cwe number is known
325+
Toml.Integer int | Just cwe <- CWE.mkCWEID int, Map.member cwe CWE.cweNames -> pure cwe
326+
-- Check if the cwe text match "number: description"
327+
Toml.String string -> case T.breakOn ":" (T.pack string) of
328+
(numTxt, name) -> case T.decimal numTxt of
329+
Right (num, "") -> do
330+
-- Value is a "num: text", now validate if it's known
331+
cwe <- Toml.fromValue (Toml.Integer num)
332+
case T.strip (T.drop 1 name) of
333+
"" -> pure cwe
334+
expectedName -> case Map.lookup cwe CWE.cweNames of
335+
Just cweName | expectedName == cweName -> pure cwe
336+
_ -> fail ("unexpected description, got: " <> show cwe <> ", expected: " <> show expectedName)
337+
_ -> fail ("expected a number, got: " <> show numTxt)
338+
_ -> fail "expected a valid number or a cwe text description"
339+
340+
instance Toml.ToValue CWE.CWEID where
341+
toValue = Toml.toValue . CWE.unCWEID
325342

326343
instance Toml.FromValue Keyword where
327344
fromValue v = Keyword <$> Toml.fromValue v

flake.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
pkgs.haskell.lib.doJailbreak (pkgs.haskell.lib.dontCheck (pkgs.haskell.lib.unmarkBroken pkg));
2121

2222
cvss = pkgs.haskellPackages.callCabal2nix "cvss" ./code/cvss { };
23+
cwe = pkgs.haskellPackages.callCabal2nix "cwe" ./code/cwe { };
2324
osv = pkgs.haskellPackages.callCabal2nix "osv" ./code/osv { inherit cvss; };
2425
hsec-core = pkgs.haskellPackages.callCabal2nix "hsec-core" ./code/hsec-core {
2526
inherit cvss osv;
@@ -33,10 +34,9 @@
3334
root = ./code/hsec-tools;
3435
withHoogle = false;
3536
overrides = self: super: {
36-
inherit cvss hsec-core osv;
37+
inherit cvss cwe hsec-core osv;
3738
Cabal-syntax = super.Cabal-syntax_3_8_1_0;
3839
toml-parser = jailbreakUnbreak (super.callCabal2nix "toml-parser" toml-parser { });
39-
cwe = super.callCabal2nix "cwe" ./code/cwe {};
4040
};
4141

4242
modifier = drv:

0 commit comments

Comments
 (0)