Skip to content

Commit

Permalink
Improve security for error message passing
Browse files Browse the repository at this point in the history
Closes: #245

PR-URL: #257
  • Loading branch information
tshemsedinov committed Oct 12, 2021
1 parent f67f81e commit 1a2904c
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 21 deletions.
30 changes: 16 additions & 14 deletions lib/channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ class Channel {
}
const packet = metautil.jsonParse(data);
if (!packet) {
this.error(500, new Error('JSON parsing error'));
const error = new Error('JSON parsing error');
this.error(400, { error, pass: true });
return;
}
const [callType, target] = Object.keys(packet);
Expand All @@ -108,57 +109,58 @@ class Channel {
this.rpc(callId, interfaceName, methodName, args);
return;
}
this.error(500, new Error('Packet structure error'));
const error = new Error('Packet structure error');
this.error(400, { callId, error, pass: true });
}

async rpc(callId, interfaceName, methodName, args) {
const { application, session, client } = this;
const [iname, ver = '*'] = interfaceName.split('.');
const proc = application.getMethod(iname, ver, methodName);
if (!proc) {
this.error(404, null, callId);
this.error(404, { callId });
return;
}
try {
await proc.enter();
} catch {
this.error(504, null, callId);
this.error(503, { callId });
return;
}
const context = session ? session.context : { client };
if (!this.session && proc.access !== 'public') {
this.error(403, null, callId);
this.error(403, { callId });
return;
}
let result = null;
try {
result = await proc.invoke(context, args);
} catch (err) {
const code = err.message === 'Timeout reached' ? 408 : 500;
this.error(code, err, callId);
} catch (error) {
const timedout = error.message === 'Timeout reached';
const code = timedout ? 408 : 500;
this.error(code, { callId, error, pass: timedout });
return;
} finally {
proc.leave();
}
if (typeof result === 'object' && result.constructor.name === 'Error') {
this.error(result.code, result, callId);
this.error(result.code, { callId, error: result, pass: true });
return;
}
this.send({ callback: callId, result });
const record = `${this.ip}\t${interfaceName}/${methodName}`;
application.console.log(record);
}

error(code, err = null, callId) {
error(code, { callId, error = null, pass = false } = {}) {
const { req, ip, application } = this;
const { url, method } = req;
const status = http.STATUS_CODES[code];
const message = status || err.message || 'Unknown error';
const message = pass ? error.message : status || 'Unknown error';
const httpCode = status ? code : 500;
const reason = `${httpCode}\t${err ? err.stack : message}`;
const reason = `${httpCode}\t${error ? error.stack : status}`;
application.console.error(`${ip}\t${method}\t${url}\t${reason}`);
const error = { message, code };
const packet = callId ? { callback: callId, error } : { error };
const packet = { callback: callId, error: { message, code } };
this.send(packet, httpCode);
}

Expand Down
6 changes: 3 additions & 3 deletions lib/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ class HttpChannel extends Channel {
const { application, client } = this;
const callId = -1;
if (!proc) {
this.error(404, null, callId);
this.error(404, { callId });
return;
}
const context = { client };
let result = null;
try {
result = await proc.invoke(context, { method: methodName, args });
} catch (err) {
this.error(500, err, callId);
} catch (error) {
this.error(500, { callId, error });
return;
}
this.send(result);
Expand Down
7 changes: 4 additions & 3 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ class Server {
if (data.length > 0) {
args = metautil.jsonParse(data);
if (!args) {
channel.error(500, new Error('JSON parsing error'));
const error = new Error('JSON parsing error');
channel.error(500, { error, pass: true });
return;
}
}
Expand All @@ -108,8 +109,8 @@ class Server {
else channel.rpc(-1, interfaceName, methodName, args);
});
}
body.catch((err) => {
channel.error(500, err);
body.catch((error) => {
channel.error(500, { error });
});
}

Expand Down
8 changes: 7 additions & 1 deletion metacom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ export class Session {
constructor(token: string, channel: Channel, data: any);
}

export interface ErrorOptions {
callId?: number;
error?: Error;
pass?: boolean;
}

export class Channel {
application: object;
req: ClientRequest;
Expand All @@ -57,7 +63,7 @@ export class Channel {
): Promise<void>;
restoreSession(): Promise<Session | null>;
destroy(): void;
error(code: number, err?: boolean, callId?: number): void;
error(code: number, errorOptions?: ErrorOptions): void;
}

export class HttpChannel extends Channel {
Expand Down

0 comments on commit 1a2904c

Please sign in to comment.