CVE-2019-14331 (JavaScript, published 2019-07-28T14:15Z)
Description: value: An issue was discovered in EspoCRM before 5.6.6. Stored XSS exists due to lack of filtration of user-supplied data in Create User. A malicious attacker can modify the firstName and lastName to contain JavaScript code.
Severity: MEDIUM (CVSS v3 base score: 6.1)
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/espocrm/espocrm
Files changed:
client/src/views/email/fields/email-address-varchar.js
client/src/views/email/fields/from-address-varchar.js
client/src/views/fields/link-multiple-with-primary.js
client/src/views/notification/items/assign.js
client/src/views/notification/items/email-received.js
client/src/views/notification/items/entity-removed.js
client/src/views/notification/items/message.js
client/src/views/site/navbar.js
client/src/views/stream/note.js
client/src/views/stream/notes/assign.js
client/src/views/stream/notes/create-related.js
client/src/views/stream/notes/create.js
client/src/views/stream/notes/email-received.js
client/src/views/stream/notes/email-sent.js
client/src/views/stream/notes/mention-in-post.js
client/src/views/stream/notes/post.js
client/src/views/stream/notes/relate.js
client/src/views/stream/notes/status.js
Commit message: xss fixes


Vulnerable code:
            var nameHtml = '<div>' + name + '&nbsp;' + '</div>';
            this.messageData['entity'] = '<a href="#' + data.entityType + '/view/' + data.entityId + '">' + data.entityName + '</a>';
            this.messageData['entityType'] = Espo.Utils.upperCaseFirst((this.translate(data.entityType, 'scopeNames') || '').toLowerCase());
                this.messageData['from'] = '<a href="#' + data.personEntityType + '/view/' + data.personEntityId + '">' + data.personEntityName + '</a>';
                this.messageData['from'] = data.fromString || this.translate('empty address');
            this.emailId = data.emailId;
            this.emailName = data.emailName;

            this.messageData['entityType'] = (this.translate(data.entityType, 'scopeNames') || '').toLowerCase();
            this.messageData['user'] = '<a href="#User/view/' + data.userId + '">' + data.userName + '</a>';
            this.messageData['entity'] = '<a href="#'+data.entityType+'/view/' + data.entityId + '">' + data.entityName + '</a>';
            this.messageData['entityType'] = Espo.Utils.upperCaseFirst((this.translate(data.entityType, 'scopeNames') || '').toLowerCase());
            this.messageData['user'] = '<a href="#User/view/' + data.userId + '">' + data.userName + '</a>';
            this.messageData['entity'] = '<a href="#'+data.entityType+'/view/' + data.entityId + '">' + data.entityName + '</a>';
                userName: this.getUser().get('name'),
                    html: avatarHtml + this.getUser().get('name')
                'entityType': this.translateEntityType(this.model.get('parentType')),
            this.messageData['assignee'] = '<a href="#User/view/' + data.assignedUserId + '">' + data.assignedUserName + '</a>';
            this.messageData['relatedEntity'] = '<a href="#' + this.entityType + '/view/' + this.entityId + '">' + this.entityName +'</a>';
                this.messageData['assignee'] = '<a href="#User/view/' + this.assignedUserId + '">' + this.assignedUserName + '</a>';
            this.messageData['email'] = '<a href="#Email/view/' + data.emailId + '">' + data.emailName + '</a>';
                this.messageData['from'] = '<a href="#'+data.personEntityType+'/view/' + data.personEntityId + '">' + data.personEntityName + '</a>';
            this.messageData['email'] = '<a href="#Email/view/' + data.emailId + '">' + data.emailName + '</a>';
            this.messageData['by'] = '<a href="#'+data.personEntityType+'/view/' + data.personEntityId + '">' + data.personEntityName + '</a>';
                                        teamHtmlList.push('<a href="#Team/view/' + teamId + '">' + teamName + '</a>');
                                            userHtmlList.push('<a href="#User/view/' + userId + '">' + userName + '</a>');

                                teamHtmlList.push('<a href="#Team/view/' + teamId + '">' + teamName + '</a>');
                                portalHtmlList.push('<a href="#Portal/view/' + portalId + '">' + portalName + '</a>');
                                            userHtmlList.push('<a href="#User/view/' + userId + '">' + userName + '</a>');
            this.messageData['relatedEntity'] = '<a href="#' + this.entityType + '/view/' + this.entityId + '">' + this.entityName +'</a>';
            this.statusText = this.getLanguage().translateOption(value, field, this.model.get('parentType'));

Fixed code:
            if (name) {
                name = this.getHelper().escapeString(name);
            }

            if (name) {
                name = this.getHelper().escapeString(name);
            }
            if (address) {
                name = this.getHelper().escapeString(address);
            }

            if (name) {
                name = this.getHelper().escapeString(name);
            }


            if (name) {
                name = this.getHelper().escapeString(name);
            }

            address = this.getHelper().escapeString(address);

            if (name) {
                name = this.getHelper().escapeString(name);
            }

            if (name) {
                name = this.getHelper().escapeString(name);
            }

            var nameHtml = '<div>' + this.getHelper().escapeString(name) + '&nbsp;' + '</div>';
            this.messageData['entity'] = '<a href="#' + this.getHelper().escapeString(data.entityType) + '/view/' + this.getHelper().escapeString(data.entityId) + '">' + this.getHelper().escapeString(data.entityName) + '</a>';
            this.messageData['entityType'] = this.getHelper().escapeString(Espo.Utils.upperCaseFirst((this.translate(data.entityType, 'scopeNames') || '').toLowerCase()));
                this.messageData['from'] = '<a href="#' + this.getHelper().escapeString(data.personEntityType) + '/view/' + this.getHelper().escapeString(data.personEntityId) + '">' + this.getHelper().escapeString(data.personEntityName) + '</a>';
                this.messageData['from'] = this.getHelper().escapeString(data.fromString || this.translate('empty address'));
            this.emailId = this.getHelper().escapeString(data.emailId);
            this.emailName = this.getHelper().escapeString(data.emailName);
            this.messageData['entityType'] = this.getHelper().escapeString((this.translate(data.entityType, 'scopeNames') || '').toLowerCase());
            this.messageData['user'] = '<a href="#User/view/' + this.getHelper().escapeString(data.userId) + '">' + this.getHelper().escapeString(data.userName) + '</a>';
            this.messageData['entity'] = '<a href="#'+this.getHelper().escapeString(data.entityType)+'/view/' + this.getHelper().escapeString(data.entityId) + '">' + this.getHelper().escapeString(data.entityName) + '</a>';
            this.messageData['entityType'] = this.getHelper().escapeString(Espo.Utils.upperCaseFirst((this.translate(data.entityType, 'scopeNames') || '').toLowerCase()));
            this.messageData['user'] = '<a href="#User/view/' + this.getHelper().escapeString(data.userId) + '">' + this.getHelper().escapeString(data.userName) + '</a>';
            this.messageData['entity'] = '<a href="#'+this.getHelper().escapeString(data.entityType)+'/view/' + this.getHelper().escapeString(data.entityId) + '">' + this.getHelper().escapeString(data.entityName) + '</a>';
                    html: avatarHtml + this.getHelper().escapeString(this.getUser().get('name')),
                'entityType': this.getHelper().escapeString(this.translateEntityType(this.model.get('parentType'))),
            this.messageData['assignee'] = '<a href="#User/view/' + this.getHelper().escapeString(data.assignedUserId) + '">' + this.getHelper().escapeString(data.assignedUserName) + '</a>';
            this.messageData['relatedEntity'] = '<a href="#' + this.getHelper().escapeString(this.entityType) + '/view/' + this.getHelper().escapeString(this.entityId) + '">' + this.getHelper().escapeString(this.entityName) +'</a>';
                this.messageData['assignee'] = '<a href="#User/view/' + this.assignedUserId + '">' + this.getHelper().escapeString(this.assignedUserName) + '</a>';
            this.messageData['email'] = '<a href="#Email/view/' + this.getHelper().escapeString(data.emailId) + '">' + this.getHelper().escapeString(data.emailName) + '</a>';
                this.messageData['from'] = '<a href="#'+this.getHelper().escapeString(data.personEntityType)+'/view/' + this.getHelper().escapeString(data.personEntityId) + '">' + this.getHelper().escapeString(data.personEntityName) + '</a>';
            this.messageData['email'] = '<a href="#Email/view/' + this.getHelper().escapeString(data.emailId) + '">' + this.getHelper().escapeString(data.emailName) + '</a>';
            this.messageData['by'] = '<a href="#'+this.getHelper().escapeString(data.personEntityType)+'/view/' + this.getHelper().escapeString(data.personEntityId) + '">' + this.getHelper().escapeString(data.personEntityName) + '</a>';
                                        teamHtmlList.push('<a href="#Team/view/' + this.getHelper().escapeString(teamId) + '">' + this.getHelper().escapeString(teamName) + '</a>');
                                            userHtmlList.push('<a href="#User/view/' + this.getHelper().escapeString(userId) + '">' + this.getHelper().escapeString(userName) + '</a>');
                                teamHtmlList.push('<a href="#Team/view/' + this.getHelper().escapeString(teamId) + '">' + this.getHelper().escapeString(teamName) + '</a>');
                                portalHtmlList.push('<a href="#Portal/view/' + this.getHelper().escapeString(portalId) + '">' + this.getHelper().escapeString(portalName) + '</a>');
                                            userHtmlList.push('<a href="#User/view/' + this.getHelper().escapeString(userId) + '">' + this.getHelper().escapeString(userName) + '</a>');
            this.messageData['relatedEntity'] = '<a href="#' + this.getHelper().escapeString(this.entityType) + '/view/' + this.getHelper().escapeString(this.entityId) + '">' + this.getHelper().escapeString(this.entityName) +'</a>';
            this.statusText = this.getHelper().escapeString(this.getLanguage().translateOption(value, field, this.model.get('parentType')));