Skip to content

Commit

Permalink
get rid of CSP script-src unsafe-inline
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Dobe committed Jul 1, 2023
1 parent af0d32a commit 7de918d
Show file tree
Hide file tree
Showing 19 changed files with 379 additions and 121 deletions.
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions dev_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@ in another terminal:

### CURRENT WORK

- create github repo
- migrate to Svelte 4 in the frontend to get rid of the `unsafe-inline` CSP

### Stage 1 - essentials

[x] finished

### Stage 2 - features - do before v1.0.0

- migrate to Svelte 4 in the frontend to get rid of the `unsafe-inline` CSP
- add more documentation
- check why DB migration returned an error inside OCI Pods only (and nowhere else)
- cleanup
Expand Down
52 changes: 29 additions & 23 deletions frontend/build.sh
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
#!/bin/bash

npm run build
rm -rf ../static/v1/*
rm -rf ../templates/html/*

mkdir ../templates/html
mkdir -p ../static/v1
rm -rf ../static/v1/*
rm -rf ../templates/html/*

cp -r build/* ../static/v1/
npm run build

cp build/index.html ../templates/html/index.html
pages=(
"../templates/html/*.html"
"../templates/html/oidc/*.html"
"../templates/html/users/*.html"
"../templates/html/users/{id}/reset/*.html"
)

for file in $(find build -name *.html); do
cp "$file" ../templates/html/
for folder in "${pages[@]}"; do
for html in $folder; do
# for pre-rendering colors
sed -i 's/#6b3d99;/{{ col_act1 }};/g' "$html"
sed -i 's/#714d99;/{{ col_act1a }};/g' "$html"
sed -i 's/#388c51;/{{ col_act2 }};/g' "$html"
sed -i 's/#4d8c62;/{{ col_act2a }};/g' "$html"
sed -i 's/#3d5d99;/{{ col_acnt }};/g' "$html"
sed -i 's/#36486b;/{{ col_acnta }};/g' "$html"
sed -i 's/#43993d;/{{ col_ok }};/g' "$html"
sed -i 's/#993d49;/{{ col_err }};/g' "$html"
sed -i 's/#545454;/{{ col_glow }};/g' "$html"
sed -i 's/#b2b2b2;/{{ col_gmid }};/g' "$html"
sed -i 's/#f2f2f2;/{{ col_ghigh }};/g' "$html"
sed -i 's/#383838;/{{ col_text }};/g' "$html"
sed -i 's/#f7f7f7;/{{ col_bg }};/g' "$html"
# for the nonce in the CSP for script files
sed -i 's/<link /<link nonce="{{ nonce }}" /g' "$html"
sed -i 's/<script>/<script nonce="{{ nonce }}">/g' "$html"
done;
done

for html in ../templates/html/*; do
sed -i 's/#6b3d99;/{{ col_act1 }};/g' "$html"
sed -i 's/#714d99;/{{ col_act1a }};/g' "$html"
sed -i 's/#388c51;/{{ col_act2 }};/g' "$html"
sed -i 's/#4d8c62;/{{ col_act2a }};/g' "$html"
sed -i 's/#3d5d99;/{{ col_acnt }};/g' "$html"
sed -i 's/#36486b;/{{ col_acnta }};/g' "$html"
sed -i 's/#43993d;/{{ col_ok }};/g' "$html"
sed -i 's/#993d49;/{{ col_err }};/g' "$html"
sed -i 's/#545454;/{{ col_glow }};/g' "$html"
sed -i 's/#b2b2b2;/{{ col_gmid }};/g' "$html"
sed -i 's/#f2f2f2;/{{ col_ghigh }};/g' "$html"
sed -i 's/#383838;/{{ col_text }};/g' "$html"
sed -i 's/#f7f7f7;/{{ col_bg }};/g' "$html"
done;
2 changes: 1 addition & 1 deletion frontend/src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="utf-8"/>
<link rel="icon" href="%sveltekit.assets%/assets/favicon.svg"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<style>
<style nonce="{{ nonce }}">
* { box-sizing: border-box; }
:root {
--col-act1: #6b3d99;
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/routes/admin/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
Please navigate to your <b>account</b> and activate MFA.<br>
Afterwards, you need to do a logout and log back in.
</div>
<Button on:click={() => window.location.href = '/auth/v1/account.html'}>ACCOUNT</Button>
<Button on:click={() => window.location.href = '/auth/v1/account'}>ACCOUNT</Button>
<!-- <Button on:click={() => window.location.href = '/auth/v1/account.html'}>ACCOUNT</Button>-->
</div>
{:else if !isAdmin}
<div class="noAdmin">
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/routes/index/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
});
function redirectToAdmin() {
window.location.href = '/auth/v1/admin.html';
window.location.href = '/auth/v1/admin';
// window.location.href = '/auth/v1/admin.html';
}
function redirectToAccount() {
window.location.href = '/auth/v1/account.html';
window.location.href = '/auth/v1/account';
// window.location.href = '/auth/v1/account.html';
}
function redirectToReg() {
Expand Down
12 changes: 3 additions & 9 deletions frontend/src/routes/oidc/logout/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,11 @@
}
async function handleRes(res) {
purgeStorage();
if (res.ok) {
purgeStorage();
window.location.href = postLogoutUri;
} else {
const body = await res.json();
err = body.message;
isLoading = false;
await handleCancel();
}
}
Expand All @@ -60,10 +58,6 @@
<title>Logout</title>
</svelte:head>

{#if isLoading}
<Loading/>
{/if}

<div class="container">
<h1>Logout</h1>

Expand All @@ -72,7 +66,7 @@
</div>

<div class="btn">
<Button on:click={handleLogout} level={2}>LOGOUT</Button>
<Button on:click={handleLogout} level={2} bind:isLoading>LOGOUT</Button>
<Button on:click={handleCancel} level={4}>CANCEL</Button>
</div>

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/routes/users/register/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
let err = '';
let success = false;
let formValues = {};
let formValues = { email: '', givenName: '', familyName: '' };
let formErrors = {};
const schema = yup.object().shape({
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/utils/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ export const ID_TOKEN = 'id_token';
export const AUTH_ENDPOINT = '/auth/v1/oidc/authorize';
export const CLIENT_ID = 'rauthy';
export const LOGOUT_URL = '/auth/v1/oidc/logout';
export const REDIRECT_URI = '/auth/v1/oidc/callback.html';
export const REDIRECT_URI_SUCCESS = '/auth/v1/admin.html';
export const REDIRECT_URI_SUCCESS_ACC = '/auth/v1/account.html';
export const POST_LOGOUT_REDIRECT_URI = '/auth/v1/index.html';
export const REDIRECT_URI = '/auth/v1/oidc/callback';
export const REDIRECT_URI_SUCCESS = '/auth/v1/admin';
export const REDIRECT_URI_SUCCESS_ACC = '/auth/v1/account';
export const POST_LOGOUT_REDIRECT_URI = '/auth/v1/';

export const REGEX_LOWERCASE = /^[a-z0-9-_/]{2,128}$/gm;
export const REGEX_NAME = /^[\w\sÀ-ÿ\-]{0,32}$/gm;
Expand Down
6 changes: 4 additions & 2 deletions frontend/svelte.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ const config = {
},
adapter: adapter({
fallback: null,
pages: 'build',
assets: 'build',
pages: '../templates/html',
// pages: 'build',
assets: '../static/v1',
// assets: 'build',
precompress: false,
strict: true,
})
Expand Down
46 changes: 38 additions & 8 deletions rauthy-handlers/src/generic.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::build_csp_header;
use actix_web::http::header;
use actix_web::http::header::HeaderValue;
use actix_web::{get, post, put, web, HttpRequest, HttpResponse, Responder};
use actix_web_grants::proc_macro::{has_any_permission, has_permissions, has_roles};
use rauthy_common::constants::{CACHE_NAME_LOGIN_DELAY, HEADER_HTML, IDX_LOGIN_TIME};
use rauthy_common::error_response::{ErrorResponse, ErrorResponseType};
use rauthy_models::app_state::AppState;
use rauthy_models::entity::colors::Colors;
use rauthy_models::entity::colors::ColorEntity;
use rauthy_models::entity::password::{PasswordHashTimes, PasswordPolicy};
use rauthy_models::entity::pow::Pow;
use rauthy_models::entity::principal::Principal;
Expand All @@ -17,16 +18,45 @@ use rauthy_models::response::{
Argon2ParamsResponse, EncKeysResponse, HealthResponse, LoginTimeResponse,
PasswordPolicyResponse,
};
use rauthy_models::templates::IndexHtml;
use rauthy_models::templates::{AccountHtml, AdminHtml, IndexHtml};
use rauthy_service::encryption;
use redhac::{cache_get, cache_get_from, cache_get_value};

#[get("/index.html")]
#[get("/")]
// #[get("/index.html")]
#[has_permissions("all")]
pub async fn get_index(data: web::Data<AppState>) -> Result<HttpResponse, ErrorResponse> {
let colors = ColorEntity::find_rauthy(&data).await?;
let (body, nonce) = IndexHtml::build(&colors);

Ok(HttpResponse::Ok()
.insert_header(HEADER_HTML)
.insert_header(build_csp_header(&nonce))
.body(body))
}

#[get("/account")]
#[has_permissions("all")]
pub async fn get_index() -> HttpResponse {
HttpResponse::Ok()
pub async fn get_account_html(data: web::Data<AppState>) -> Result<HttpResponse, ErrorResponse> {
let colors = ColorEntity::find_rauthy(&data).await?;
let (body, nonce) = AccountHtml::build(&colors);

Ok(HttpResponse::Ok()
.insert_header(HEADER_HTML)
.insert_header(build_csp_header(&nonce))
.body(body))
}

#[get("/admin")]
#[has_permissions("all")]
pub async fn get_admin_html(data: web::Data<AppState>) -> Result<HttpResponse, ErrorResponse> {
let colors = ColorEntity::find_rauthy(&data).await?;
let (body, nonce) = AdminHtml::build(&colors);

Ok(HttpResponse::Ok()
.insert_header(HEADER_HTML)
.body(IndexHtml::build(&Colors::default()))
.insert_header(build_csp_header(&nonce))
.body(body))
}

/// Check if the given JWT Token is valid
Expand Down Expand Up @@ -376,7 +406,7 @@ pub async fn redirect() -> impl Responder {
HttpResponse::MovedPermanently()
.insert_header((
header::LOCATION,
HeaderValue::from_str("/auth/v1/index.html").unwrap(),
HeaderValue::from_str("/auth/v1/").unwrap(),
))
.finish()
}
Expand All @@ -385,7 +415,7 @@ pub async fn redirect() -> impl Responder {
#[has_permissions("all")]
pub async fn redirect_v1() -> HttpResponse {
HttpResponse::MovedPermanently()
.insert_header(("location", "/auth/v1/index.html"))
.insert_header(("location", "/auth/v1/"))
.finish()
}

Expand Down
16 changes: 16 additions & 0 deletions rauthy-handlers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,19 @@ fn add_req_mfa_cookie(

Ok(())
}

pub fn build_csp_header(nonce: &str) -> (&str, String) {
// Note: The unsafe-inline for the style-src currently has an open issue on the svelte repo.
// As soon as this is fixed, we can get rid of it.
// let value = format!(
// "default-src 'self'; script-src 'self' 'nonce-{}'; style-src 'self' 'nonce-{}'; \
// frame-ancestors 'self'; object-src 'none'; img-src 'self' data:;",
// nonce, nonce
// );
let value = format!(
"default-src 'self'; script-src 'self' 'nonce-{}'; style-src 'self' 'unsafe-inline'; \
frame-ancestors 'self'; object-src 'none'; img-src 'self' data:;",
nonce,
);
("content-security-policy", value)
}
Loading

0 comments on commit 7de918d

Please sign in to comment.