Skip to content

Commit ce2702c

Browse files
authored
Display security advisory summary in /security package sub-resource (#790)
* Display CVE summary in /security package sub-resource * Make the listing responsive * Link from the package page
1 parent 15748a3 commit ce2702c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+10694
-674
lines changed

.github/PULL_REQUEST_TEMPLATE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Contributor checklist
44

5-
- [ ] My PR is related to \<insert ticket number>
5+
- [ ] My PR is related to \<insert ticket number>
66
- [ ] I have read and understood the [CONTRIBUTING guide](https://github.com/flora-pm/flora-server/blob/development/CONTRIBUTING.md)
77
- [ ] I have inserted my change and a link to this PR in the [CHANGELOG](https://github.com/flora-pm/flora-server/blob/development/CHANGELOG.md)
88
- [ ] I have updated documentation in `./docs/docs` if a public feature has a behaviour change

.github/workflows/backend.yml

+12-10
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,6 @@ jobs:
5656
ghc-version: "${{ matrix.ghc }}"
5757
cabal-version: "latest"
5858

59-
- uses: actions/setup-node@v4
60-
with:
61-
node-version: "18"
62-
cache: "yarn"
63-
cache-dependency-path: assets/yarn.lock
64-
6559
- name: Configure environment
6660
run: |
6761
./.github/workflows/setup.sh
@@ -77,20 +71,28 @@ jobs:
7771
echo "${FLORA_DB_HOST}:${FLORA_DB_PORT}:${FLORA_DB_DATABASE}:${FLORA_DB_USER}:${FLORA_DB_PASSWORD}" > .pgpass
7872
cat ~/.pgpass
7973
cabal update
74+
mkdir -p ~/.local/share
75+
git clone https://github.com/haskell/security-advisories.git ~/.local/share/security-advisories
76+
cd ~/.local/share/security-advisories
77+
git checkout df64e86a39668c057031fe7e2c679b1003090e03
78+
cd -
79+
80+
- name: "Create freeze file"
81+
run: |
82+
cabal freeze --enable-tests
8083
- name: Cache
81-
uses: actions/cache@v4.2.0
84+
uses: actions/cache@v4
8285
with:
8386
path: ${{ steps.setup-haskell.outputs.cabal-store }}
84-
key: ${{ runner.os }}-ghc-${{ matrix.ghc }}-cabal-${{ hashFiles('./.plan.json') }}
87+
key: ${{ runner.os }}-ghc-${{ matrix.ghc }}-cabal-${{ hashFiles('./dist-newstyle/cache/plan.json') }}
8588
restore-keys: ${{ runner.os }}-ghc-${{ matrix.ghc }}-
8689

8790
- name: Build
8891
run: |
8992
cabal install postgresql-migration
9093
make soufflé
91-
make assets-deps
92-
make build-assets
9394
make build
95+
9496
- name: Test
9597
run: |
9698
set -x

.plan.json

-1
This file was deleted.

Makefile

+42-14
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ clean-assets: ## Remove JS artifacts
3030
@cd assets/ && rm -R node_modules
3131
@cd docs/ && rm -R node_modules
3232

33+
db-setup: db-create db-init db-migrate ## Setup the dev database
34+
3335
db-create: ## Create the database
3436
@createdb -h $(FLORA_DB_HOST) -p $(FLORA_DB_PORT) -U $(FLORA_DB_USER) $(FLORA_DB_DATABASE)
3537

3638
db-drop: ## Drop the database
3739
@dropdb -f --if-exists -h $(FLORA_DB_HOST) -p $(FLORA_DB_PORT) -U $(FLORA_DB_USER) $(FLORA_DB_DATABASE)
3840

39-
db-setup: db-create db-init db-migrate ## Setup the dev database
40-
4141
db-init: ## Create the database schema
4242
@migrate init "$(FLORA_DB_CONNSTRING)"
4343

@@ -56,10 +56,38 @@ db-provision: ## Create categories and repositories
5656
@cabal run -- flora-cli provision-repository --name "horizon" --url https://packages.horizon-haskell.net \
5757
--description "Packages of the Horizon project"
5858

59-
db-provision-test-packages: ## Load development data in the database
59+
db-provision-advisories: ## Load HSEC advisories in the database
60+
@cabal run -- flora-cli provision advisories
61+
62+
db-provision-packages: ## Load development data in the dev database
6063
@cabal run -- flora-cli provision test-packages --repository "hackage"
6164
@cabal run -- flora-cli provision test-packages --repository "cardano"
6265

66+
db-test-create: ## Create the test database
67+
./scripts/run-with-test-config.sh db-create
68+
69+
db-test-setup: db-test-create db-test-init db-test-migrate ## Setup the dev database
70+
71+
db-test-drop: ## Drop the test database
72+
./scripts/run-with-test-config.sh db-drop
73+
74+
db-test-init: ## Create the test database schema
75+
./scripts/run-with-test-config.sh db-init
76+
77+
db-test-migrate: ## Apply test database migrations
78+
./scripts/run-with-test-config.sh db-migrate
79+
80+
db-test-reset: db-test-drop db-test-setup db-test-provision ## Reset the test database
81+
82+
db-test-provision: ## Create categories and repositories
83+
./scripts/run-with-test-config.sh db-provision
84+
85+
db-test-provision-advisories: ## Load HSEC advisories in the test database
86+
./scripts/run-with-test-config.sh db-provision-advisories
87+
88+
db-test-provision-packages: ## Load development data in the database
89+
./scripts/run-with-test-config.sh db-provision-packages
90+
6391
import-from-hackage: ## Imports every cabal file from the ./index-01 directory
6492
@cabal run -- flora-cli import-packages ./01-index
6593

@@ -125,9 +153,20 @@ tags: ## Generate ctags for the project with `ghc-tags`
125153

126154
design-system: ## Generate the HTML components used by the design system
127155
@cabal run -- flora-cli gen-design-system
156+
128157
start-design-sysytem: ## Start storybook.js
129158
@cd design; yarn storybook
130159

160+
migration: ## Generate timestamped database migration boilerplate files
161+
@if test -z "$$name"; then \
162+
echo "Usage: make migration name=some-name"; \
163+
else \
164+
migName="`date -u '+%Y%m%d%H%M%S'`_$$name"; \
165+
fname="migrations/$$migName.sql"; \
166+
touch "$$fname"; \
167+
echo "Touched $$fname";\
168+
fi
169+
131170
help:
132171
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.* ?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
133172

@@ -144,14 +183,3 @@ endif
144183
.PHONY: all $(MAKECMDGOALS)
145184

146185
.DEFAULT_GOAL := help
147-
148-
.PHONY: migration
149-
migration: ## Generate timestamped database migration boilerplate files
150-
@if test -z "$$name"; then \
151-
echo "Usage: make migration name=some-name"; \
152-
else \
153-
migName="`date -u '+%Y%m%d%H%M%S'`_$$name"; \
154-
fname="migrations/$$migName.sql"; \
155-
touch "$$fname"; \
156-
echo "Touched $$fname";\
157-
fi

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
* 🌓 Dark and light modes
5050
* 📱 Mobile user interface
5151

52-
## 📖 Guides
52+
## 📖 Guides
5353

5454
Visit https://flora.pm/documentation for explanations on what Flora can do.
5555

@@ -66,4 +66,4 @@ To setup a local installation, see [CONTRIBUTING.md#project-setup](https://githu
6666

6767
## 🫶 Special Collaborations
6868

69-
We would like to thank our dear friends at Guérilla Studio ([www](https://guerilla.studio/), [GitHub](https://github.com/GuerillaStudio)) for help with accessibility and CSS integration.
69+
We would like to thank our dear friends at Guérilla.Studio ([www](https://guerilla.studio/), [GitHub](https://github.com/GuerillaStudio)) for help with accessibility and CSS integration.

app/cli/DesignSystem.hs

+54-6
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ module DesignSystem where
55
import Control.Monad.Trans.Reader (runReaderT)
66
import Data.ByteString.Lazy (ByteString)
77
import Data.ByteString.Lazy qualified as ByteString
8+
import Data.Either.Extra
89
import Data.Foldable (forM_)
910
import Data.Functor.Identity (runIdentity)
11+
import Data.Maybe (fromJust)
1012
import Data.Text (Text)
1113
import Data.Text.Lazy qualified as TL
1214
import Data.Time.Calendar.OrdinalDate as Time
@@ -20,13 +22,17 @@ import Effectful.Fail
2022
import Env
2123
import Lucid
2224
import PyF (fmt)
25+
import Security.Advisories.Core.HsecId qualified as HsecId
26+
import Security.CVSS
2327

28+
import Advisories.Model.Affected.Types
2429
import Distribution.SPDX
2530
import Flora.Environment.Config
2631
import Flora.Model.Category
2732
import Flora.Model.Category qualified as Category
2833
import Flora.Model.Package
2934
import Flora.Search
35+
import FloraWeb.Components.AdvisoryListItem qualified as Component
3036
import FloraWeb.Components.Alert qualified as Component
3137
import FloraWeb.Components.CategoryCard qualified as Component
3238
import FloraWeb.Components.PackageListItem qualified as Component
@@ -73,6 +79,7 @@ components =
7379
, ("category-card", ComponentTitle "Category", ComponentName "CategoryCard", categoryCardExample)
7480
, ("pagination-area", ComponentTitle "Pagination Area", ComponentName "Pagination", paginationExample)
7581
, ("alerts", ComponentTitle "Alerts", ComponentName "Alert", alertsExample)
82+
, ("advisory-preview", ComponentTitle "Advisories", ComponentName "AdvisoryPreviews", packageAdvisoriesExample)
7683
]
7784

7885
-----------------------
@@ -133,9 +140,50 @@ paginationExample = div_ $ do
133140
Component.paginationNav 32 1 (SearchPackages "text")
134141

135142
alertsExample :: FloraHTML
136-
alertsExample = div_ $ do
137-
div_ $ do
138-
h4_ "Info alert"
139-
Component.info "Info alert"
140-
h4_ "Error alert"
141-
Component.exception "Error alert!"
143+
alertsExample = div_ $ div_ $ do
144+
h4_ "Info alert"
145+
Component.info "Info alert"
146+
h4_ "Error alert"
147+
Component.exception "Error alert!"
148+
149+
packageAdvisoriesExample :: FloraHTML
150+
packageAdvisoriesExample = do
151+
let advisoryPreviews =
152+
Vector.fromList
153+
[ PackageAdvisoryPreview
154+
{ hsecId = fromJust $ HsecId.parseHsecId "HSEC-2023-0009"
155+
, summary = "git-annex command injection via malicious SSH hostname"
156+
, fixed = True
157+
, published = read "2023-07-25 13:25:42 UTC"
158+
, cvss = fromRight' $ parseCVSS "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H"
159+
}
160+
, PackageAdvisoryPreview
161+
{ hsecId = fromJust $ HsecId.parseHsecId "HSEC-2023-0010"
162+
, summary = "git-annex private data exfiltration to compromised remote"
163+
, fixed = True
164+
, published = read "2023-07-25 13:25:42 UTC"
165+
, cvss = fromRight' $ parseCVSS "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N"
166+
}
167+
, PackageAdvisoryPreview
168+
{ hsecId = fromJust $ HsecId.parseHsecId "HSEC-2023-0012"
169+
, summary = "git-annex checksum exposure to encrypted special remotes"
170+
, fixed = True
171+
, published = read "2023-07-25 13:25:42 UTC"
172+
, cvss = fromRight' $ parseCVSS "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N"
173+
}
174+
, PackageAdvisoryPreview
175+
{ hsecId = fromJust $ HsecId.parseHsecId "HSEC-2023-0013"
176+
, summary = "git-annex plaintext storage of embedded credentials on encrypted remotes"
177+
, fixed = True
178+
, published = read "2023-07-25 13:25:42 UTC"
179+
, cvss = fromRight' $ parseCVSS "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H"
180+
}
181+
, PackageAdvisoryPreview
182+
{ hsecId = fromJust $ HsecId.parseHsecId "HSEC-2023-0011"
183+
, summary = "git-annex GPG decryption attack via compromised remote"
184+
, fixed = True
185+
, published = read "2023-07-25 13:25:42 UTC"
186+
, cvss = fromRight' $ parseCVSS "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N"
187+
}
188+
]
189+
ul_ [class_ "advisory-list"] $ Vector.forM_ advisoryPreviews (\preview -> Component.advisoryListRow preview)

0 commit comments

Comments
 (0)