mirror of
https://github.com/DumbWareio/DumbDrop.git
synced 2025-10-23 07:41:58 +00:00
- Introduced ALLOWED_IFRAME_ORIGINS environment variable to specify trusted origins for iframe embedding. - Updated security headers middleware to conditionally allow specified origins in Content Security Policy. - Enhanced documentation in README.md to explain the new configuration and its security implications. Fixes #35
This commit is contained in:
committed by
GitHub
parent
12ae628bd4
commit
107684fe6a
13
README.md
13
README.md
@@ -123,6 +123,19 @@ docker run -p 3000:3000 -v "${PWD}\local_uploads:/app/uploads" dumbwareio/dumbdr
|
|||||||
| APPRISE_SIZE_UNIT| Size unit for notifications | Auto | No |
|
| APPRISE_SIZE_UNIT| Size unit for notifications | Auto | No |
|
||||||
| AUTO_UPLOAD | Enable automatic upload on file selection | false | No |
|
| AUTO_UPLOAD | Enable automatic upload on file selection | false | No |
|
||||||
| ALLOWED_EXTENSIONS| Comma-separated list of allowed file extensions | None | No |
|
| ALLOWED_EXTENSIONS| Comma-separated list of allowed file extensions | None | No |
|
||||||
|
| ALLOWED_IFRAME_ORIGINS | Comma-separated list of origins allowed to embed the app in an iframe (e.g. https://organizr.example.com,https://myportal.com) | None | No |
|
||||||
|
|
||||||
|
### ALLOWED_IFRAME_ORIGINS
|
||||||
|
|
||||||
|
To allow this app to be embedded in an iframe on specific origins (such as Organizr), set the `ALLOWED_IFRAME_ORIGINS` environment variable to a comma-separated list of allowed parent origins. Example:
|
||||||
|
|
||||||
|
```env
|
||||||
|
ALLOWED_IFRAME_ORIGINS=https://organizr.example.com,https://myportal.com
|
||||||
|
```
|
||||||
|
|
||||||
|
- If not set, the app will only allow itself to be embedded in an iframe on the same origin (default security).
|
||||||
|
- If set, the app will allow embedding in iframes on the specified origins and itself.
|
||||||
|
- **Security Note:** Only add trusted origins. Allowing arbitrary origins can expose your app to clickjacking and other attacks.
|
||||||
|
|
||||||
### File Extension Filtering
|
### File Extension Filtering
|
||||||
To restrict which file types can be uploaded, set the `ALLOWED_EXTENSIONS` environment variable. For example:
|
To restrict which file types can be uploaded, set the `ALLOWED_EXTENSIONS` environment variable. For example:
|
||||||
|
@@ -66,7 +66,13 @@ const config = {
|
|||||||
// File extensions
|
// File extensions
|
||||||
allowedExtensions: process.env.ALLOWED_EXTENSIONS ?
|
allowedExtensions: process.env.ALLOWED_EXTENSIONS ?
|
||||||
process.env.ALLOWED_EXTENSIONS.split(',').map(ext => ext.trim().toLowerCase()) :
|
process.env.ALLOWED_EXTENSIONS.split(',').map(ext => ext.trim().toLowerCase()) :
|
||||||
null
|
null,
|
||||||
|
|
||||||
|
// Allowed iframe origins (for embedding in iframes)
|
||||||
|
// Comma-separated list of origins, e.g. "https://organizr.example.com,https://dumb.myportal.com"
|
||||||
|
allowedIframeOrigins: process.env.ALLOWED_IFRAME_ORIGINS
|
||||||
|
? process.env.ALLOWED_IFRAME_ORIGINS.split(',').map(origin => origin.trim()).filter(Boolean)
|
||||||
|
: null
|
||||||
};
|
};
|
||||||
|
|
||||||
// Validate required settings
|
// Validate required settings
|
||||||
|
@@ -6,34 +6,39 @@
|
|||||||
|
|
||||||
const { safeCompare } = require('../utils/security');
|
const { safeCompare } = require('../utils/security');
|
||||||
const logger = require('../utils/logger');
|
const logger = require('../utils/logger');
|
||||||
|
const { config } = require('../config');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Security headers middleware
|
* Security headers middleware
|
||||||
*/
|
*/
|
||||||
function securityHeaders(req, res, next) {
|
function securityHeaders(req, res, next) {
|
||||||
// Content Security Policy
|
// Content Security Policy
|
||||||
res.setHeader(
|
let csp =
|
||||||
'Content-Security-Policy',
|
|
||||||
"default-src 'self'; " +
|
"default-src 'self'; " +
|
||||||
"style-src 'self' 'unsafe-inline' cdn.jsdelivr.net; " +
|
"style-src 'self' 'unsafe-inline' cdn.jsdelivr.net; " +
|
||||||
"script-src 'self' 'unsafe-inline' cdn.jsdelivr.net; " +
|
"script-src 'self' 'unsafe-inline' cdn.jsdelivr.net; " +
|
||||||
"img-src 'self' data: blob:;"
|
"img-src 'self' data: blob:;";
|
||||||
);
|
|
||||||
|
// If allowedIframeOrigins is set, allow those origins to embed via iframe
|
||||||
// X-Content-Type-Options
|
if (config.allowedIframeOrigins && config.allowedIframeOrigins.length > 0) {
|
||||||
|
// Remove X-Frame-Options header (do not set it)
|
||||||
|
// Add frame-ancestors directive to CSP
|
||||||
|
const frameAncestors = ["'self'", ...config.allowedIframeOrigins].join(' ');
|
||||||
|
csp += ` frame-ancestors ${frameAncestors};`;
|
||||||
|
} else {
|
||||||
|
// Default: only allow same origin if not configured
|
||||||
|
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setHeader('Content-Security-Policy', csp);
|
||||||
res.setHeader('X-Content-Type-Options', 'nosniff');
|
res.setHeader('X-Content-Type-Options', 'nosniff');
|
||||||
|
|
||||||
// X-Frame-Options
|
|
||||||
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
|
|
||||||
|
|
||||||
// X-XSS-Protection
|
|
||||||
res.setHeader('X-XSS-Protection', '1; mode=block');
|
res.setHeader('X-XSS-Protection', '1; mode=block');
|
||||||
|
|
||||||
// Strict Transport Security (when in production)
|
// Strict Transport Security (when in production)
|
||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === 'production') {
|
||||||
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user