diff --git a/core/server/models/base.js b/core/server/models/base.js index 2d2df713fdb..02ad1d17f77 100644 --- a/core/server/models/base.js +++ b/core/server/models/base.js @@ -7,7 +7,7 @@ var ghostBookshelf, config = require('../config'), Validator = require('validator').Validator, unidecode = require('unidecode'), - sanitize = require('validator').sanitize; + sanitize = require('caja-sanitizer').sanitize; // Initializes a new Bookshelf instance, for reference elsewhere in Ghost. ghostBookshelf = Bookshelf.ghost = Bookshelf.initialize(config().database); @@ -80,7 +80,10 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({ }, sanitize: function (attr) { - return sanitize(this.get(attr)).xss(); + if (this.get(attr) === null || this.get(attr) === undefined) { + return this.get(attr); + } + return sanitize(this.get(attr)); }, // #### generateSlug diff --git a/core/server/models/post.js b/core/server/models/post.js index b471f51568c..1edfddb1647 100644 --- a/core/server/models/post.js +++ b/core/server/models/post.js @@ -1,16 +1,17 @@ -var Post, - Posts, - _ = require('underscore'), - uuid = require('node-uuid'), - when = require('when'), - errors = require('../errorHandling'), - Showdown = require('showdown'), - github = require('../../shared/vendor/showdown/extensions/github'), - converter = new Showdown.converter({extensions: [github]}), - User = require('./user').User, - Tag = require('./tag').Tag, - Tags = require('./tag').Tags, - ghostBookshelf = require('./base'); +var _ = require('underscore'), + uuid = require('node-uuid'), + when = require('when'), + Showdown = require('showdown'), + errors = require('../errorHandling'), + github = require('../../shared/vendor/showdown/extensions/github'), + User = require('./user').User, + Tag = require('./tag').Tag, + Tags = require('./tag').Tags, + ghostBookshelf = require('./base'), + + converter = new Showdown.converter({extensions: [github]}), + Post, + Posts; Post = ghostBookshelf.Model.extend({ @@ -33,25 +34,20 @@ Post = ghostBookshelf.Model.extend({ this.on('creating', this.creating, this); this.on('saving', this.updateTags, this); this.on('saving', this.saving, this); - this.on('saving', this.validate, this); - }, - - validate: function () { - ghostBookshelf.validator.check(this.get('title'), "Post title cannot be blank").notEmpty(); - ghostBookshelf.validator.check(this.get('title'), 'Post title maximum length is 150 characters.').len(0, 150); - return true; }, saving: function (newPage, attr, options) { /*jslint unparam:true*/ - var self = this; - - // Remove any properties which don't belong on the post model - this.attributes = this.pick(this.permittedAttributes); + var self = this, + unsafeTitle = this.get('title'); this.set('html', converter.makeHtml(this.get('markdown'))); this.set('title', this.sanitize('title').trim()); + ghostBookshelf.validator.check(this.get('title'), + this.get('title') === unsafeTitle ? "Post title cannot be blank" : "Post title cannot be blank (current text is classified as unsafe and will be removed)") + .notEmpty(); + ghostBookshelf.validator.check(this.get('title'), 'Post title maximum length is 150 characters.').len(0, 150); if (this.hasChanged('status') && this.get('status') === 'published') { if (!this.get('published_at')) { diff --git a/core/test/integration/model/model_posts_spec.js b/core/test/integration/model/model_posts_spec.js index 9ab6c2be2a4..d62714f202b 100644 --- a/core/test/integration/model/model_posts_spec.js +++ b/core/test/integration/model/model_posts_spec.js @@ -370,9 +370,9 @@ describe('Post Model', function () { it('should sanitize the title', function (done) { new PostModel().fetch().then(function (model) { - return model.set({'title': ""}).save(); + return model.set({'title': 'title'}).save(); }).then(function (saved) { - saved.get('title').should.eql("</title></head><body>[removed]alert('blogtitle');[removed]"); + saved.get('title').should.eql('title'); done(); }).otherwise(done); }); diff --git a/package.json b/package.json index c73cfab4c71..2308d1715f5 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,8 @@ "underscore": "1.5.2", "unidecode": "0.1.3", "validator": "1.4.0", - "when": "2.7.0" + "when": "2.7.0", + "caja-sanitizer": "0.1.1" }, "optionalDependencies": { "mysql": "2.0.0-alpha9"