mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-23 18:26:32 -05:00
0093aa4783
The snippet export broke due to two reasons. First of all, the request to GitLab fail in the default configuration due to the CSP not being set properly. This commit adds the configured GitLab base url to the connect-src directives. The second problem is a change in the GitLab API spec. Instead of `code` and `file_name` the GitLab API now requires an `files` array with `content` and `file_path` entries per snippet. Signed-off-by: Erik Michelson <github@erik.michelson.eu>
119 lines
4.1 KiB
JavaScript
119 lines
4.1 KiB
JavaScript
const config = require('./config')
|
|
const { v4: uuidv4 } = require('uuid')
|
|
const { buildDomainOriginWithProtocol } = require('./config/buildDomainOriginWithProtocol')
|
|
|
|
const CspStrategy = {}
|
|
|
|
const defaultDirectives = {
|
|
defaultSrc: ['\'none\''],
|
|
baseUri: ['\'self\''],
|
|
connectSrc: ['\'self\'', buildDomainOriginWithProtocol(config, 'ws')],
|
|
fontSrc: ['\'self\''],
|
|
manifestSrc: ['\'self\''],
|
|
frameSrc: ['\'self\'', 'https://player.vimeo.com', 'https://www.slideshare.net/slideshow/embed_code/key/', 'https://www.youtube.com'],
|
|
imgSrc: ['*'], // we allow using arbitrary images
|
|
scriptSrc: [
|
|
config.serverURL + '/build/',
|
|
config.serverURL + '/js/',
|
|
config.serverURL + '/config',
|
|
'https://gist.github.com/',
|
|
'https://vimeo.com/api/oembed.json',
|
|
'https://www.slideshare.net/api/oembed/2',
|
|
'\'unsafe-inline\'' // this is ignored by browsers supporting nonces/hashes
|
|
],
|
|
styleSrc: [config.serverURL + '/build/', config.serverURL + '/css/', '\'unsafe-inline\'', 'https://github.githubassets.com'], // unsafe-inline is required for some libs, plus used in views
|
|
objectSrc: ['*'], // Chrome PDF viewer treats PDFs as objects :/
|
|
formAction: ['\'self\''],
|
|
mediaSrc: ['*']
|
|
}
|
|
|
|
const disqusDirectives = {
|
|
scriptSrc: ['https://disqus.com', 'https://*.disqus.com', 'https://*.disquscdn.com'],
|
|
styleSrc: ['https://*.disquscdn.com'],
|
|
fontSrc: ['https://*.disquscdn.com']
|
|
}
|
|
|
|
const googleAnalyticsDirectives = {
|
|
scriptSrc: ['https://www.google-analytics.com']
|
|
}
|
|
|
|
const dropboxDirectives = {
|
|
scriptSrc: ['https://www.dropbox.com', '\'unsafe-inline\'']
|
|
}
|
|
|
|
const disallowFramingDirectives = {
|
|
frameAncestors: ['\'self\'']
|
|
}
|
|
|
|
const allowPDFEmbedDirectives = {
|
|
objectSrc: ['*'], // Chrome and Firefox treat PDFs as objects
|
|
frameSrc: ['*'] // Chrome also checks PDFs against frame-src
|
|
}
|
|
|
|
const configuredGitLabInstanceDirectives = {
|
|
connectSrc: [config.gitlab.baseURL]
|
|
}
|
|
|
|
CspStrategy.computeDirectives = function () {
|
|
const directives = {}
|
|
mergeDirectives(directives, config.csp.directives)
|
|
mergeDirectivesIf(config.csp.addDefaults, directives, defaultDirectives)
|
|
mergeDirectivesIf(config.csp.addDisqus, directives, disqusDirectives)
|
|
mergeDirectivesIf(config.csp.addGoogleAnalytics, directives, googleAnalyticsDirectives)
|
|
mergeDirectivesIf(config.dropbox.appKey, directives, dropboxDirectives)
|
|
mergeDirectivesIf(!config.csp.allowFraming, directives, disallowFramingDirectives)
|
|
mergeDirectivesIf(config.csp.allowPDFEmbed, directives, allowPDFEmbedDirectives)
|
|
mergeDirectivesIf(config.isGitlabSnippetsEnable, directives, configuredGitLabInstanceDirectives)
|
|
addInlineScriptExceptions(directives)
|
|
addUpgradeUnsafeRequestsOptionTo(directives)
|
|
addReportURI(directives)
|
|
return directives
|
|
}
|
|
|
|
function mergeDirectives (existingDirectives, newDirectives) {
|
|
for (const propertyName in newDirectives) {
|
|
const newDirective = newDirectives[propertyName]
|
|
if (newDirective) {
|
|
const existingDirective = existingDirectives[propertyName] || []
|
|
existingDirectives[propertyName] = existingDirective.concat(newDirective)
|
|
}
|
|
}
|
|
}
|
|
|
|
function mergeDirectivesIf (condition, existingDirectives, newDirectives) {
|
|
if (condition) {
|
|
mergeDirectives(existingDirectives, newDirectives)
|
|
}
|
|
}
|
|
|
|
function addInlineScriptExceptions (directives) {
|
|
directives.scriptSrc.push(getCspNonce)
|
|
// TODO: This is the SHA-256 hash of the inline script in build/reveal.js/plugins/notes/notes.html
|
|
// Any more clean solution appreciated.
|
|
directives.scriptSrc.push('\'sha256-81acLZNZISnyGYZrSuoYhpzwDTTxi7vC1YM4uNxqWaM=\'')
|
|
}
|
|
|
|
function getCspNonce (req, res) {
|
|
return '\'nonce-' + res.locals.nonce + '\''
|
|
}
|
|
|
|
function addUpgradeUnsafeRequestsOptionTo (directives) {
|
|
if (config.csp.upgradeInsecureRequests === 'auto' && (config.useSSL || config.protocolUseSSL)) {
|
|
directives.upgradeInsecureRequests = []
|
|
} else if (config.csp.upgradeInsecureRequests === true) {
|
|
directives.upgradeInsecureRequests = []
|
|
}
|
|
}
|
|
|
|
function addReportURI (directives) {
|
|
if (config.csp.reportURI) {
|
|
directives.reportUri = config.csp.reportURI
|
|
}
|
|
}
|
|
|
|
CspStrategy.addNonceToLocals = function (req, res, next) {
|
|
res.locals.nonce = uuidv4()
|
|
next()
|
|
}
|
|
|
|
module.exports = CspStrategy
|