diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7ea2a93..aea697a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1 +1,7 @@ -*TODO* +# Contributing +We welcome contributions to this repository. + +Before you start coding, please create an issue. This way, we can discuss the changes before you start coding. + +After you made your changes, please create a pull request. We will review it and merge it if it fits the project. +Please explain your changes in the pull request. diff --git a/README.md b/README.md index cdc0af5..64abe62 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,10 @@ # MantaRayPlan MantaRayPlan is a scheduling application that allows you to share your agenda with friends and family. -Designed for multiple users, this application is available on multiple platforms, making it easier to plan together. -Currently, MantaRayPlan is in the setup phase and is not yet usable. +Designed for multiple users, this application is available on multiple platforms, making it easier to plan together. + +> [!WARNING] +> Currently, MantaRayPlan is in the setup phase and is not yet usable. ## Key Features *TODO* diff --git a/SECURITY.md b/SECURITY.md index 8cdd02e..55454e0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,22 +1,29 @@ # Security Policy -*TODO* +This document describes the security policy of the project. The security policy is a set of rules and practices that are +used to protect the project from security vulnerabilities. The security policy is used to ensure that the project is secure +and that the project is not vulnerable to attacks. ## Supported Versions +The latest version of browser and operating system is supported. High possibilty that lower version are working well, but not guaranteed. There are not enough resources to test all versions. -Use this section to tell people about which versions of your project are -currently being supported with security updates. +Supported browsers for web applications: -| Version | Supported | -| ------- | ------------------ | -| 5.1.x | :white_check_mark: | -| 5.0.x | :x: | -| 4.0.x | :white_check_mark: | -| < 4.0 | :x: | +| Browser | Version | Supported | +|-------------------|----------------|--------------------| +| Google Chrome | Latest | :white_check_mark: | +| Firefox | Latest | :white_check_mark: | +| Safari | Latest | :white_check_mark: | +| Chromium Browsers | Latest | :white_check_mark: | +| Other | Lower versions | :x: | -## Reporting a Vulnerability +Supported operating systems for native applications: -Use this section to tell people how to report a vulnerability. +| Operating system | Version | Supported | +|------------------|----------------|--------------------| +| Android | Latest | :white_check_mark: | +| iOS | Latest | :white_check_mark: | +| Other | Lower versions | :x: | -Tell them where to go, how often they can expect to get an update on a -reported vulnerability, what to expect if the vulnerability is accepted or -declined, etc. +## Reporting a Vulnerability +You can create an issue in the repository. The issue will be reviewed and a decision will be made on how to proceed. +If the issue is accepted, it will be fixed in the next release. If the issue is rejected, the reason will be explained in the issue. diff --git a/deployment/MantaRayPlanCloud/templates/admin-web.yaml b/deployment/MantaRayPlanCloud/templates/admin-web.yaml index 0088947..49c1712 100644 --- a/deployment/MantaRayPlanCloud/templates/admin-web.yaml +++ b/deployment/MantaRayPlanCloud/templates/admin-web.yaml @@ -1,3 +1,32 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ .Values.admin.web.app }}-nginx-config" + namespace: {{ .Values.namespace }} +data: + default.conf: | + server { + listen 80; + listen [::]:80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + add_header X-Frame-Options "DENY" always; + add_header Referrer-Policy "no-referrer"; + add_header X-Content-Type-Options "nosniff"; + add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=()"; + add_header content-security-policy "default-src 'self' https://{{ .Values.admin.bff.host }}; img-src 'self' data: ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; connect-src 'self' https://{{ .Values.admin.bff.host }}; upgrade-insecure-requests; frame-ancestors 'self'"; + } +--- apiVersion: apps/v1 kind: Deployment metadata: @@ -30,8 +59,17 @@ spec: periodSeconds: 10 timeoutSeconds: 1 failureThreshold: 3 + volumeMounts: + - name: "{{ .Values.admin.web.app }}-nginx-config-volume" + mountPath: /etc/nginx/conf.d/default.conf + subPath: default.conf + readOnly: true ports: - containerPort: 80 + volumes: + - name: "{{ .Values.admin.web.app }}-nginx-config-volume" + configMap: + name: "{{ .Values.admin.web.app }}-nginx-config" --- apiVersion: v1 kind: Service diff --git a/deployment/MantaRayPlanCloud/templates/viewer-web.yaml b/deployment/MantaRayPlanCloud/templates/viewer-web.yaml index c395ead..84c07ad 100644 --- a/deployment/MantaRayPlanCloud/templates/viewer-web.yaml +++ b/deployment/MantaRayPlanCloud/templates/viewer-web.yaml @@ -1,3 +1,32 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ .Values.viewer.web.app }}-nginx-config" + namespace: {{ .Values.namespace }} +data: + default.conf: | + server { + listen 80; + listen [::]:80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + add_header X-Frame-Options "DENY" always; + add_header Referrer-Policy "no-referrer"; + add_header X-Content-Type-Options "nosniff"; + add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=()"; + add_header content-security-policy "default-src 'self' https://{{ .Values.viewer.bff.host }}; img-src 'self' data: ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; connect-src 'self' https://{{ .Values.viewer.bff.host }}; upgrade-insecure-requests; frame-ancestors 'self'"; + } +--- apiVersion: apps/v1 kind: Deployment metadata: @@ -30,8 +59,17 @@ spec: periodSeconds: 10 timeoutSeconds: 1 failureThreshold: 3 + volumeMounts: + - name: "{{ .Values.viewer.web.app }}-nginx-config-volume" + mountPath: /etc/nginx/conf.d/default.conf + subPath: default.conf + readOnly: true ports: - containerPort: 80 + volumes: + - name: "{{ .Values.viewer.web.app }}-nginx-config-volume" + configMap: + name: "{{ .Values.viewer.web.app }}-nginx-config" --- apiVersion: v1 kind: Service diff --git a/docs/kubernetes.md b/docs/kubernetes.md index 6949574..a7a82e5 100644 --- a/docs/kubernetes.md +++ b/docs/kubernetes.md @@ -43,6 +43,10 @@ minikube addons enable ingress Convenient tools for debugging Kubernetes: ```shell minikube dashboard +``` + +Open access localhost domains like www.mantarayplan.localhost: +```shell minikube tunnel ``` diff --git a/src/Clients.Admin.Bff/Program.cs b/src/Clients.Admin.Bff/Program.cs index dd61034..8748f93 100644 --- a/src/Clients.Admin.Bff/Program.cs +++ b/src/Clients.Admin.Bff/Program.cs @@ -28,6 +28,19 @@ app.UseRateLimiter(); +// Security Headers +app.Use(async (context, next) => +{ + context.Response.Headers.Remove("Server"); + context.Response.Headers.Remove("X-Powered-By"); + context.Response.Headers.Add("X-Frame-Options", "DENY"); + context.Response.Headers.Add("Referrer-Policy", "no-referrer"); + context.Response.Headers.Add("X-Content-Type-Options", "nosniff"); + context.Response.Headers.Add("Permissions-Policy", "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=()"); + context.Response.Headers.Add("Content-Security-Policy", "default-src 'self'"); + await next(); +}); + var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" diff --git a/src/Clients.Viewer.Bff/Program.cs b/src/Clients.Viewer.Bff/Program.cs index a9f3e84..5684f50 100644 --- a/src/Clients.Viewer.Bff/Program.cs +++ b/src/Clients.Viewer.Bff/Program.cs @@ -28,6 +28,19 @@ app.UseRateLimiter(); +// Security Headers +app.Use(async (context, next) => +{ + context.Response.Headers.Remove("Server"); + context.Response.Headers.Remove("X-Powered-By"); + context.Response.Headers.Add("X-Frame-Options", "DENY"); + context.Response.Headers.Add("Referrer-Policy", "no-referrer"); + context.Response.Headers.Add("X-Content-Type-Options", "nosniff"); + context.Response.Headers.Add("Permissions-Policy", "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=()"); + context.Response.Headers.Add("Content-Security-Policy", "default-src 'self'"); + await next(); +}); + var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"