Yuki Takei 1 год назад
Родитель
Сommit
4ecef41b16

+ 0 - 73
apps/app/src/server/service/xss.js

@@ -1,73 +0,0 @@
-import loggerFactory from '~/utils/logger';
-
-const logger = loggerFactory('growi:service:XssSerivce'); // eslint-disable-line no-unused-vars
-
-const Xss = require('~/services/xss');
-const { tags, attrs } = require('~/services/xss/recommended-whitelist');
-
-/**
- * the service class of XssSerivce
- */
-class XssSerivce {
-
-  constructor(configManager) {
-    this.configManager = configManager;
-
-    this.xss = new Xss();
-  }
-
-  process(value) {
-    return this.xss.process(value);
-  }
-
-  getTagWhitelist() {
-    const isEnabledXssPrevention = this.configManager.getConfig('markdown', 'markdown:xss:isEnabledPrevention');
-    const xssOpiton = this.configManager.getConfig('markdown', 'markdown:xss:option');
-
-    if (isEnabledXssPrevention) {
-      switch (xssOpiton) {
-        case 1: // ignore all: use default option
-          return [];
-
-        case 2: // recommended
-          return tags;
-
-        case 3: // custom whitelist
-          return this.configManager.getConfig('markdown', 'markdown:xss:tagWhitelist');
-
-        default:
-          return [];
-      }
-    }
-    else {
-      return [];
-    }
-  }
-
-  getAttrWhitelist() {
-    const isEnabledXssPrevention = this.configManager.getConfig('markdown', 'markdown:xss:isEnabledPrevention');
-    const xssOpiton = this.configManager.getConfig('markdown', 'markdown:xss:option');
-
-    if (isEnabledXssPrevention) {
-      switch (xssOpiton) {
-        case 1: // ignore all: use default option
-          return [];
-
-        case 2: // recommended
-          return attrs;
-
-        case 3: // custom whitelist
-          return this.configManager.getConfig('markdown', 'markdown:xss:attrWhitelist');
-
-        default:
-          return [];
-      }
-    }
-    else {
-      return [];
-    }
-  }
-
-}
-
-module.exports = XssSerivce;

+ 32 - 0
apps/app/src/server/service/xss.ts

@@ -0,0 +1,32 @@
+import { RehypeSanitizeOption } from '~/interfaces/rehype';
+import { Xss } from '~/services/xss';
+import type { XssOptionConfig } from '~/services/xss/xssOption';
+import XssOption from '~/services/xss/xssOption';
+import loggerFactory from '~/utils/logger'; // eslint-disable-line no-unused-vars
+
+import { configManager } from './config-manager';
+
+const logger = loggerFactory('growi:service:XssSerivce');
+
+
+export const xss = (() => {
+  const options: XssOptionConfig = {
+    isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
+    xssOption: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option') as RehypeSanitizeOption,
+    tagWhitelist: configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
+    attrWhitelist: configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes'),
+  };
+  const xssOption = new XssOption(options);
+  return new Xss(xssOption);
+})();
+
+export const xssForRevisionId = (() => {
+  const options: XssOptionConfig = {
+    isEnabledXssPrevention: true,
+    xssOption: RehypeSanitizeOption.CUSTOM,
+    tagWhitelist: [],
+    attrWhitelist: {},
+  };
+  const xssOption = new XssOption(options);
+  return new Xss(xssOption);
+})();

+ 6 - 6
apps/app/src/services/xss/index.ts

@@ -12,16 +12,16 @@ export class Xss {
 
 
   myxss: FilterXSS;
   myxss: FilterXSS;
 
 
-  constructor(xssOption: XssOption) {
-
-    xssOption = xssOption || {}; // eslint-disable-line no-param-reassign
+  constructor(xssOption?: XssOption) {
 
 
     // default
     // default
     const option: IFilterXSSOptions = {
     const option: IFilterXSSOptions = {
       stripIgnoreTag: true,
       stripIgnoreTag: true,
       stripIgnoreTagBody: false, // see https://github.com/weseek/growi/pull/505
       stripIgnoreTagBody: false, // see https://github.com/weseek/growi/pull/505
       css: false,
       css: false,
-      whiteList: xssOption.attrWhitelist as Record<string, string[] | undefined>,
+      whiteList: xssOption != null
+        ? xssOption.attrWhitelist as Record<string, string[] | undefined>
+        : {},
       escapeHtml: (html) => { return html }, // resolve https://github.com/weseek/growi/issues/221
       escapeHtml: (html) => { return html }, // resolve https://github.com/weseek/growi/issues/221
       onTag: (tag, html, options) => {
       onTag: (tag, html, options) => {
         // pass autolink
         // pass autolink
@@ -35,7 +35,7 @@ export class Xss {
     this.myxss = new FilterXSS(option);
     this.myxss = new FilterXSS(option);
   }
   }
 
 
-  process(document: string): string {
+  process(document: string | undefined): string {
     let count = 0;
     let count = 0;
     let currDoc = document;
     let currDoc = document;
     let prevDoc = document;
     let prevDoc = document;
@@ -48,7 +48,7 @@ export class Xss {
       }
       }
 
 
       prevDoc = currDoc;
       prevDoc = currDoc;
-      currDoc = this.myxss.process(currDoc);
+      currDoc = this.myxss.process(currDoc ?? '');
     }
     }
     while (currDoc !== prevDoc);
     while (currDoc !== prevDoc);
 
 

+ 1 - 1
apps/app/src/services/xss/xssOption.ts

@@ -21,7 +21,7 @@ export default class XssOption {
   constructor(config: XssOptionConfig) {
   constructor(config: XssOptionConfig) {
     const initializedConfig: Partial<XssOptionConfig> = (config != null) ? config : {};
     const initializedConfig: Partial<XssOptionConfig> = (config != null) ? config : {};
 
 
-    this.isEnabledXssPrevention = initializedConfig.isEnabledXssPrevention || true;
+    this.isEnabledXssPrevention = initializedConfig.isEnabledXssPrevention ?? true;
     this.tagWhitelist = initializedConfig.tagWhitelist || recommendedTagNames;
     this.tagWhitelist = initializedConfig.tagWhitelist || recommendedTagNames;
     this.attrWhitelist = initializedConfig.attrWhitelist || recommendedAttributes;
     this.attrWhitelist = initializedConfig.attrWhitelist || recommendedAttributes;
   }
   }