CVE-2021-25993 (JavaScript, published 2021-12-29T17:15Z)
Description: value: In Requarks wiki.js, versions 2.0.0-beta.147 to 2.5.255 are affected by Stored XSS vulnerability, where a low privileged (editor) user can upload a SVG file that contains malicious JavaScript while uploading assets in the page. That will send the JWT tokens to the attacker’s server and will lead to account takeover when accessed by the victim.
Severity: LOW (CVSS v3 base score: 5.4)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/Requarks/wiki
Files changed:
client/components/admin/admin-security.vue
server/app/data.yml
server/graph/resolvers/site.js
server/graph/schemas/site.graphql
server/jobs/sanitize-svg.js
server/models/assets.js
Commit message: fix: sanitize SVG uploads


Vulnerable code:
        uploadMaxFiles: WIKI.config.uploads.maxFiles
          maxFiles: _.get(args, 'uploadMaxFiles', WIKI.config.uploads.maxFiles)
  host: String!
  title: String!
  description: String!
  robots: [String]!
  analyticsService: String!
  analyticsId: String!
  company: String!
  contentLicense: String!
  logoUrl: String!
  featurePageRatings: Boolean!
  featurePageComments: Boolean!
  featurePersonalWikis: Boolean!
  securityOpenRedirect: Boolean!
  securityIframe: Boolean!
  securityReferrerPolicy: Boolean!
  securityTrustProxy: Boolean!
  securitySRI: Boolean!
  securityHSTS: Boolean!
  securityHSTSDuration: Int!
  securityCSP: Boolean!
  securityCSPDirectives: String!
  uploadMaxFileSize: Int!
  uploadMaxFiles: Int!

Fixed code:
                  v-divider.mt-3
                  v-switch(
                    inset
                    label='Scan and Sanitize SVG Uploads'
                    color='primary'
                    v-model='config.uploadScanSVG'
                    persistent-hint
                    hint='Should SVG uploads be scanned for vulnerabilities and stripped of any potentially unsafe content.'
                    )
        uploadScanSVG: true,
              $uploadScanSVG: Boolean
                  uploadScanSVG: $uploadScanSVG
            uploadScanSVG: _.get(this.config, 'uploadScanSVG', false),
              uploadScanSVG
      scanSVG: true
        uploadMaxFiles: WIKI.config.uploads.maxFiles,
        uploadScanSVG: WIKI.config.uploads.scanSVG
          maxFiles: _.get(args, 'uploadMaxFiles', WIKI.config.uploads.maxFiles),
          scanSVG: _.get(args, 'uploadScanSVG', WIKI.config.uploads.scanSVG)
    uploadScanSVG: Boolean
  host: String
  title: String
  description: String
  robots: [String]
  analyticsService: String
  analyticsId: String
  company: String
  contentLicense: String
  logoUrl: String
  featurePageRatings: Boolean
  featurePageComments: Boolean
  featurePersonalWikis: Boolean
  securityOpenRedirect: Boolean
  securityIframe: Boolean
  securityReferrerPolicy: Boolean
  securityTrustProxy: Boolean
  securitySRI: Boolean
  securityHSTS: Boolean
  securityHSTSDuration: Int
  securityCSP: Boolean
  securityCSPDirectives: String
  uploadMaxFileSize: Int
  uploadMaxFiles: Int
  uploadScanSVG: Boolean
const fs = require('fs-extra')
const { JSDOM } = require('jsdom')
const createDOMPurify = require('dompurify')

/* global WIKI */

module.exports = async (svgPath) => {
  WIKI.logger.info(`Sanitizing SVG file upload...`)

  try {
    let svgContents = await fs.readFile(svgPath, 'utf8')

    const window = new JSDOM('').window
    const DOMPurify = createDOMPurify(window)

    svgContents = DOMPurify.sanitize(svgContents)

    await fs.writeFile(svgPath, svgContents)
    WIKI.logger.info(`Sanitized SVG file upload: [ COMPLETED ]`)
  } catch (err) {
    WIKI.logger.error(`Failed to sanitize SVG file upload: [ FAILED ]`)
    WIKI.logger.error(err.message)
    throw err
  }
}
    // Sanitize SVG contents
    if (WIKI.config.uploads.scanSVG && opts.mimetype === 'image/svg+xml') {
      const svgSanitizeJob = await WIKI.scheduler.registerJob({
        name: 'sanitize-svg',
        immediate: true,
        worker: true
      }, opts.path)
      await svgSanitizeJob.finished
    }