Security: FEATURE REMOVAL: Remove all plain text password logic and ui (#4178)

This will be a breaking change for some people.  

We removed all internal password control logic.  If this affects you, you have two options:

1. Use a plugin for authentication and use session based pad access (recommended).
1. Use a plugin for password setting.

The reasoning for removing this feature is to reduce the overall security footprint of Etherpad.  It is unnecessary and cumbersome to keep this feature and with the thousands of available authentication methods available in the world our focus should be on supporting those and allowing more granual access based on their implementations (instead of half assed baking our own).
This commit is contained in:
John McLear 2020-10-07 13:43:54 +01:00 committed by GitHub
parent 45bee54aa0
commit 66df0a572f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 23 additions and 246 deletions

View file

@ -70,8 +70,6 @@ version["1"] = Object.assign({},
, "getReadOnlyID" : ["padID"]
, "setPublicStatus" : ["padID", "publicStatus"]
, "getPublicStatus" : ["padID"]
, "setPassword" : ["padID", "password"]
, "isPasswordProtected" : ["padID"]
, "listAuthorsOfPad" : ["padID"]
, "padUsersCount" : ["padID"]
}

View file

@ -219,7 +219,7 @@ exports.handleMessage = async function(client, message)
const {session: {user} = {}} = client.client.request;
const {accessStatus, authorID} =
await securityManager.checkAccess(padId, auth.sessionID, auth.token, auth.password, user);
await securityManager.checkAccess(padId, auth.sessionID, auth.token, user);
if (accessStatus !== 'grant') {
// Access denied. Send the reason to the user.
client.json.send({accessStatus});
@ -826,7 +826,7 @@ async function handleSwitchToPad(client, message, _authorID)
const newPadIds = await readOnlyManager.getIds(message.padId);
const {session: {user} = {}} = client.client.request;
const {accessStatus, authorID} = await securityManager.checkAccess(
newPadIds.padId, message.sessionID, message.token, message.password, user);
newPadIds.padId, message.sessionID, message.token, user);
if (accessStatus !== 'grant') {
// Access denied. Send the reason to the user.
client.json.send({accessStatus});
@ -868,7 +868,6 @@ function createSessionInfoAuth(sessionInfo, message)
sessionID: message.sessionID,
padID: message.padId,
token: message.token,
password: message.password,
};
}

View file

@ -58,7 +58,7 @@ exports.setSocketIO = function(_socket) {
// wrap the original send function to log the messages
client._send = client.send;
client.send = function(message) {
messageLogger.debug("to " + client.id + ": " + stringifyWithoutPassword(message));
messageLogger.debug(`to ${client.id}: ${JSON.stringify(message)}`);
client._send(message);
}
@ -69,14 +69,14 @@ exports.setSocketIO = function(_socket) {
client.on('message', async function(message) {
if (message.protocolVersion && message.protocolVersion != 2) {
messageLogger.warn("Protocolversion header is not correct:" + stringifyWithoutPassword(message));
messageLogger.warn(`Protocolversion header is not correct: ${JSON.stringify(message)}`);
return;
}
if (!message.component || !components[message.component]) {
messageLogger.error("Can't route the message:" + stringifyWithoutPassword(message));
messageLogger.error(`Can't route the message: ${JSON.stringify(message)}`);
return;
}
messageLogger.debug("from " + client.id + ": " + stringifyWithoutPassword(message));
messageLogger.debug(`from ${client.id}: ${JSON.stringify(message)}`);
await components[message.component].handleMessage(client, message);
});
@ -88,16 +88,3 @@ exports.setSocketIO = function(_socket) {
});
});
}
// returns a stringified representation of a message, removes the password
// this ensures there are no passwords in the log
function stringifyWithoutPassword(message)
{
let newMessage = Object.assign({}, message);
if (newMessage.password != null) {
newMessage.password = "xxx";
}
return JSON.stringify(newMessage);
}