diff --git a/.github/workflows/haskell-ci.yml b/.github/workflows/haskell-ci.yml index abbbb5e5..55caf438 100644 --- a/.github/workflows/haskell-ci.yml +++ b/.github/workflows/haskell-ci.yml @@ -181,8 +181,10 @@ jobs: - name: initial cabal.project for sdist run: | touch cabal.project + echo "packages: $GITHUB_WORKSPACE/source/code/hsec-core" >> cabal.project echo "packages: $GITHUB_WORKSPACE/source/code/hsec-tools" >> cabal.project echo "packages: $GITHUB_WORKSPACE/source/code/cvss" >> cabal.project + echo "packages: $GITHUB_WORKSPACE/source/code/osv" >> cabal.project cat cabal.project - name: sdist run: | @@ -196,20 +198,34 @@ jobs: run: | PKGDIR_hsec_tools="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/hsec-tools-[0-9.]*')" echo "PKGDIR_hsec_tools=${PKGDIR_hsec_tools}" >> "$GITHUB_ENV" + PKGDIR_hsec_tools="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/hsec-tools-[0-9.]*')" + echo "PKGDIR_hsec_tools=${PKGDIR_hsec_tools}" >> "$GITHUB_ENV" + PKGDIR_hsec_core="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/hsec-core-[0-9.]*')" + echo "PKGDIR_hsec_core=${PKGDIR_hsec_core}" >> "$GITHUB_ENV" + PKGDIR_osv="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/osv-[0-9.]*')" + echo "PKGDIR_osv=${PKGDIR_osv}" >> "$GITHUB_ENV" PKGDIR_cvss="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/cvss-[0-9.]*')" echo "PKGDIR_cvss=${PKGDIR_cvss}" >> "$GITHUB_ENV" rm -f cabal.project cabal.project.local touch cabal.project touch cabal.project.local + echo "packages: ${PKGDIR_hsec_core}" >> cabal.project echo "packages: ${PKGDIR_hsec_tools}" >> cabal.project + echo "packages: ${PKGDIR_osv}" >> cabal.project echo "packages: ${PKGDIR_cvss}" >> cabal.project echo "package hsec-tools" >> cabal.project echo " ghc-options: -Werror=missing-methods" >> cabal.project + echo "package hsec-tools" >> cabal.project + echo " ghc-options: -Werror=missing-methods" >> cabal.project + echo "package hsec-core" >> cabal.project + echo " ghc-options: -Werror=missing-methods" >> cabal.project + echo "package osv" >> cabal.project + echo " ghc-options: -Werror=missing-methods" >> cabal.project echo "package cvss" >> cabal.project echo " ghc-options: -Werror=missing-methods" >> cabal.project cat >> cabal.project <> cabal.project.local + $HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(cvss|osv|hsec-core|hsec-tools)$/; }' >> cabal.project.local cat cabal.project cat cabal.project.local - name: dump install plan @@ -239,13 +255,19 @@ jobs: run: | if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_hsec_tools} && hlint -XHaskell2010 src) ; fi if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_hsec_tools} && hlint -XHaskell2010 app) ; fi + if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_hsec_core} && hlint -XHaskell2010 src) ; fi + if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_osv} && hlint -XHaskell2010 src) ; fi if [ $((HCNUMVER >= 90400 && HCNUMVER < 90600)) -ne 0 ] ; then (cd ${PKGDIR_cvss} && hlint -XHaskell2010 src) ; fi - name: cabal check run: | + cd ${PKGDIR_hsec_core} || false + ${CABAL} -vnormal check cd ${PKGDIR_hsec_tools} || false ${CABAL} -vnormal check cd ${PKGDIR_cvss} || false ${CABAL} -vnormal check + cd ${PKGDIR_osv} || false + ${CABAL} -vnormal check - name: haddock run: | $CABAL v2-haddock --disable-documentation --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all diff --git a/cabal.project b/cabal.project index 41943084..3f2ec970 100644 --- a/cabal.project +++ b/cabal.project @@ -1,4 +1,6 @@ packages: code/*/*.cabal +package hsec-core package hsec-tools package cvss +package osv diff --git a/code/hsec-core/.gitignore b/code/hsec-core/.gitignore new file mode 100644 index 00000000..c5e63c97 --- /dev/null +++ b/code/hsec-core/.gitignore @@ -0,0 +1,30 @@ +##### Haskell +dist +dist-* +cabal-dev +*.o +*.hi +*.hie +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog +.stack-work/ +cabal.project.local +cabal.project.local~ +.HTF/ +.ghc.environment.* +build +bin-* + +result +.direnv +.env diff --git a/code/hsec-core/CHANGELOG.md b/code/hsec-core/CHANGELOG.md new file mode 100644 index 00000000..e69de29b diff --git a/code/hsec-core/README.md b/code/hsec-core/README.md new file mode 100644 index 00000000..93d792e4 --- /dev/null +++ b/code/hsec-core/README.md @@ -0,0 +1,15 @@ +# hsec-core + +`hesc-core` aims to support [Haskell advisories database](https://github.com/haskell/security-advisories). + +## Building + +We aim to support both regular cabal-based and nix-based builds. + +## Testing + +Run (and auto update) the golden test: + +```ShellSession +cabal test -O0 --test-show-details=direct --test-option=--accept +``` diff --git a/code/hsec-core/hsec-core.cabal b/code/hsec-core/hsec-core.cabal new file mode 100644 index 00000000..2039abbc --- /dev/null +++ b/code/hsec-core/hsec-core.cabal @@ -0,0 +1,67 @@ +cabal-version: 2.4 +name: hsec-core +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: Core package representing Haskell advisories + +-- A longer description of the package. +description: Core package representing Haskell advisories. + +-- A URL where users can report bugs. +-- bug-reports: + +-- The license under which the package is released. +license: BSD-3-Clause +author: David Christiansen +maintainer: david@davidchristiansen.dk + +-- A copyright notice. +-- copyright: +category: Data +extra-doc-files: CHANGELOG.md + +tested-with: + GHC ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.8 || ==9.6.3 || ==9.8.1 + +library + exposed-modules: + Security.Advisories.Core.Advisory + Security.Advisories.Core.HsecId + + build-depends: + , base >=4.14 && <4.20 + , Cabal-syntax >=3.8.1.0 && <3.11 + , cvss + , osv + , pandoc-types >=1.22 && <2 + , safe >=0.3 + , text >=1.2 && <3 + , time >=1.9 && <1.14 + + -- , commonmark ^>=0.2.2 + -- , commonmark-pandoc >=0.2 && <0.3 + -- , containers >=0.6 && <0.7 + -- , mtl >=2.2 && <2.4 + hs-source-dirs: src + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints + +test-suite spec + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Spec.hs + build-depends: + , base <5 + , cvss + , hsec-core + , tasty <1.5 + , tasty-hunit <0.11 + , text + + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints diff --git a/code/hsec-tools/src/Security/Advisories/Definition.hs b/code/hsec-core/src/Security/Advisories/Core/Advisory.hs similarity index 96% rename from code/hsec-tools/src/Security/Advisories/Definition.hs rename to code/hsec-core/src/Security/Advisories/Core/Advisory.hs index d5f8e6d1..1211be2b 100644 --- a/code/hsec-tools/src/Security/Advisories/Definition.hs +++ b/code/hsec-core/src/Security/Advisories/Core/Advisory.hs @@ -1,6 +1,6 @@ {-# LANGUAGE DerivingVia #-} -module Security.Advisories.Definition +module Security.Advisories.Core.Advisory ( Advisory(..) -- * Supporting types , Affected(..) @@ -19,7 +19,7 @@ import Distribution.Types.VersionRange (VersionRange) import Text.Pandoc.Definition (Pandoc) -import Security.Advisories.HsecId +import Security.Advisories.Core.HsecId import qualified Security.CVSS as CVSS import Security.OSV (Reference) diff --git a/code/hsec-tools/src/Security/Advisories/HsecId.hs b/code/hsec-core/src/Security/Advisories/Core/HsecId.hs similarity index 98% rename from code/hsec-tools/src/Security/Advisories/HsecId.hs rename to code/hsec-core/src/Security/Advisories/Core/HsecId.hs index 7835219c..e1155cf2 100644 --- a/code/hsec-tools/src/Security/Advisories/HsecId.hs +++ b/code/hsec-core/src/Security/Advisories/Core/HsecId.hs @@ -1,4 +1,4 @@ -module Security.Advisories.HsecId +module Security.Advisories.Core.HsecId ( HsecId , hsecIdYear diff --git a/code/hsec-core/test/Spec.hs b/code/hsec-core/test/Spec.hs new file mode 100644 index 00000000..52c35ba7 --- /dev/null +++ b/code/hsec-core/test/Spec.hs @@ -0,0 +1,10 @@ +module Main where + +import Test.Tasty + +main :: IO () +main = + defaultMain $ + testGroup + "Tests" + [] diff --git a/code/hsec-tools/app/Command/Reserve.hs b/code/hsec-tools/app/Command/Reserve.hs index acc5a463..2e937d9c 100644 --- a/code/hsec-tools/app/Command/Reserve.hs +++ b/code/hsec-tools/app/Command/Reserve.hs @@ -13,7 +13,7 @@ import Security.Advisories.Git , explainGitError , getRepoRoot ) -import Security.Advisories.HsecId +import Security.Advisories.Core.HsecId ( placeholder , printHsecId , getNextHsecId diff --git a/code/hsec-tools/hsec-tools.cabal b/code/hsec-tools/hsec-tools.cabal index 9c0c0fe2..00d3bc61 100644 --- a/code/hsec-tools/hsec-tools.cabal +++ b/code/hsec-tools/hsec-tools.cabal @@ -33,37 +33,36 @@ library exposed-modules: Security.Advisories Security.Advisories.Convert.OSV - Security.Advisories.Definition Security.Advisories.Filesystem Security.Advisories.Generate.HTML Security.Advisories.Git - Security.Advisories.HsecId Security.Advisories.Parse Security.Advisories.Queries - Security.OSV build-depends: - , aeson >=2.0.1.0 && <3 - , base >=4.14 && <4.20 - , Cabal-syntax >=3.8.1.0 && <3.11 + , aeson >=2.0.1.0 && <3 + , base >=4.14 && <4.20 + , Cabal-syntax >=3.8.1.0 && <3.11 , commonmark ^>=0.2.2 - , commonmark-pandoc >=0.2 && <0.3 - , containers >=0.6 && <0.7 + , commonmark-pandoc >=0.2 && <0.3 + , containers >=0.6 && <0.7 , cvss , directory <2 , extra ^>=1.7.5 - , filepath >=1.4 && <1.5 + , filepath >=1.4 && <1.5 + , hsec-core , lucid >=2.9.0 - , mtl >=2.2 && <2.4 - , pandoc-types >=1.22 && <2 - , parsec >=3 && <4 + , mtl >=2.2 && <2.4 + , osv + , pandoc-types >=1.22 && <2 + , parsec >=3 && <4 , pathwalk >=0.3 - , process >=1.6 && <1.7 + , process >=1.6 && <1.7 , safe >=0.3 - , text >=1.2 && <3 - , time >=1.9 && <1.14 + , text >=1.2 && <3 + , time >=1.9 && <1.14 , toml-parser ^>=1.3.0.0 - , validation-selective >=0.1 && <1 + , validation-selective >=0.1 && <1 hs-source-dirs: src default-language: Haskell2010 @@ -86,6 +85,7 @@ executable hsec-tools , bytestring >=0.10 && <0.13 , Cabal-syntax >=3.8.1.0 && <3.11 , filepath >=1.4 && <1.5 + , hsec-core , hsec-tools , optparse-applicative >=0.17 && <0.19 , text >=1.2 && <3 @@ -108,6 +108,7 @@ test-suite spec , Cabal-syntax , cvss , directory + , hsec-core , hsec-tools , pretty-simple <5 , tasty <1.5 diff --git a/code/hsec-tools/index.html b/code/hsec-tools/index.html new file mode 100644 index 00000000..28fb61f3 --- /dev/null +++ b/code/hsec-tools/index.html @@ -0,0 +1,133 @@ + + + + + + + Haskell Security Advisories + + + +
+
+ Advisories list + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
#Package(s)Title
HSEC-2023-0003xmonad-contribcode injection in xmonad-contrib
HSEC-2023-0002biscuit-haskellImproper Verification of Cryptographic Signature
HSEC-2023-0001aesonHash flooding vulnerability in aeson
+
+
+
+

aeson

+
+ + + + + + + + + + + + + + + + + +
#IntroducedFixedTitle
HSEC-2023-00011.1.0Hash flooding vulnerability in aeson
+
+

biscuit-haskell

+
+ + + + + + + + + + + + + + + + + +
#IntroducedFixedTitle
HSEC-2023-00021.1.02.0.0Improper Verification of Cryptographic Signature
+
+

xmonad-contrib

+
+ + + + + + + + + + + + + + + + + +
#IntroducedFixedTitle
HSEC-2023-00031.1.02.0.0code injection in xmonad-contrib
+
+
+
+ + diff --git a/code/hsec-tools/src/Security/Advisories.hs b/code/hsec-tools/src/Security/Advisories.hs index fd96865f..4c8e5f8b 100644 --- a/code/hsec-tools/src/Security/Advisories.hs +++ b/code/hsec-tools/src/Security/Advisories.hs @@ -1,10 +1,10 @@ module Security.Advisories - ( module Security.Advisories.Definition - , module Security.Advisories.HsecId + ( module Security.Advisories.Core.Advisory + , module Security.Advisories.Core.HsecId , module Security.Advisories.Parse ) where -import Security.Advisories.Definition -import Security.Advisories.HsecId +import Security.Advisories.Core.Advisory +import Security.Advisories.Core.HsecId import Security.Advisories.Parse diff --git a/code/hsec-tools/src/Security/Advisories/Filesystem.hs b/code/hsec-tools/src/Security/Advisories/Filesystem.hs index adbe61d1..f3877a5c 100644 --- a/code/hsec-tools/src/Security/Advisories/Filesystem.hs +++ b/code/hsec-tools/src/Security/Advisories/Filesystem.hs @@ -40,7 +40,7 @@ import System.Directory.PathWalk import Validation (Validation, eitherToValidation) import Security.Advisories (Advisory, AttributeOverridePolicy (NoOverrides), OutOfBandAttributes (..), ParseAdvisoryError, emptyOutOfBandAttributes, parseAdvisory) -import Security.Advisories.HsecId (HsecId, parseHsecId, placeholder) +import Security.Advisories.Core.HsecId (HsecId, parseHsecId, placeholder) import Security.Advisories.Git(firstAppearanceCommitDate, getAdvisoryGitInfo, lastModificationCommitDate) diff --git a/code/hsec-tools/src/Security/Advisories/Generate/HTML.hs b/code/hsec-tools/src/Security/Advisories/Generate/HTML.hs index ba541973..7652b8c1 100644 --- a/code/hsec-tools/src/Security/Advisories/Generate/HTML.hs +++ b/code/hsec-tools/src/Security/Advisories/Generate/HTML.hs @@ -158,7 +158,7 @@ inPage page content = base_ [href_ $ baseUrlForPage page] link_ [rel_ "stylesheet", href_ "https://cdn.jsdelivr.net/npm/purecss@3.0.0/build/pure-min.css", integrity_ "sha384-X38yfunGUhNzHpBaEBsWLO+A0HDYOQi8ufWDkZ0k9e0eXz/tH3II7uKZ9msv++Ls", crossorigin_ "anonymous"] meta_ [name_ "viewport", content_ "width=device-width, initial-scale=1"] - title_ "Haskell Security Advisories" + title_ "Haskell Security.Advisories.Core" style_ $ T.intercalate "\n" diff --git a/code/hsec-tools/src/Security/Advisories/Parse.hs b/code/hsec-tools/src/Security/Advisories/Parse.hs index 52449da8..fd5c5431 100644 --- a/code/hsec-tools/src/Security/Advisories/Parse.hs +++ b/code/hsec-tools/src/Security/Advisories/Parse.hs @@ -45,8 +45,8 @@ import Text.Pandoc.Definition (Block(..), Inline(..), Pandoc(..)) import Text.Pandoc.Walk (query) import Text.Parsec.Pos (sourceLine) -import Security.Advisories.HsecId -import Security.Advisories.Definition +import Security.Advisories.Core.HsecId +import Security.Advisories.Core.Advisory import Security.OSV (Reference(..), referenceTypes) import qualified Security.CVSS as CVSS diff --git a/code/hsec-tools/src/Security/Advisories/Queries.hs b/code/hsec-tools/src/Security/Advisories/Queries.hs index c4d0104c..7d04555f 100644 --- a/code/hsec-tools/src/Security/Advisories/Queries.hs +++ b/code/hsec-tools/src/Security/Advisories/Queries.hs @@ -13,7 +13,7 @@ import Distribution.Types.VersionInterval (asVersionIntervals) import Distribution.Types.VersionRange (VersionRange, anyVersion, earlierVersion, intersectVersionRanges, noVersion, orLaterVersion, unionVersionRanges, withinRange) import Validation (Validation(..)) -import Security.Advisories.Definition +import Security.Advisories.Core.Advisory import Security.Advisories.Filesystem import Security.Advisories.Parse diff --git a/code/hsec-tools/test/Spec/QueriesSpec.hs b/code/hsec-tools/test/Spec/QueriesSpec.hs index ef2caeb9..69554036 100644 --- a/code/hsec-tools/test/Spec/QueriesSpec.hs +++ b/code/hsec-tools/test/Spec/QueriesSpec.hs @@ -15,8 +15,8 @@ import Test.Tasty import Test.Tasty.HUnit import Security.CVSS (parseCVSS) -import Security.Advisories.Definition -import Security.Advisories.HsecId +import Security.Advisories.Core.Advisory +import Security.Advisories.Core.HsecId import Security.Advisories.Queries spec :: TestTree diff --git a/code/osv/.gitignore b/code/osv/.gitignore new file mode 100644 index 00000000..c5e63c97 --- /dev/null +++ b/code/osv/.gitignore @@ -0,0 +1,30 @@ +##### Haskell +dist +dist-* +cabal-dev +*.o +*.hi +*.hie +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog +.stack-work/ +cabal.project.local +cabal.project.local~ +.HTF/ +.ghc.environment.* +build +bin-* + +result +.direnv +.env diff --git a/code/osv/CHANGELOG.md b/code/osv/CHANGELOG.md new file mode 100644 index 00000000..e69de29b diff --git a/code/osv/README.md b/code/osv/README.md new file mode 100644 index 00000000..eb2d86dc --- /dev/null +++ b/code/osv/README.md @@ -0,0 +1,7 @@ +# osv + +This project aims to support [Open Source Vulnerability format](https://ossf.github.io/osv-schema/). + +## Building + +We aim to support both regular cabal-based and nix-based builds. diff --git a/code/osv/osv.cabal b/code/osv/osv.cabal new file mode 100644 index 00000000..5c5eea3f --- /dev/null +++ b/code/osv/osv.cabal @@ -0,0 +1,59 @@ +cabal-version: 2.4 +name: osv +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: + Open Source Vulnerability format + +-- A longer description of the package. +description: + Open Source Vulnerability format. + +-- A URL where users can report bugs. +-- bug-reports: + +-- The license under which the package is released. +license: BSD-3-Clause +author: David Christiansen +maintainer: david@davidchristiansen.dk + +-- A copyright notice. +-- copyright: +category: Data +extra-doc-files: CHANGELOG.md + +tested-with: + GHC ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.8 || ==9.6.3 || ==9.8.1 + +library + exposed-modules: + Security.OSV + + build-depends: + , aeson >=2.0.1.0 && <3 + , base >=4.14 && <4.20 + , cvss + , text >=1.2 && <3 + , time >=1.9 && <1.14 + + hs-source-dirs: src + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints + +test-suite spec + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Spec.hs + build-depends: + , base <5 + , osv + , tasty <1.5 + , tasty-hunit <0.11 + + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints diff --git a/code/hsec-tools/src/Security/OSV.hs b/code/osv/src/Security/OSV.hs similarity index 100% rename from code/hsec-tools/src/Security/OSV.hs rename to code/osv/src/Security/OSV.hs diff --git a/code/osv/test/Spec.hs b/code/osv/test/Spec.hs new file mode 100644 index 00000000..0ffe11d5 --- /dev/null +++ b/code/osv/test/Spec.hs @@ -0,0 +1,11 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Main where + +import Test.Tasty + +main :: IO () +main = + defaultMain $ + testGroup "Tests" + [] diff --git a/flake.nix b/flake.nix index 866b0364..b7247016 100644 --- a/flake.nix +++ b/flake.nix @@ -20,6 +20,11 @@ pkgs.haskell.lib.doJailbreak (pkgs.haskell.lib.dontCheck (pkgs.haskell.lib.unmarkBroken pkg)); cvss = pkgs.haskellPackages.callCabal2nix "cvss" ./code/cvss {}; + osv = pkgs.haskellPackages.callCabal2nix "osv" ./code/osv {inherit cvss;}; + hsec-core = pkgs.haskellPackages.callCabal2nix "hsec-core" ./code/hsec-core { + inherit cvss osv; + Cabal-syntax = pkgs.haskellPackages.Cabal-syntax_3_8_1_0; + }; hsec-tools = returnShellEnv: pkgs.haskellPackages.developPackage { @@ -28,7 +33,7 @@ root = ./code/hsec-tools; withHoogle = false; overrides = self: super: { - inherit cvss; + inherit cvss hsec-core osv; Cabal-syntax = super.Cabal-syntax_3_8_1_0; toml-parser = jailbreakUnbreak (super.callCabal2nix "toml-parser" toml-parser { }); }; @@ -56,6 +61,8 @@ in { packages.cvss = cvss; + packages.osv = osv; + packages.hsec-core = hsec-core; packages.hsec-tools = pkgs.haskell.lib.justStaticExecutables (hsec-tools false); packages.hsec-tools-image = pkgs.dockerTools.buildImage {