🔒 feat: Add Content Security Policy using Helmet middleware (#7377)

* 🔒 feat: Add Content Security Policy using Helmet middleware

* 🔒 feat: Set trust proxy and refine Content Security Policy directives

* 🎨 feat: add `copy-tex` to improve copying KaTeX (#7308)

When selecting equations and using copy paste, uses the correct latex code.

Co-authored-by: Ruben Talstra <RubenTalstra1211@outlook.com>

* 🔃 refactor: `AgentFooter` to conditionally render buttons based on `activePanel` (#7306)

* 🚀 feat: Add `Cloudflare Turnstile` support (#5987)

* 🚀 feat: Add @marsidev/react-turnstile dependency to package.json and package-lock.json

* 🚀 feat: Integrate Cloudflare Turnstile configuration support in AppService and add schema validation

* 🚀 feat: Implemented Cloudflare Turnstile integration in Login and Registration forms

* 🚀 feat: Enhance AppService tests with additional mocks and configuration setups

* 🚀 feat: Comment out outdated config version warning tests in AppService.spec.js

* 🚀 feat: Remove outdated warning tests and add new checks for environment variables and API health

* 🔧 test: Update AppService.spec.js to use expect.anything() for paths validation

* 🔧 test: Refactor AppService.spec.js to streamline mocks and enhance clarity

* 🔧 chore: removed not needed test

* Potential fix for code scanning alert no. 5638: Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting.

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Potential fix for code scanning alert no. 5629: Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting.

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Potential fix for code scanning alert no. 5642: Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting.

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Update turnstile.js

* Potential fix for code scanning alert no. 5634: Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting.

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Potential fix for code scanning alert no. 5646: Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting.

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Potential fix for code scanning alert no. 5647: Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting.

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* 🔒 feat: Refactor Content Security Policy setup to use Helmet middleware with custom directives

* 🔒 feat: Enhance Content Security Policy to include Sandpack Bundler URL

* 🔒 feat: Update Content Security Policy and integrate Turnstile captcha support

---------

Co-authored-by: andresgit <9771158+andresgit@users.noreply.github.com>
Co-authored-by: matt burnett <mawburn@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
This commit is contained in:
Ruben Talstra 2025-05-15 22:25:10 +02:00 committed by GitHub
parent fe311df969
commit 7a91f6ca62
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 93 additions and 60 deletions

View file

@ -2,6 +2,7 @@ require('dotenv').config();
const path = require('path');
require('module-alias')({ base: path.resolve(__dirname, '..') });
const cors = require('cors');
const helmet = require('helmet');
const axios = require('axios');
const express = require('express');
const compression = require('compression');
@ -22,7 +23,15 @@ const staticCache = require('./utils/staticCache');
const noIndex = require('./middleware/noIndex');
const routes = require('./routes');
const { PORT, HOST, ALLOW_SOCIAL_LOGIN, DISABLE_COMPRESSION, TRUST_PROXY } = process.env ?? {};
const {
PORT,
HOST,
ALLOW_SOCIAL_LOGIN,
DISABLE_COMPRESSION,
TRUST_PROXY,
SANDPACK_BUNDLER_URL,
SANDPACK_STATIC_BUNDLER_URL,
} = process.env ?? {};
const port = Number(PORT) || 3080;
const host = HOST || 'localhost';
@ -38,6 +47,8 @@ const startServer = async () => {
const app = express();
app.disable('x-powered-by');
app.set('trust proxy', trusted_proxy);
await AppService(app);
const indexPath = path.join(app.locals.paths.dist, 'index.html');
@ -49,23 +60,54 @@ const startServer = async () => {
app.use(noIndex);
app.use(errorController);
app.use(express.json({ limit: '3mb' }));
app.use(mongoSanitize());
app.use(express.urlencoded({ extended: true, limit: '3mb' }));
app.use(staticCache(app.locals.paths.dist));
app.use(staticCache(app.locals.paths.fonts));
app.use(staticCache(app.locals.paths.assets));
app.set('trust proxy', trusted_proxy);
app.use(mongoSanitize());
app.use(cors());
app.use(cookieParser());
app.use(
helmet({
contentSecurityPolicy: {
useDefaults: false,
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", 'https://challenges.cloudflare.com'],
styleSrc: ["'self'", "'unsafe-inline'"],
fontSrc: ["'self'", 'data:'],
objectSrc: ["'none'"],
imgSrc: ["'self'", 'data:'],
mediaSrc: ["'self'", 'data:', 'blob:'],
connectSrc: ["'self'"],
frameSrc: [
"'self'",
'https://challenges.cloudflare.com',
'https://codesandbox.io',
...(SANDPACK_BUNDLER_URL ? [SANDPACK_BUNDLER_URL] : []),
...(SANDPACK_STATIC_BUNDLER_URL ? [SANDPACK_STATIC_BUNDLER_URL] : []),
],
frameAncestors: [
"'self'",
'https://codesandbox.io',
...(SANDPACK_BUNDLER_URL ? [SANDPACK_BUNDLER_URL] : []),
...(SANDPACK_STATIC_BUNDLER_URL ? [SANDPACK_STATIC_BUNDLER_URL] : []),
],
},
},
}),
);
if (!isEnabled(DISABLE_COMPRESSION)) {
app.use(compression());
} else {
console.warn('Response compression has been disabled via DISABLE_COMPRESSION.');
}
// Serve static assets with aggressive caching
app.use(staticCache(app.locals.paths.dist));
app.use(staticCache(app.locals.paths.fonts));
app.use(staticCache(app.locals.paths.assets));
if (!ALLOW_SOCIAL_LOGIN) {
console.warn(
'Social logins are disabled. Set Environment Variable "ALLOW_SOCIAL_LOGIN" to true to enable them.',
);
console.warn('Social logins are disabled. Set ALLOW_SOCIAL_LOGIN=true to enable them.');
}
/* OAUTH */
@ -128,7 +170,7 @@ const startServer = async () => {
});
app.listen(port, host, () => {
if (host == '0.0.0.0') {
if (host === '0.0.0.0') {
logger.info(
`Server listening on all interfaces at port ${port}. Use http://localhost:${port} to access it`,
);