Skip to content

Commit

Permalink
fix(sanitize): use same setup for dompurify as FE
Browse files Browse the repository at this point in the history
  • Loading branch information
seaerchin committed Mar 31, 2023
1 parent dd6f1ae commit aefc85b
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 13 deletions.
42 changes: 42 additions & 0 deletions src/services/utilServices/Sanitizer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import DOMPurify from "isomorphic-dompurify"

DOMPurify.setConfig({
ADD_TAGS: ["iframe", "#comment", "script"],
ADD_ATTR: [
"allow",
"allowfullscreen",
"frameborder",
"scrolling",
"marginheight",
"marginwidth",
"target",
"async",
],
// required in case <script> tag appears as the first line of the markdown
FORCE_BODY: true,
})
DOMPurify.addHook("uponSanitizeElement", (node, data) => {
// Allow script tags if it has a src attribute
// Script sources are handled by our CSP sanitiser
if (
data.tagName === "script" &&
!(node.hasAttribute("src") && node.innerHTML === "")
) {
// Adapted from https://github.com/cure53/DOMPurify/blob/e0970d88053c1c564b6ccd633b4af7e7d9a10375/src/purify.js#L719-L736
DOMPurify.removed.push({ element: node })
try {
node.parentNode.removeChild(node)
} catch (e) {
try {
// eslint-disable-next-line no-param-reassign
node.outerHTML = ""
} catch (ex) {
node.remove()
}
}
}
})

// NOTE: Doing a re-export so that clients always use the correct config
export const sanitizer = DOMPurify
export default sanitizer
11 changes: 7 additions & 4 deletions src/utils/file-upload-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import logger from "@logger/logger"
const CloudmersiveVirusApiClient = require("cloudmersive-virus-api-client")
const FileType = require("file-type")
const isSvg = require("is-svg")
const DOMPurify = require("isomorphic-dompurify")

const { BaseIsomerError } = require("@errors/BaseError")
const { sanitizer } = require("@services/utilServices/Sanitizer")

const CLOUDMERSIVE_API_KEY = config.get("cloudmersiveKey")

Expand Down Expand Up @@ -49,7 +48,7 @@ const validateAndSanitizeFileUpload = async (data) => {
const detectedFileType = await FileType.fromBuffer(fileBuffer)

if (isSvg(fileBuffer)) {
const sanitizedBuffer = DOMPurify.sanitize(fileBuffer)
const sanitizedBuffer = sanitizer.sanitize(fileBuffer)
return Buffer.from(sanitizedBuffer, "utf8").toString("base64")
}
if (
Expand All @@ -62,4 +61,8 @@ const validateAndSanitizeFileUpload = async (data) => {
return undefined
}

module.exports = { validateAndSanitizeFileUpload, scanFileForVirus, ALLOWED_FILE_EXTENSIONS }
module.exports = {
validateAndSanitizeFileUpload,
scanFileForVirus,
ALLOWED_FILE_EXTENSIONS,
}
10 changes: 4 additions & 6 deletions src/utils/markdown-utils.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
const DOMPurify = require("isomorphic-dompurify")
const _ = require("lodash")

const {
sanitizedYamlParse,
sanitizedYamlStringify,
} = require("@utils/yaml-utils")

const { sanitizer } = require("@services/utilServices/Sanitizer")

const getTrailingSlashWithPermalink = (permalink) =>
permalink.endsWith("/") ? permalink : `${permalink}/`

const retrieveDataFromMarkdown = (fileContent) => {
// eslint-disable-next-line no-unused-vars
const [unused, encodedFrontMatter, ...pageContent] = DOMPurify.sanitize(
fileContent
).split("---")
const [unused, encodedFrontMatter, ...pageContent] = fileContent.split("---")
const frontMatter = sanitizedYamlParse(encodedFrontMatter)
return { frontMatter, pageContent: pageContent.join("---").trim() }
}
Expand All @@ -34,8 +33,7 @@ const convertDataToMarkdown = (originalFrontMatter, pageContent) => {
}
const newFrontMatter = sanitizedYamlStringify(frontMatter)
const newContent = ["---\n", newFrontMatter, "---\n", pageContent].join("")

return DOMPurify.sanitize(newContent)
return sanitizer.sanitize(newContent)
}

module.exports = {
Expand Down
7 changes: 4 additions & 3 deletions src/utils/yaml-utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import DOMPurify from "isomorphic-dompurify"
import yaml from "yaml"

import { sanitizer } from "@services/utilServices/Sanitizer"

// Note: `yaml.parse()` and `yaml.stringify()` should not be used anywhere
// else in the codebase.
export const sanitizedYamlParse = (
unparsedContent: string
): Record<string, unknown> => yaml.parse(DOMPurify.sanitize(unparsedContent))
): Record<string, unknown> => yaml.parse(sanitizer.sanitize(unparsedContent))

export const sanitizedYamlStringify = (prestringifiedContent: object): string =>
DOMPurify.sanitize(yaml.stringify(prestringifiedContent))
sanitizer.sanitize(yaml.stringify(prestringifiedContent))

0 comments on commit aefc85b

Please sign in to comment.