Skip to content

Commit

Permalink
Merge pull request #3731 from mercedes-benz/develop
Browse files Browse the repository at this point in the history
Merge `develop` into `master` for wrapper release
  • Loading branch information
sven-dmlr authored Dec 13, 2024
2 parents f36b43b + 9666850 commit 4216f3c
Show file tree
Hide file tree
Showing 40 changed files with 645 additions and 283 deletions.
27 changes: 27 additions & 0 deletions sechub-pds-solutions/owaspzap/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,33 @@ Furthermore, the combination of OWASP ZAP and PDS make it possible to run both i

This folder contains the necessary scripts to run OWASP ZAP+PDS inside a container locally. Additionally, it contains scripts to build and push the OWASP ZAP+PDS container to your container registry and a Helm chart to install and run OWASP ZAP+PDS in a Kubernetes cluster.

== Script authentication using templates and assets
This PDS solution supports templates for web scan login.

With templates it is very easy to handle complex authentication scenarios (e.g. a corporate MFA login). Please read the [technical documentation](https://mercedes-benz.github.io/sechub/latest/sechub-techdoc.html) for details about templates and assets.

TIP: Templates are not mandatory. If you only need Basic Auth or custom headers template definitions and usage are not necessary.

To start a scan this pds-solution executes the script link:docker/scripts/owasp-zap.sh[owasp-zap.sh].
SecHub will automatically create the directory `$PDS_JOB_EXTRACTED_ASSETS_FOLDER`. The shell script requires a file called `script.groovy` inside the directory for script authentication with templates and assets to work. This script performs the authentication steps necessary for the targeted application.
When creating a template with an asset for webscan authentication and assigning it to a SecHub project, ensure that

- `PDS_OWASP_ZAP.zip` is available as asset file inside the used asset
- `PDS_OWASP_ZAP.zip` contains `script.groovy` at root level

The PDS will extract the file at runtime to `$PDS_JOB_EXTRACTED_ASSETS_FOLDER/webscan-login/script.groovy`.
If the extracted file exists by the time the script `owasp-zap.sh` is executed, the groovy script will be used for automated login.
Details about the configuration of the wrapper application that is used to configure the ZAP, can be found at link:https://github.com/mercedes-benz/sechub/blob/develop/sechub-wrapper-owasp-zap/README.adoc[https://github.com/mercedes-benz/sechub/blob/develop/sechub-wrapper-owasp-zap/README.adoc].

=== Script authentication template data variables
For a webscan script authentication with this pds-solution, template data with the following variables are required:

- `username`
- `password`

These variables are used for the credential data of the scan user. The `username` can be used for any type of user identification like email address, user ID, user name etc.
If TOTP is required make sure to use the dedicated entry inside the webscan authentication section of the sechub configuration JSON.

== Run Locally

This is the easiest way to get started.
Expand Down
9 changes: 9 additions & 0 deletions sechub-pds-solutions/owaspzap/docker/scripts/owasp-zap.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/bin/bash
# SPDX-License-Identifier: MIT

target_script_file="$PDS_JOB_EXTRACTED_ASSETS_FOLDER/webscan-login/script.groovy"

shutdownZAP() {
# --full: to specify the process by looking at full command line including the parameters
pkill -9 --full "/pds/tools/ZAP_"
Expand Down Expand Up @@ -121,6 +123,13 @@ else
echo "Use default value of wrapper for WRAPPER_RETRY_WAITTIME_MILLISECONDS"
fi

if [ -f "$target_script_file" ] ; then
export ZAP_GROOVY_LOGIN_SCRIPT_FILE="$target_script_file"
echo "Use script login file: $ZAP_GROOVY_LOGIN_SCRIPT_FILE"
else
echo "No script login file was found"
fi

echo ""
echo "Start scanning"
echo ""
Expand Down
2 changes: 1 addition & 1 deletion sechub-pds-solutions/owaspzap/env
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
BASE_IMAGE="ghcr.io/mercedes-benz/sechub/pds-base"

# See: https://github.com/mercedes-benz/sechub/releases/
OWASPZAP_WRAPPER_VERSION="1.6.0"
OWASPZAP_WRAPPER_VERSION="1.7.0"
# See: https://github.com/zaproxy/zaproxy/releases/latest
OWASPZAP_VERSION="2.15.0"
OWASPZAP_SHA256SUM="6410e196baab458a9204e29aafb5745fca003a2a6c0386f2c6e5c04b67621fa7"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ protected Customizer<AuthorizeHttpRequestsConfigurer<HttpSecurity>.Authorization
.requestMatchers(APIConstants.API_USER + "**").hasAnyRole(RoleConstants.ROLE_USER, RoleConstants.ROLE_SUPERADMIN)
.requestMatchers(APIConstants.API_PROJECT + "**").hasAnyRole(RoleConstants.ROLE_USER, RoleConstants.ROLE_SUPERADMIN)
.requestMatchers(APIConstants.API_OWNER + "**").hasAnyRole(RoleConstants.ROLE_OWNER, RoleConstants.ROLE_SUPERADMIN)
.requestMatchers(APIConstants.API_PROJECTS).hasAnyRole(RoleConstants.ROLE_USER, RoleConstants.ROLE_SUPERADMIN, RoleConstants.ROLE_OWNER)
.requestMatchers(APIConstants.API_ANONYMOUS + "**").permitAll()
.requestMatchers(APIConstants.ERROR_PAGE).permitAll()
.requestMatchers(APIConstants.ACTUATOR + "**").permitAll()
Expand Down
2 changes: 1 addition & 1 deletion sechub-solution/helm/sechub-server/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ type: application
# This is the chart version.
# This version number should be incremented each time you make changes to the chart and its templates.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 2.3.0
version: 2.4.0
16 changes: 16 additions & 0 deletions sechub-solution/helm/sechub-server/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,22 @@ spec:
- name: SERVER_TOMCAT_ACCESSLOG_PATTERN
value: "{{ .Values.server.spring.embeddedTomcat.logging.accessLogFormat }}"
{{- end }}
{{- if .Values.oauth2.enabled }}
# ----------------------------------------------------------------------------------------------#
# - Scope: Oauth2
# --------------------------------------------------------------------------------------------- #
# See https://mercedes-benz.github.io/sechub/latest/sechub-operations.html#section-general-configuration
- name: SECHUB_SECURITY_OAUTH2_MODE
value: "{{ .Values.oauth2.mode }}"
- name: SECHUB_SECURITY_OAUTH2_JWK_SET_URI
value: "{{ .Values.oauth2.jwt.uri }}"
- name: SECHUB_SECURITY_OAUTH2_OPAQUE_TOKEN_CLIENT_ID
value: "{{ .Values.oauth2.opaque_token.client_id }}"
- name: SECHUB_SECURITY_OAUTH2_OPAQUE_TOKEN_CLIENT_SECRET
value: "{{ .Values.oauth2.opaque_token.client_secret }}"
- name: SECHUB_SECURITY_OAUTH2_OPAQUE_TOKEN_INTROSPECTION_URI
value: "{{ .Values.oauth2.opaque_token.introspection_uri }}"
{{- end }}
# ----------------------------------------------------------------------------------------------#
# - Scope: storage
# --------------------------------------------------------------------------------------------- #
Expand Down
14 changes: 14 additions & 0 deletions sechub-solution/helm/sechub-server/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,20 @@ go_mmproxy:
# Choose a "go-mmproxy" docker image. See e.g. https://hub.docker.com/search?q=go-mmproxy
image: "example.org/go-mmproxy:2.1.0"

oauth2:
# Enable Oauth2 authentication
# Explanation of the modes and parameters: Search for 'oauth2' in documentation
# https://mercedes-benz.github.io/sechub/latest/sechub-operations.html#section-general-configuration
enabled: false
# Choose either 'JWT' or 'OPAQUE_TOKEN'
mode: JWT
jwt:
uri: https://sso.example.org/JWKS
opaque_token:
client_id: insert_your_client_id_here
client_secret: insert_your_client_secret_here
introspection_uri: https://sso.example.org/introspect.oauth2

storage:
local:
# No shared storage - only for standalone SecHub server (stores into local /tmp)
Expand Down
1 change: 1 addition & 0 deletions sechub-web-ui-solution/docker/Web-UI-Debian.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ COPY nginx/ /etc/nginx/
# Copy content to web server's document root
COPY --from=builder "${WEB_UI_ARTIFACTS}/dist" "${HTDOCS_FOLDER}"
COPY htdocs/ "${HTDOCS_FOLDER}/"
COPY nginx/config.json "${HTDOCS_FOLDER}/"

# Create self-signed certificate
RUN cd /tmp && \
Expand Down
5 changes: 5 additions & 0 deletions sechub-web-ui-solution/docker/nginx/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
// HOST represents the URL of the API client. In this case, it's the URL of the SPA because we proxy API requests to the backend to sidestep any CORS issues.
"HOST": "https://localhost",
"LOCAL_DEV": false
}
5 changes: 5 additions & 0 deletions sechub-web-ui-solution/docker/nginx/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ http {
add_header Content-Type text/plain;
}

# loading environment variables from config.json during runtime
location /config.json {
root /var/www/html;
}

ssl_certificate /etc/nginx/certificates/sechub-web-ui.cert;
ssl_certificate_key /etc/nginx/certificates/sechub-web-ui.key;
ssl_protocols TLSv1.2 TLSv1.3;
Expand Down
2 changes: 2 additions & 0 deletions sechub-web-ui-solution/env
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ WEB_UI_VERSION="0.2.0"
GIT_TAG=""
GIT_BRANCH=""
WEB_UI_SSL_KEYSTORE_ALIAS="undefined"

# Please see docker/nignx/config.json for ENV variables for the SPA itself
10 changes: 10 additions & 0 deletions sechub-web-ui/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This .env file contains the default environment variables
# For local development, create an .env.local file with the desired variable values
# Note: .env.local will be ignored by git
# Local development variables must start with VITE_API
VITE_API_HOST=http://localhost:3000

# Optional variables needed for testing with SecHub Server Basic Auth
VITE_API_LOCAL_DEV=false
VITE_API_USER='example-test-user'
VITE_API_PASSWORD='example-api-token'
40 changes: 30 additions & 10 deletions sechub-web-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ This project is a web application that provides a user interface for the SecHub

### Installation

Install the node version manager (nvm) and use it to install the correct version of Node.js:
Install the node version manager (nvm) and use it to install and use the correct version of Node.js:
You can skip the installation processes if you already have nvm installed and the node version in nvm.

```bash
nvm install
```

```bash
nvm use
Expand All @@ -19,6 +24,14 @@ Install the project dependencies:
npm install
```

### Building openAPI SecHub Client

To generate the SecHub openAPI Client use:

```bash
npm run generate-api-client
```

### Starting the Development Server

To start the development server with hot-reload, run the following command. The server will be accessible at [http://localhost:3000](http://localhost:3000):
Expand All @@ -29,19 +42,26 @@ npm run dev

> Add NODE_OPTIONS='--no-warnings' to suppress the JSON import warnings that happen as part of the Vuetify import mapping. If you are on Node [v21.3.0](https://nodejs.org/en/blog/release/v21.3.0) or higher, you can change this to NODE_OPTIONS='--disable-warning=5401'. If you don't mind the warning, you can remove this from your package.json dev script.
#### Running in Development mode with sechub for testing

1. Start SecHub Integration Test Server (or Docker Server)
2. Configure your `.env.local` file by copying `.env` to `.env.local` and adjusting the variables as needed.
Set `VITE_API_LOCAL_DEV=true`
Set `VITE_API_USER` to your SecHub user
Set `VITE_API_PASSWORD` to your SecHub Api Token
3. Set `VITE_API_HOST` to the URL of your application http://localhost:3000 - this is because of the proxy defined in the Vite dev server to avoid CORS Issues
4. Start the SPA in Development mode (npm run dev)

Happy Testing!

### Building for Production

Set Environment Variables:
Be aware that `npm run build` sets the environment variables at build time.
For deploying runtime ENV please se sechub-web-ui-solution/docker/nginx/conf.json it will override the VITE variables. Be aware that the config.json will be served by nginx.

To build your project for production, use:

```bash
npm run build
```

### Building openAPI SecHub Client

To generate the SecHub openAPI Client use:

```bash
npm run codegen
```

76 changes: 46 additions & 30 deletions sechub-web-ui/src/components/Projects.vue
Original file line number Diff line number Diff line change
@@ -1,37 +1,36 @@
<!-- SPDX-License-Identifier: MIT -->
<template>
<v-card
class="mr-auto"
color="background_paper"
width="70%"
>
<v-toolbar
color="background_paper"
width="70%"
>
<v-card class="mr-auto" color="background_paper" width="70%">
<v-toolbar color="background_paper" width="70%">
<v-toolbar-title>{{ $t('PROJECTS') }}</v-toolbar-title>
</v-toolbar>

<v-list
bg-color="background_paper"
lines="two"
>
<!-- Case when the user is not assigned to any project -->
<div v-if="projects.length === 0 && !loading">
<v-list bg-color="background_paper" lines="two">
<v-list-item v-if="error" class="ma-5" rounded="lg">{{ $t('ERROR_FETCHING_DATA') }}</v-list-item>
<v-list-item v-else class="ma-5" rounded="lg">{{ $t('NO_PROJECTS_ASSIGNED') }}</v-list-item>
</v-list>
</div>

<!-- Iterate over the projects array -->
<v-list v-else bg-color="background_paper" lines="two">
<v-list-item
v-for="(item, i) in items"
v-for="(project, i) in projects"
:key="i"
background="red"
class="ma-5"
rounded="lg"
:value="item"
:value="project"
>
<template #prepend>
<v-icon :class="getIconClass(item)" :icon="item.icon" />
<v-icon v-if="project.isOwned" :class="ownedClass" icon="mdi-cube" />
<v-icon v-else icon="mdi-cube" />
</template>
<template #title>
<span>{{ item.text }}</span>
<span>{{ project.projectId }}</span>
</template>
<template #subtitle>
<span v-if="item.owned">({{ $t('OWNED') }})</span>
<span v-if="project.isOwned">({{ $t('OWNED') }})</span>
<span v-else>({{ $t('MEMBER') }})</span>
</template>
</v-list-item>
Expand All @@ -40,18 +39,35 @@
</template>

<script>
import defaultClient from '@/services/defaultClient'

export default {
data: () => ({
items: [
{ text: 'Project 1', icon: 'mdi-cube', owned: true },
{ text: 'Project 2', icon: 'mdi-cube', owned: false },
{ text: 'Project 3', icon: 'mdi-cube', owned: true },
],
}),
methods: {
getIconClass (item) {
return item.owned ? 'project-owned' : ''
},
name: 'ProjectsComponent',

setup () {
const projects = ref([])
const loading = ref(true)
const error = ref(null)

onMounted(async () => {
try {
projects.value = await defaultClient.withProjectApi.getAssignedProjectDataList()
} catch (err) {
error.value = 'ProjectAPI error fetching assigned projects.'
console.error('ProjectAPI error fetching assigned projects:', err)
} finally {
loading.value = false
}
})

return {
ownedClass: {
'project-owned': true,
},
projects,
loading,
error,
}
},
}
</script>
Expand Down
27 changes: 25 additions & 2 deletions sechub-web-ui/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,27 @@
// SPDX-License-Identifier: MIT
export const CONFIG = {
HOST: String(import.meta.env.SECHUB_HOST) || '',

import { ref } from 'vue'

const config = ref({
// New ENV must be defined in global.d.ts
HOST: String(import.meta.env.VITE_API_HOST) || '',
USERNAME: String(import.meta.env.VITE_API_USER) || '',
PASSWORD: String(import.meta.env.VITE_API_PASSWORD) || '',
LOCAL_DEV: String(import.meta.env.VITE_API_LOCAL_DEV) || '',
})

// Overrides local environment variables after project compilation
// Utilizes variables from config.json if available
export async function loadConfig () {
try {
const response = await fetch('/config.json')
const runtimeConfig = await response.json()
config.value = { ...config.value, ...runtimeConfig }
} catch (error) {
console.error('Failed to load configuration, using fallback in .env:', error)
}
}

export function useConfig () {
return config
}
4 changes: 3 additions & 1 deletion sechub-web-ui/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
"GREETING": "Welcome",
"PROJECTS": "Projects",
"OWNED": "owned",
"MEMBER": "member"
"MEMBER": "member",
"NO_PROJECTS_ASSIGNED": "You are not assigned to any projects.",
"ERROR_FETCHING_DATA": "Could not load data from Server."
}
9 changes: 6 additions & 3 deletions sechub-web-ui/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@

// Plugins
import { registerPlugins } from '@/plugins'
import { loadConfig } from './config'

// Components
import App from './App.vue'

// Composables
import { createApp } from 'vue'

const app = createApp(App)
loadConfig().then(() => {
const app = createApp(App)

registerPlugins(app)
registerPlugins(app)

app.mount('#app')
app.mount('#app')
})
Loading

0 comments on commit 4216f3c

Please sign in to comment.