Skip to content

Commit

Permalink
Merge pull request #46 from MadWorldNL/Feature/45-security-headers
Browse files Browse the repository at this point in the history
Feature: Add Security headers like CSP
  • Loading branch information
oveldman authored Aug 7, 2024
2 parents ac1b378 + 1745f99 commit 8ddfc6d
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 17 deletions.
8 changes: 7 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -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.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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*
Expand Down
35 changes: 21 additions & 14 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -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.
38 changes: 38 additions & 0 deletions deployment/MantaRayPlanCloud/templates/admin-web.yaml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down Expand Up @@ -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
Expand Down
38 changes: 38 additions & 0 deletions deployment/MantaRayPlanCloud/templates/viewer-web.yaml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions docs/kubernetes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```

Expand Down
13 changes: 13 additions & 0 deletions src/Clients.Admin.Bff/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
13 changes: 13 additions & 0 deletions src/Clients.Viewer.Bff/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 8ddfc6d

Please sign in to comment.