security: Fix authorization bypass vulnerability

Before, a malicious user could bypass authorization restrictions
imposed by the authorize hook:

 * Step 1: Fetch any resource that the malicious user is authorized to
   access (e.g., static content).
 * Step 2: Use the signed express_sid cookie generated in step 1 to
   create a socket.io connection.
 * Step 3: Perform the CLIENT_READY handshake for the desired pad.
 * Step 4: Profit!

Now the authorization decision made by the authorize hook is
propagated to SecurityManager so that it can approve or reject
socket.io messages as appropriate.

This also sets up future support for per-user read-only and
modify-only (no create) authorization levels.
This commit is contained in:
Richard Hansen 2020-09-11 19:26:26 -04:00 committed by John McLear
parent ae1142a799
commit b80a37173e
4 changed files with 63 additions and 25 deletions

View file

@ -178,7 +178,7 @@ describe('socket.io access checks', () => {
settings.requireAuthentication = true;
await assert.rejects(connect(null), {message: /signed express_sid cookie is required/i});
});
xit('authorization bypass attempt -> error', async () => {
it('authorization bypass attempt -> error', async () => {
plugins.hooks.authorize = [{hook_fn: (hookName, {req}, cb) => {
if (req.session.user == null) return cb([]); // Hasn't authenticated yet.
// Only allowed to access /p/pad.