1
0
mirror of https://github.com/moparisthebest/mail synced 2024-11-22 17:02:17 -05:00

Merge remote-tracking branch 'origin/dev/security-review'

This commit is contained in:
Felix Hammerl 2014-01-09 12:12:44 +01:00
commit e62e085771
5 changed files with 110 additions and 14 deletions

View File

@ -20,7 +20,12 @@ define(function(require) {
// push handler // push handler
if (emailDao) { if (emailDao) {
emailDao.onIncomingMessage = function(email) { emailDao.onIncomingMessage = function(email) {
if (email.subject.indexOf(str.subjectPrefix) === -1) { if (!email.subject) {
return;
}
if (email.subject.indexOf(str.subjectPrefix) === -1 ||
email.subject === str.subjectPrefix + str.verificationSubject) {
return; return;
} }

View File

@ -486,9 +486,8 @@ define(function(require) {
return; return;
} }
// imap filtering may not be sufficient, since google filters out // imap filtering is insufficient, since google ignores non-alphabetical characters
// non-alphabetical characters if (message.subject.indexOf(str.subjectPrefix.trim()) === -1) {
if (message.subject.indexOf(str.subjectPrefix) === -1) {
syncNextItem(); syncNextItem();
return; return;
} }
@ -718,7 +717,7 @@ define(function(require) {
} }
function verify(email, localCallback) { function verify(email, localCallback) {
var uuid, index, verifyUrlPrefix = config.cloudUrl + config.verificationUrl; var uuid, isValidUuid, index, verifyUrlPrefix = config.cloudUrl + config.verificationUrl;
if (!email.unread) { if (!email.unread) {
// don't bother if the email was already marked as read // don't bother if the email was already marked as read
@ -733,8 +732,14 @@ define(function(require) {
return; return;
} }
uuid = email.body.substr(index + verifyUrlPrefix.length, config.verificationUuidLength); uuid = email.body.substr(index + verifyUrlPrefix.length, config.verificationUuidLength);
isValidUuid = new RegExp('[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}').test(uuid);
if (!isValidUuid) {
// there's no valid uuid in the email, so forget about that, too.
localCallback();
return;
}
self._keychain.verifyPublicKey(uuid, function(err) { self._keychain.verifyPublicKey(uuid, function(err) {
if (err) { if (err) {
localCallback({ localCallback({

View File

@ -14,7 +14,15 @@ define(function() {
this._restDao.get({ this._restDao.get({
uri: uri, uri: uri,
type: 'text' type: 'text'
}, callback); }, function(err, res, status) {
if (err && err.code === 400) {
// there was an attempt to verify a non-existing public key
callback();
return;
}
callback(err, res, status);
});
}; };
/** /**

View File

@ -15,6 +15,7 @@ define(function(require) {
var emailAddress, passphrase, asymKeySize, mockkeyId, dummyEncryptedMail, var emailAddress, passphrase, asymKeySize, mockkeyId, dummyEncryptedMail,
dummyDecryptedMail, mockKeyPair, account, publicKey, verificationMail, verificationUuid, dummyDecryptedMail, mockKeyPair, account, publicKey, verificationMail, verificationUuid,
corruptedVerificationMail, corruptedVerificationUuid,
nonWhitelistedMail; nonWhitelistedMail;
beforeEach(function(done) { beforeEach(function(done) {
@ -35,7 +36,7 @@ define(function(require) {
unread: false, unread: false,
answered: false answered: false
}; };
verificationUuid = 'OMFG_FUCKING_BASTARD_UUID_FROM_HELL!'; verificationUuid = '9A858952-17EE-4273-9E74-D309EAFDFAFB';
verificationMail = { verificationMail = {
from: [{ from: [{
name: 'Whiteout Test', name: 'Whiteout Test',
@ -49,6 +50,20 @@ define(function(require) {
unread: true, unread: true,
answered: false answered: false
}; };
corruptedVerificationUuid = 'OMFG_FUCKING_BASTARD_UUID_FROM_HELL!';
corruptedVerificationMail = {
from: [{
name: 'Whiteout Test',
address: 'whiteout.test@t-online.de'
}], // sender address
to: [{
address: 'safewithme.testuser@gmail.com'
}], // list of receivers
subject: "[whiteout] New public key uploaded", // Subject line
body: 'yadda yadda bla blabla foo bar https://keys.whiteout.io/verify/' + corruptedVerificationUuid, // plaintext body
unread: true,
answered: false
};
dummyDecryptedMail = { dummyDecryptedMail = {
uid: 1234, uid: 1234,
from: [{ from: [{
@ -193,7 +208,9 @@ define(function(require) {
// initFolders // initFolders
listFolderStub = sinon.stub(dao, '_imapListFolders'); listFolderStub = sinon.stub(dao, '_imapListFolders');
listFolderStub.yields({code:42}); listFolderStub.yields({
code: 42
});
dao.init({ dao.init({
account: account account: account
@ -1666,7 +1683,6 @@ define(function(require) {
dao.sync({ dao.sync({
folder: folder folder: folder
}, function(err) { }, function(err) {
if (invocations === 0) { if (invocations === 0) {
expect(err).to.not.exist; expect(err).to.not.exist;
expect(dao._account.busy).to.be.true; expect(dao._account.busy).to.be.true;
@ -1714,7 +1730,6 @@ define(function(require) {
dao.sync({ dao.sync({
folder: folder folder: folder
}, function(err) { }, function(err) {
if (invocations === 0) { if (invocations === 0) {
expect(err).to.not.exist; expect(err).to.not.exist;
expect(dao._account.busy).to.be.true; expect(dao._account.busy).to.be.true;
@ -1761,7 +1776,6 @@ define(function(require) {
dao.sync({ dao.sync({
folder: folder folder: folder
}, function(err) { }, function(err) {
if (invocations === 0) { if (invocations === 0) {
expect(err).to.not.exist; expect(err).to.not.exist;
expect(dao._account.busy).to.be.true; expect(dao._account.busy).to.be.true;
@ -1814,6 +1828,59 @@ define(function(require) {
markReadStub = sinon.stub(dao, '_imapMark'); markReadStub = sinon.stub(dao, '_imapMark');
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage'); imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage');
dao.sync({
folder: folder
}, function(err) {
if (invocations === 0) {
expect(err).to.not.exist;
expect(dao._account.busy).to.be.true;
invocations++;
return;
}
expect(err).to.not.exist;
expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0].messages).to.be.empty;
expect(localListStub.calledOnce).to.be.true;
expect(imapSearchStub.calledThrice).to.be.true;
expect(imapGetStub.calledOnce).to.be.true;
expect(keychainStub.verifyPublicKey.called).to.be.false;
expect(markReadStub.called).to.be.false;
expect(imapDeleteStub.called).to.be.false;
done();
});
});
it('should not bother about corrupted authentication mails', function(done) {
var invocations, folder, localListStub, imapSearchStub, imapGetStub, markReadStub, imapDeleteStub;
invocations = 0;
folder = 'FOLDAAAA';
dao._account.folders = [{
type: 'Folder',
path: folder,
messages: []
}];
localListStub = sinon.stub(dao, '_localListMessages').yields(null, []);
imapSearchStub = sinon.stub(dao, '_imapSearch');
imapSearchStub.withArgs({
folder: folder
}).yields(null, [corruptedVerificationMail.uid]);
imapSearchStub.withArgs({
folder: folder,
unread: true
}).yields(null, []);
imapSearchStub.withArgs({
folder: folder,
answered: true
}).yields(null, []);
imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, corruptedVerificationMail);
markReadStub = sinon.stub(dao, '_imapMark');
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage');
dao.sync({ dao.sync({
folder: folder folder: folder
}, function(err) { }, function(err) {
@ -1838,7 +1905,7 @@ define(function(require) {
}); });
}); });
it('should not bother about corrupted authentication mails', function(done) { it('should not bother about corrupted authentication mails no verification link', function(done) {
var invocations, folder, localListStub, imapSearchStub, var invocations, folder, localListStub, imapSearchStub,
imapGetStub, markReadStub, imapDeleteStub; imapGetStub, markReadStub, imapDeleteStub;

View File

@ -49,12 +49,23 @@ define(function(require) {
it('should fail', function(done) { it('should fail', function(done) {
restDaoStub.get.yields(42); restDaoStub.get.yields(42);
pubkeyDao.get('id', function(err) { pubkeyDao.verify('id', function(err) {
expect(err).to.exist; expect(err).to.exist;
done(); done();
}); });
}); });
it('should not error for 400', function(done) {
restDaoStub.get.yields({
code: 400
});
pubkeyDao.verify('id', function(err) {
expect(err).to.not.exist;
done();
});
});
it('should work', function(done) { it('should work', function(done) {
var uuid = 'c621e328-8548-40a1-8309-adf1955e98a9'; var uuid = 'c621e328-8548-40a1-8309-adf1955e98a9';
restDaoStub.get.yields(null); restDaoStub.get.yields(null);