Skip to content
This repository has been archived by the owner on Jul 23, 2024. It is now read-only.

Run security analysis at each push #489

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ jobs:
distribution: 'temurin'
java-version: '17'

- name: Setup Go environment
uses: actions/[email protected]
with:
go-version: 'stable'

- name: Maven Verify
run: mvn clean verify

Expand All @@ -31,6 +36,10 @@ jobs:
make build-images GIT_BRANCH=${GITHUB_REF##*/}
make tag-images GIT_BRANCH=${GITHUB_REF##*/}

- name: "Security analysis of images"
run: |
make analyse-images stop-local-registry stop-clair

- name: Login to Docker Hub
uses: docker/login-action@v2
with:
Expand Down
28 changes: 28 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,31 @@ jobs:
uses: skjolber/maven-cache-github-action@v1
with:
step: save

security-checks:
runs-on: ubuntu-latest
needs:
- containers
steps:
- uses: actions/checkout@v3

- name: Setup Go environment
uses: actions/[email protected]
with:
go-version: 'stable'

- name: Download images
uses: ishworkh/docker-image-artifact-download@v1
with:
image: "docker-compose_notification-service:latest"

- name: Download images
uses: ishworkh/docker-image-artifact-download@v1
with:
image: "docker-compose_workflow-service:latest"

- name: "Security analysis of images"
run: |
make analyse-images stop-local-registry stop-clair


5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,8 @@ notification-service-sdk/.openapi-generator
##############################
manifests.yaml
hack/manifests/release

##############################
## Security checks
##############################
clair
77 changes: 77 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
DOCKER ?= docker
DOCKER-COMPOSE ?= docker-compose

CLAIR_TMP_DIR := .

TESTDBPASS := parodos
TESTDBNAME := parodos
TESTDBUSER := parodos
Expand Down Expand Up @@ -147,6 +149,81 @@ tag-images: ## Tag docker images with git hash and branch name
$(DOCKER) tag docker-compose_workflow-service:latest $(ORG)$(WORKFLOW_SERVICE_IMAGE):$(GIT_BRANCH)
$(DOCKER) tag docker-compose_notification-service:latest $(ORG)$(NOTIFICATION_SERVICE_IMAGE):$(GIT_BRANCH)

deploy-local-registry:
ifneq ($(shell $(DOCKER) container inspect -f '{{.State.Running}}' registry 2> /dev/null), true)
$(DOCKER) run -d -p 5000:5000 --restart=always --name registry registry:2
endif
$(DOCKER) tag docker-compose_workflow-service:latest localhost:5000/docker-compose_workflow-service:latest
$(DOCKER) tag docker-compose_notification-service:latest localhost:5000/docker-compose_notification-service:latest
$(DOCKER) push localhost:5000/docker-compose_workflow-service:latest
$(DOCKER) push localhost:5000/docker-compose_notification-service:latest

stop-local-registry:
$(DOCKER) stop registry
$(DOCKER) rm registry

deploy-clair: deploy-local-registry
cd $(CLAIR_TMP_DIR) ; git clone https://github.com/quay/clair ; cd clair; $(DOCKER) compose up -d
sleep 15m
@echo "Clair is up and running"

stop-clair:
cd $(CLAIR_TMP_DIR)/clair ; $(DOCKER) compose down

.PHONY: clairctl
CLAIRCTL = $(shell pwd)/bin/clairctl
clairctl: ## Download clairctl locally if necessary.
ifeq (,$(wildcard $(CLAIRCTL)))
ifeq (,$(shell which clairctl 2>/dev/null))
@{ \
go install github.com/quay/clair/v4/cmd/clairctl@latest ;\
}
endif
CLAIRCTL = $(shell which clairctl)
endif

run-images-analysis: clairctl
$(eval BRIDGE=$(shell $(DOCKER) network inspect -f '{{json .IPAM.Config}}' bridge | jq -r .[].Gateway))
$(CLAIRCTL) --config $(CLAIR_TMP_DIR)/clair/local-dev/clair/config.yaml report -o json $(BRIDGE):5000/docker-compose_notification-service:latest | jq .vulnerabilities > $(CLAIR_TMP_DIR)/docker-compose_notification-service_report.json
$(CLAIRCTL) --config $(CLAIR_TMP_DIR)/clair/local-dev/clair/config.yaml report -o json $(BRIDGE):5000/docker-compose_workflow-service:latest | jq .vulnerabilities > $(CLAIR_TMP_DIR)/docker-compose_workflow-service_report.json

.SILENT: analyse-images
analyse-images: deploy-clair run-images-analysis analyse-images-fast
#

.SILENT: analyse-images-fast
analyse-images-fast:
$(eval FIXABLE_CRITICAL_NOTIFICATION?=$(shell cat $(CLAIR_TMP_DIR)/docker-compose_notification-service_report.json | jq '[.[] | select(.normalized_severity=="Critical") | select(.fixed_in_version!="")] | length'))
$(eval FIXABLE_HIGH_NOTIFICATION?=$(shell cat $(CLAIR_TMP_DIR)/docker-compose_notification-service_report.json | jq '[.[] | select(.normalized_severity=="High") | select(.fixed_in_version!="")] | length'))
$(eval FIXABLE_CRITICAL_WORKFLOW?=$(shell cat $(CLAIR_TMP_DIR)/docker-compose_workflow-service_report.json | jq '[.[] | select(.normalized_severity=="Critical") | select(.fixed_in_version!="")] | length'))
$(eval FIXABLE_HIGH_WORKFLOW?=$(shell cat $(CLAIR_TMP_DIR)/docker-compose_workflow-service_report.json | jq '[.[] | select(.normalized_severity=="High") | select(.fixed_in_version!="")] | length'))
$(eval CRITICAL_NOTIFICATION?=$(shell cat $(CLAIR_TMP_DIR)/docker-compose_notification-service_report.json |jq '[.[] | select(.normalized_severity=="Critical")] | length'))
$(eval HIGH_NOTIFICATION?=$(shell cat $(CLAIR_TMP_DIR)/docker-compose_notification-service_report.json | jq '[.[] | select(.normalized_severity=="High")] | length'))
$(eval CRITICAL_WORKFLOW?=$(shell cat $(CLAIR_TMP_DIR)/docker-compose_workflow-service_report.json | jq '[.[] | select(.normalized_severity=="Critical")] | length'))
$(eval HIGH_WORKFLOW?=$(shell cat $(CLAIR_TMP_DIR)/docker-compose_workflow-service_report.json | jq '[.[] | select(.normalized_severity=="High")] | length'))

$(eval FIXABLE_CRITICAL_NOTIFICATION=$(shell [ $(FIXABLE_CRITICAL_NOTIFICATION) > 0 ] && echo "$(FIXABLE_CRITICAL_NOTIFICATION)" || echo "0"))
$(eval FIXABLE_HIGH_NOTIFICATION=$(shell [ $(FIXABLE_HIGH_NOTIFICATION) > 0 ] && echo "$(FIXABLE_HIGH_NOTIFICATION)" || echo "0"))
$(eval FIXABLE_CRITICAL_WORKFLOW=$(shell [ $(FIXABLE_CRITICAL_WORKFLOW) > 0 ] && echo "$(FIXABLE_CRITICAL_WORKFLOW)" || echo "0"))
$(eval FIXABLE_HIGH_WORKFLOW=$(shell [ $(FIXABLE_HIGH_WORKFLOW) > 0 ] && echo "$(FIXABLE_HIGH_WORKFLOW)" || echo "0"))

echo -e "Notification service: \n\t$(CRITICAL_NOTIFICATION) critical issues found; $(FIXABLE_CRITICAL_NOTIFICATION) fixable\n\t$(HIGH_NOTIFICATION) high issues found; $(FIXABLE_HIGH_NOTIFICATION) fixable\n\
Workflow service:\n\t$(CRITICAL_WORKFLOW) critical issues found; $(FIXABLE_CRITICAL_WORKFLOW) fixable\n\t$(HIGH_WORKFLOW) high issues found; $(FIXABLE_HIGH_WORKFLOW) fixable\n"
if [ "${FIXABLE_CRITICAL_NOTIFICATION}" -gt 0 ] ; then \
echo "$(FIXABLE_CRITICAL_NOTIFICATION) fixable critical issues found for notification service" ; \
exit 1 ; \
elif [ "${FIXABLE_CRITICAL_WORKFLOW}" -gt 0 ] ; then \
echo "$(FIXABLE_CRITICAL_WORKFLOW) fixable critical issues found for workflow service" ; \
exit 1 ; \
elif [ "${FIXABLE_HIGH_NOTIFICATION}" -gt 0 ] ; then \
echo "$(FIXABLE_HIGH_NOTIFICATION) fixable high issues found for notification service" ; \
exit 1 ; \
elif [ "${FIXABLE_HIGH_WORKFLOW}" -gt 0 ] ; then \
echo "$(FIXABLE_HIGH_WORKFLOW) fixable high issues found for workflow service" ; \
exit 1 ; \
fi
@echo "Remember to clean $(CLAIR_TMP_DIR)!"

push-images: ## Push docker images to quay.io registry
$(eval TAG?=$(GIT_HASH))
$(DOCKER) push $(ORG)$(WORKFLOW_SERVICE_IMAGE):$(TAG)
Expand Down
1 change: 1 addition & 0 deletions notification-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<!-- END Spring Data Dependencies -->
<!-- START Developer Productivity Dependencies -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

/**
Expand Down Expand Up @@ -64,9 +65,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeHttpRequests(auth ->auth
.requestMatchers(HttpMethod.OPTIONS, "/**")
.requestMatchers(new AntPathRequestMatcher("/**", HttpMethod.OPTIONS.name()))
.permitAll()
.requestMatchers("/api/**")
.requestMatchers(new AntPathRequestMatcher("/api/**"))
.fullyAuthenticated()
.anyRequest().permitAll())
.httpBasic(Customizer.withDefaults())
Expand Down
3 changes: 2 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
<maven.plugins.gpg.version>1.5</maven.plugins.gpg.version>
<maven.plugin.source>3.2.1</maven.plugin.source>
<maven.plugin.enforcer.version>3.3.0</maven.plugin.enforcer.version>
<springframework.boot.version>3.1.0</springframework.boot.version>
<springframework.boot.version>3.1.2</springframework.boot.version>
<spring.javaformat.version>0.0.34</spring.javaformat.version>
<junit.version>5.10.0</junit.version>
<hamcrest.version>2.2</hamcrest.version>
Expand All @@ -68,6 +68,7 @@
<spring-cloud.version>2022.0.3</spring-cloud.version>
<gson-fire-version>1.8.5</gson-fire-version>
<snakeyaml-version>2.0</snakeyaml-version>
<h2.version>2.2.220</h2.version>
</properties>
<modules>
<module>workflow-engine</module>
Expand Down
17 changes: 17 additions & 0 deletions workflow-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,22 @@
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-archiver</artifactId>
<version>4.8.0</version>
</dependency>

<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
Expand All @@ -97,6 +113,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

/**
Expand Down Expand Up @@ -70,12 +71,14 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth ->
auth
.requestMatchers(HttpMethod.OPTIONS, "/**")
.requestMatchers(new AntPathRequestMatcher("/**", HttpMethod.OPTIONS.name()))
.permitAll()
.requestMatchers("/api/**", "/actuator/shutdown")
.requestMatchers(new AntPathRequestMatcher("/api/**"))
.fullyAuthenticated()
.requestMatchers(new AntPathRequestMatcher("/actuator/shutdown"))
.fullyAuthenticated()
.anyRequest().permitAll())
.httpBasic(Customizer.withDefaults())
.httpBasic(Customizer.withDefaults())
.headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
.formLogin(form -> form.loginProcessingUrl("/login"))
.logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer
Expand Down
Loading