فهرست منبع

Merge branch 'master' into imprv/reactify-admin-user-groups

mizozobu 6 سال پیش
والد
کامیت
a9406ca527

+ 1 - 0
CHANGES.md

@@ -5,6 +5,7 @@
 * Improvement: Handle private pages on group deletion
 * Improvement: Handle private pages on group deletion
 * Fix: Searching with `tag:xxx` syntax doesn't work
 * Fix: Searching with `tag:xxx` syntax doesn't work
 * Fix: Check CSRF when updating user data
 * Fix: Check CSRF when updating user data
+* Fix: `createdAt` field initialization
 * I18n: Import data page
 * I18n: Import data page
 * I18n: Group Management page
 * I18n: Group Management page
 
 

+ 1 - 1
src/server/models/attachment.js

@@ -28,7 +28,7 @@ module.exports = function(crowi) {
     originalName: { type: String },
     originalName: { type: String },
     fileFormat: { type: String, required: true },
     fileFormat: { type: String, required: true },
     fileSize: { type: Number, default: 0 },
     fileSize: { type: Number, default: 0 },
-    createdAt: { type: Date, default: Date.now() },
+    createdAt: { type: Date, default: Date.now },
   });
   });
 
 
   attachmentSchema.virtual('filePathProxied').get(function() {
   attachmentSchema.virtual('filePathProxied').get(function() {

+ 1 - 1
src/server/models/bookmark.js

@@ -13,7 +13,7 @@ module.exports = function(crowi) {
   bookmarkSchema = new mongoose.Schema({
   bookmarkSchema = new mongoose.Schema({
     page: { type: ObjectId, ref: 'Page', index: true },
     page: { type: ObjectId, ref: 'Page', index: true },
     user: { type: ObjectId, ref: 'User', index: true },
     user: { type: ObjectId, ref: 'User', index: true },
-    createdAt: { type: Date, default: Date.now() },
+    createdAt: { type: Date, default: Date.now },
   });
   });
   bookmarkSchema.index({ page: 1, user: 1 }, { unique: true });
   bookmarkSchema.index({ page: 1, user: 1 }, { unique: true });
 
 

+ 2 - 2
src/server/models/page.js

@@ -57,8 +57,8 @@ const pageSchema = new mongoose.Schema({
   pageIdOnHackmd: String,
   pageIdOnHackmd: String,
   revisionHackmdSynced: { type: ObjectId, ref: 'Revision' }, // the revision that is synced to HackMD
   revisionHackmdSynced: { type: ObjectId, ref: 'Revision' }, // the revision that is synced to HackMD
   hasDraftOnHackmd: { type: Boolean }, // set true if revision and revisionHackmdSynced are same but HackMD document has modified
   hasDraftOnHackmd: { type: Boolean }, // set true if revision and revisionHackmdSynced are same but HackMD document has modified
-  createdAt: { type: Date, default: Date.now() },
-  updatedAt: { type: Date, default: Date.now() },
+  createdAt: { type: Date, default: Date.now },
+  updatedAt: { type: Date, default: Date.now },
 }, {
 }, {
   toJSON: { getters: true },
   toJSON: { getters: true },
   toObject: { getters: true },
   toObject: { getters: true },

+ 14 - 1
src/server/routes/login-passport.js

@@ -4,6 +4,7 @@ module.exports = function(crowi, app) {
   const debug = require('debug')('growi:routes:login-passport');
   const debug = require('debug')('growi:routes:login-passport');
   const logger = require('@alias/logger')('growi:routes:login-passport');
   const logger = require('@alias/logger')('growi:routes:login-passport');
   const passport = require('passport');
   const passport = require('passport');
+  const { URL } = require('url');
   const ExternalAccount = crowi.model('ExternalAccount');
   const ExternalAccount = crowi.model('ExternalAccount');
   const passportService = crowi.passportService;
   const passportService = crowi.passportService;
 
 
@@ -24,7 +25,19 @@ module.exports = function(crowi, app) {
     const jumpTo = req.session.jumpTo;
     const jumpTo = req.session.jumpTo;
     if (jumpTo) {
     if (jumpTo) {
       req.session.jumpTo = null;
       req.session.jumpTo = null;
-      return res.redirect(jumpTo);
+
+      // prevention from open redirect
+      try {
+        const redirectUrl = new URL(jumpTo, `${req.protocol}://${req.get('host')}`);
+        if (redirectUrl.hostname === req.hostname) {
+          return res.redirect(redirectUrl);
+        }
+        logger.warn('Requested redirect URL is invalid, redirect to root page');
+      }
+      catch (err) {
+        logger.warn('Requested redirect URL is invalid, redirect to root page', err);
+        return res.redirect('/');
+      }
     }
     }
 
 
     return res.redirect('/');
     return res.redirect('/');

+ 13 - 1
src/server/routes/login.js

@@ -37,7 +37,19 @@ module.exports = function(crowi, app) {
     const jumpTo = req.session.jumpTo;
     const jumpTo = req.session.jumpTo;
     if (jumpTo) {
     if (jumpTo) {
       req.session.jumpTo = null;
       req.session.jumpTo = null;
-      return res.redirect(jumpTo);
+
+      // prevention from open redirect
+      try {
+        const redirectUrl = new URL(jumpTo, `${req.protocol}://${req.get('host')}`);
+        if (redirectUrl.hostname === req.hostname) {
+          return res.redirect(redirectUrl);
+        }
+        logger.warn('Requested redirect URL is invalid, redirect to root page');
+      }
+      catch (err) {
+        logger.warn('Requested redirect URL is invalid, redirect to root page', err);
+        return res.redirect('/');
+      }
     }
     }
 
 
     return res.redirect('/');
     return res.redirect('/');

+ 1 - 1
src/server/views/layout/layout.html

@@ -247,7 +247,7 @@
 {% endblock %}
 {% endblock %}
 
 
 <script type="application/json" id="crowi-context-hydrate">
 <script type="application/json" id="crowi-context-hydrate">
-{{ local_config|json|safe }}
+{{ local_config|json|safe|preventXss }}
 </script>
 </script>
 
 
 {% block custom_script %}
 {% block custom_script %}