mirror of
https://github.com/sasjs/server.git
synced 2026-01-16 10:20:05 +00:00
chore: helmet config cleanup
This commit is contained in:
11
README.md
11
README.md
@@ -64,15 +64,18 @@ PROTOCOL=
|
|||||||
# default: 5000
|
# default: 5000
|
||||||
PORT=
|
PORT=
|
||||||
|
|
||||||
|
|
||||||
# optional
|
# optional
|
||||||
# for MODE: `desktop`, prompts user
|
# for MODE: `desktop`, prompts user
|
||||||
# for MODE: `server` gets value from api/package.json `configuration.sasPath`
|
# for MODE: `server` gets value from api/package.json `configuration.sasPath`
|
||||||
SAS_PATH=/path/to/sas/executable.exe
|
SAS_PATH=/path/to/sas/executable.exe
|
||||||
|
|
||||||
# optional
|
# optional HELMET config
|
||||||
# When `true` it will disable strict Content Security Policy
|
# crossOriginEmbedderPolicy flag that will be passed in HELMET config
|
||||||
CSP_DISABLE=true
|
HELMET_COEP=
|
||||||
|
|
||||||
|
# optional HELMET config
|
||||||
|
# path to json file that will include HELMET `contentSecurityPolicy` directives
|
||||||
|
HELMET_CSP_CONFIG_PATH=./csp.config.json
|
||||||
|
|
||||||
# optional
|
# optional
|
||||||
# for MODE: `desktop`, prompts user
|
# for MODE: `desktop`, prompts user
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ FULL_CHAIN=fullchain.pem
|
|||||||
|
|
||||||
PORT=[5000] default value is 5000
|
PORT=[5000] default value is 5000
|
||||||
|
|
||||||
|
HELMET_CSP_CONFIG_PATH=./csp.config.json if omitted HELMET default will be used
|
||||||
|
HELMET_COEP=[true|false] if omitted HELMET default will be used
|
||||||
|
|
||||||
ACCESS_TOKEN_SECRET=<secret>
|
ACCESS_TOKEN_SECRET=<secret>
|
||||||
REFRESH_TOKEN_SECRET=<secret>
|
REFRESH_TOKEN_SECRET=<secret>
|
||||||
AUTH_CODE_SECRET=<secret>
|
AUTH_CODE_SECRET=<secret>
|
||||||
|
|||||||
5
api/csp.config.example.json
Normal file
5
api/csp.config.example.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"img-src": ["'self'", "domen.com"],
|
||||||
|
"script-src": ["'self'", "'unsafe-inline'"],
|
||||||
|
"script-src-attr": ["'self'", "'unsafe-inline'"]
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
setProcessVariables,
|
setProcessVariables,
|
||||||
setupFolders
|
setupFolders
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
import { getEnvCSPDirectives } from './utils/parseHelmetConfig'
|
||||||
|
|
||||||
dotenv.config()
|
dotenv.config()
|
||||||
|
|
||||||
@@ -25,7 +26,8 @@ const app = express()
|
|||||||
app.use(cookieParser())
|
app.use(cookieParser())
|
||||||
app.use(morgan('tiny'))
|
app.use(morgan('tiny'))
|
||||||
|
|
||||||
const { MODE, CORS, WHITELIST, PROTOCOL, CSP_DISABLE } = process.env
|
const { MODE, CORS, WHITELIST, PROTOCOL, HELMET_CSP_CONFIG_PATH, HELMET_COEP } =
|
||||||
|
process.env
|
||||||
|
|
||||||
export const cookieOptions = {
|
export const cookieOptions = {
|
||||||
secure: PROTOCOL === 'https',
|
secure: PROTOCOL === 'https',
|
||||||
@@ -33,6 +35,10 @@ export const cookieOptions = {
|
|||||||
maxAge: 24 * 60 * 60 * 1000 // 24 hours
|
maxAge: 24 * 60 * 60 * 1000 // 24 hours
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cspConfigJson = getEnvCSPDirectives(HELMET_CSP_CONFIG_PATH)
|
||||||
|
const coepFlag =
|
||||||
|
HELMET_COEP === 'true' || HELMET_COEP === undefined ? true : false
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
* CSRF Protection *
|
* CSRF Protection *
|
||||||
***********************************/
|
***********************************/
|
||||||
@@ -41,18 +47,17 @@ export const csrfProtection = csrf({ cookie: cookieOptions })
|
|||||||
/***********************************
|
/***********************************
|
||||||
* Handle security and origin *
|
* Handle security and origin *
|
||||||
***********************************/
|
***********************************/
|
||||||
if (CSP_DISABLE !== 'true') {
|
app.use(
|
||||||
app.use(
|
helmet({
|
||||||
helmet({
|
contentSecurityPolicy: {
|
||||||
contentSecurityPolicy: {
|
directives: {
|
||||||
directives: {
|
...helmet.contentSecurityPolicy.getDefaultDirectives(),
|
||||||
...helmet.contentSecurityPolicy.getDefaultDirectives(),
|
...cspConfigJson
|
||||||
'script-src': ["'self'", "'unsafe-inline'"]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
)
|
crossOriginEmbedderPolicy: coepFlag
|
||||||
}
|
})
|
||||||
|
)
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
* Enabling CORS *
|
* Enabling CORS *
|
||||||
|
|||||||
33
api/src/utils/parseHelmetConfig.ts
Normal file
33
api/src/utils/parseHelmetConfig.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import path from 'path'
|
||||||
|
import fs from 'fs'
|
||||||
|
|
||||||
|
export const getEnvCSPDirectives = (
|
||||||
|
HELMET_CSP_CONFIG_PATH: string | undefined
|
||||||
|
) => {
|
||||||
|
let cspConfigJson = {
|
||||||
|
'script-src': ["'self'", "'unsafe-inline'"]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof HELMET_CSP_CONFIG_PATH === 'string' &&
|
||||||
|
HELMET_CSP_CONFIG_PATH.length > 0
|
||||||
|
) {
|
||||||
|
const cspConfigPath = path.join(process.cwd(), HELMET_CSP_CONFIG_PATH)
|
||||||
|
|
||||||
|
try {
|
||||||
|
let file = fs.readFileSync(cspConfigPath).toString()
|
||||||
|
|
||||||
|
try {
|
||||||
|
cspConfigJson = JSON.parse(file)
|
||||||
|
} catch (e) {
|
||||||
|
console.error(
|
||||||
|
'Parsing Content Security Policy JSON config failed. Make sure it is valid json'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Error reading HELMET CSP config file', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cspConfigJson
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user