Просмотр исходного кода

allow tags according to CommonMark Spec

Yuki Takei 7 лет назад
Родитель
Сommit
194e90d988
2 измененных файлов с 51 добавлено и 1 удалено
  1. 42 0
      src/lib/service/xss/commonmark-spec.js
  2. 9 1
      src/lib/service/xss/index.js

+ 42 - 0
src/lib/service/xss/commonmark-spec.js

@@ -0,0 +1,42 @@
+/**
+ * Valid schemes
+ * @see https://spec.commonmark.org/0.16/#autolinks
+ */
+const schemesForAutolink = [
+  'coap', 'doi', 'javascript', 'aaa', 'aaas', 'about', 'acap', 'cap', 'cid', 'crid', 'data', 'dav', 'dict', 'dns',
+  'file', 'ftp', 'geo', 'go', 'gopher', 'h323', 'http', 'https', 'iax', 'icap', 'im', 'imap', 'info', 'ipp', 'iris',
+  'iris.beep', 'iris.xpc', 'iris.xpcs', 'iris.lwz', 'ldap', 'mailto', 'mid', 'msrp', 'msrps', 'mtqp', 'mupdate',
+  'news', 'nfs', 'ni', 'nih', 'nntp', 'opaquelocktoken', 'pop', 'pres', 'rtsp', 'service', 'session', 'shttp',
+  'sieve', 'sip', 'sips', 'sms', 'snmp,soap.beep', 'soap.beeps', 'tag', 'tel', 'telnet', 'tftp', 'thismessage',
+  'tn3270', 'tip', 'tv', 'urn', 'vemmi', 'ws', 'wss', 'xcon', 'xcon-userid', 'xmlrpc.beep', 'xmlrpc.beeps', 'xmpp',
+  'z39.50r', 'z39.50s', 'adiumxtra', 'afp', 'afs', 'aim', 'apt,attachment', 'aw', 'beshare', 'bitcoin', 'bolo',
+  'callto', 'chrome,chrome-extension', 'com-eventbrite-attendee', 'content', 'cvs,dlna-playsingle', 'dlna-playcontainer',
+  'dtn', 'dvb', 'ed2k', 'facetime', 'feed', 'finger', 'fish', 'gg', 'git', 'gizmoproject', 'gtalk', 'hcp', 'icon',
+  'ipn', 'irc', 'irc6', 'ircs', 'itms', 'jar', 'jms', 'keyparc', 'lastfm', 'ldaps', 'magnet', 'maps', 'market,message',
+  'mms', 'ms-help', 'msnim', 'mumble', 'mvn', 'notes', 'oid', 'palm', 'paparazzi', 'platform', 'proxy', 'psyc',
+  'query', 'res', 'resource', 'rmi', 'rsync', 'rtmp', 'secondlife', 'sftp', 'sgn', 'skype', 'smb', 'soldat', 'spotify',
+  'ssh', 'steam', 'svn', 'teamspeak', 'things', 'udp', 'unreal', 'ut2004', 'ventrilo', 'view-source', 'webcal',
+  'wtai', 'wyciwyg', 'xfire', 'xri', 'ymsgr',
+];
+const schemesCondition = schemesForAutolink.join('|');
+
+/**
+ * RegExp for URI
+ * @type {RegExp}
+ * @see https://spec.commonmark.org/0.16/#autolinks
+ */
+const uriAutolinkRegexp = new RegExp(`^(${schemesCondition}):\\/\\/.+$`);
+
+/**
+ * RegExp for email
+ * @type {RegExp}
+ * @see https://spec.commonmark.org/0.16/#autolinks
+ */
+// eslint-disable-next-line max-len
+const emailAutolinkRegexp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
+
+
+module.exports = {
+  uriAutolinkRegexp,
+  emailAutolinkRegexp,
+};

+ 9 - 1
src/lib/service/xss/index.js

@@ -1,7 +1,9 @@
+const xss = require('xss');
+const commonmarkSpec = require('./commonmark-spec');
+
 class Xss {
 
   constructor(xssOption) {
-    const xss = require('xss');
 
     xssOption = xssOption || {}; // eslint-disable-line no-param-reassign
 
@@ -17,6 +19,12 @@ class Xss {
       css: false,
       whiteList: whiteListContent,
       escapeHtml: (html) => { return html }, // resolve https://github.com/weseek/growi/issues/221
+      onTag: (tag, html, options) => {
+        // pass autolink
+        if (tag.match(commonmarkSpec.uriAutolinkRegexp) || tag.match(commonmarkSpec.emailAutolinkRegexp)) {
+          return html;
+        }
+      },
     };
 
     tagWhiteList.forEach((tag) => {