Add precheck for base64 strings in auth:import (#942)

This commit is contained in:
misterpoe
2018-10-15 12:51:30 -07:00
committed by Michael Bleigh
parent e613e421a7
commit 384797bce5
3 changed files with 86 additions and 11 deletions

View File

@@ -77,6 +77,11 @@ module.exports = new Command("auth:import [dataFile]")
return newStr === "" ? undefined : newStr;
})
);
if (user.error) {
return reject(
"Line " + counter + " (" + line + ") has invalid data format: " + user.error
);
}
currentBatch.push(user);
if (currentBatch.length === MAX_BATCH_SIZE) {
batches.push(currentBatch);
@@ -113,16 +118,21 @@ module.exports = new Command("auth:import [dataFile]")
});
inStream.pipe(parser);
}
}).then(function(userListArr) {
logger.debug(
"Preparing to import",
counter,
"user records in",
userListArr.length,
"batches."
);
if (userListArr.length) {
return serialImportUsers(projectId, hashOptions, userListArr, 0);
}).then(
function(userListArr) {
logger.debug(
"Preparing to import",
counter,
"user records in",
userListArr.length,
"batches."
);
if (userListArr.length) {
return serialImportUsers(projectId, hashOptions, userListArr, 0);
}
},
function(error) {
return utils.reject(error, { exit: 1 });
}
});
);
});

View File

@@ -26,6 +26,16 @@ var ALLOWED_JSON_KEYS_RENAMING = {
var ALLOWED_PROVIDER_USER_INFO_KEYS = ["providerId", "rawId", "email", "displayName", "photoUrl"];
var ALLOWED_PROVIDER_IDS = ["google.com", "facebook.com", "twitter.com", "github.com"];
var _isValidBase64 = function(str) {
var expected = Buffer.from(str, "base64").toString("base64");
// Buffer automatically pads with '=' character,
// but input string might not have padding.
if (str.length < expected.length && str.slice(-1) !== "=") {
str += "=".repeat(expected.length - str.length);
}
return expected === str;
};
var _toWebSafeBase64 = function(data) {
return data
.toString("base64")
@@ -115,6 +125,17 @@ var transArrayToUser = function(arr) {
_addProviderUserInfo(user, "facebook.com", arr.slice(11, 15));
_addProviderUserInfo(user, "twitter.com", arr.slice(15, 19));
_addProviderUserInfo(user, "github.com", arr.slice(19, 23));
if (user.passwordHash && !_isValidBase64(user.passwordHash)) {
return {
error: "Password hash should be base64 encoded.",
};
}
if (user.salt && !_isValidBase64(user.salt)) {
return {
error: "Password salt should be base64 encoded.",
};
}
return user;
};
@@ -251,6 +272,17 @@ var validateUserJson = function(userJson) {
}
}
}
var badFormat = JSON.stringify(userJson, null, 2) + " has invalid data format: ";
if (userJson.passwordHash && !_isValidBase64(userJson.passwordHash)) {
return {
error: badFormat + "Password hash should be base64 encoded.",
};
}
if (userJson.salt && !_isValidBase64(userJson.salt)) {
return {
error: badFormat + "Password salt should be base64 encoded.",
};
}
return {};
};

View File

@@ -8,10 +8,25 @@ var helpers = require("../helpers");
var expect = chai.expect;
describe("accountImporter", function() {
var transArrayToUser = accountImporter.transArrayToUser;
var validateOptions = accountImporter.validateOptions;
var validateUserJson = accountImporter.validateUserJson;
var serialImportUsers = accountImporter.serialImportUsers;
describe("transArrayToUser", function() {
it("should reject when passwordHash is invalid base64", function() {
return expect(transArrayToUser(["123", undefined, undefined, "false"])).to.have.property(
"error"
);
});
it("should not reject when passwordHash is valid base64", function() {
return expect(
transArrayToUser(["123", undefined, undefined, "Jlf7onfLbzqPNFP/1pqhx6fQF/w="])
).to.not.have.property("error");
});
});
describe("validateOptions", function() {
it("should reject when unsupported hash algorithm provided", function() {
return expect(validateOptions({ hashAlgo: "MD2" })).to.be.rejected;
@@ -63,6 +78,24 @@ describe("accountImporter", function() {
})
).to.have.property("error");
});
it("should reject when passwordHash is invalid base64", function() {
return expect(
validateUserJson({
localId: "123",
passwordHash: "false",
})
).to.have.property("error");
});
it("should not reject when passwordHash is valid base64", function() {
return expect(
validateUserJson({
localId: "123",
passwordHash: "Jlf7onfLbzqPNFP/1pqhx6fQF/w=",
})
).to.not.have.property("error");
});
});
describe("serialImportUsers", function() {