Merge branch 'develop'

* develop:
  Updated travis for lastest distro and chromedriver. Update darkwire to v1.5.8
  Adds rel=noreferrer and rel=noopener to autolinks (Fixes #46)
  Fixes XSS attack through user renaming (#47)
  Dockerfile strictly requiring njs 6.7
This commit is contained in:
Dan Seripap 2016-11-28 13:34:30 -05:00
commit d9a51de7e7
8 changed files with 44 additions and 17 deletions

View File

@ -18,7 +18,7 @@ before_install:
- sudo apt-get install -y libappindicator1 fonts-liberation - sudo apt-get install -y libappindicator1 fonts-liberation
- wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb - wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
- sudo dpkg -i google-chrome*.deb - sudo dpkg -i google-chrome*.deb
- wget http://chromedriver.storage.googleapis.com/2.21/chromedriver_linux64.zip - wget http://chromedriver.storage.googleapis.com/2.24/chromedriver_linux64.zip
- unzip chromedriver_linux64 - unzip chromedriver_linux64
- sudo mv chromedriver /usr/bin - sudo mv chromedriver /usr/bin
before_script: before_script:

View File

@ -1,4 +1,4 @@
FROM node:6 FROM node:6.7
RUN npm install -g forever RUN npm install -g forever

View File

@ -1,6 +1,6 @@
{ {
"name": "darkwire", "name": "darkwire",
"version": "1.5.7", "version": "1.5.8",
"description": "Encrypted web socket chat", "description": "Encrypted web socket chat",
"main": "index.js", "main": "index.js",
"dependencies": { "dependencies": {

View File

@ -211,9 +211,19 @@ export default class App {
// Prevents input from having injected markup // Prevents input from having injected markup
cleanInput(input) { cleanInput(input) {
input = input.replace(/\r?\n/g, '<br />'); input = input.replace(/\r?\n/g, '<br />');
let sanitized = he.encode(input); return this.autolinker(he.encode(input));
sanitized = Autolinker.link(sanitized); }
return sanitized;
// Adds rel=noopener noreferrer to autolinked links (Addresses #46 from @Mickael-van-der-Beek)
autolinker(sanitized) {
return Autolinker.link(sanitized, {
replaceFn: function(match) {
const tag = match.buildTag();
tag.setAttr('rel', 'noopener noreferrer');
return tag;
}
});
} }
// Sets the client's username // Sets the client's username

View File

@ -358,3 +358,9 @@ html.no-touchevents .chat #input-icons {
font-style: italic; font-style: italic;
display: block; display: block;
} }
.external-link:after {
content: 'External Link';
color: #FFF;
background-color: red;
}

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,7 @@ class Room {
EventEmitter.call(this); EventEmitter.call(this);
const thisIO = io.of(this._id); const thisIO = io.of(this._id);
thisIO.on('connection', (socket) => { thisIO.on('connection', (socket) => {
let addedUser = false; let addedUser = false;
@ -34,10 +35,13 @@ class Room {
if (addedUser) { return; } if (addedUser) { return; }
data.id = uuid.v4(); data.id = uuid.v4();
this.users.push(data); this.users.push(data);
const username = this.sanitizeUsername(data.username);
// we store the username in the socket session for this client // we store the username in the socket session for this client
socket.username = data.username; socket.username = username;
socket.user = data; socket.user = data;
++this.numUsers; ++this.numUsers;
addedUser = true; addedUser = true;
@ -87,16 +91,18 @@ class Room {
// Update user // Update user
socket.on('update user', (data) => { socket.on('update user', (data) => {
if (data.newUsername.length > 16) { const newUsername = this.sanitizeUsername(data.newUsername);
if (newUsername.length > 16) {
return false; return false;
} }
let user = _.find(this.users, (users) => {
const user = _.find(this.users, (users) => {
return users === socket.user; return users === socket.user;
}); });
if (user) { if (user) {
user.username = data.newUsername; socket.username = user.username = newUsername;
socket.username = user.username;
socket.user = user; socket.user = user;
thisIO.emit('user update', { thisIO.emit('user update', {
@ -110,6 +116,10 @@ class Room {
}); });
} }
sanitizeUsername(str) {
return str.replace(/[^A-Za-z0-9]/g, '-');
}
roomId() { roomId() {
return this.id; return this.id;
} }

View File

@ -38,10 +38,11 @@ describe('App', () => {
app = new App(); app = new App();
}); });
it('should create HTML links from URLs', () => { it('should create HTML links from URLs with "rel=noopener noreferrer"', () => {
let input = app.cleanInput('cnn.com'); let input = app.cleanInput('cnn.com');
assert.equal(input, '<a href="http://cnn.com" target="_blank">cnn.com</a>'); assert.equal(input, '<a href="http://cnn.com" target="_blank" rel="noopener noreferrer">cnn.com</a>');
}); });
}); });
}); });