Skip to content

Commit

Permalink
Add an optional handler for invalid request signature error
Browse files Browse the repository at this point in the history
  • Loading branch information
dophsquare committed Jul 2, 2024
1 parent 8e49f7b commit 04820f1
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/receivers/AwsLambdaReceiver.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,11 @@ describe('AwsLambdaReceiver', function () {
});

it('should detect invalid signature', async (): Promise<void> => {
const spy = sinon.spy();
const awsReceiver = new AwsLambdaReceiver({
signingSecret: 'my-secret',
logger: noopLogger,
invalidRequestSignatureHandler: spy,
});
const handler = awsReceiver.toHandler();
const timestamp = Math.floor(Date.now() / 1000);
Expand Down Expand Up @@ -504,6 +506,7 @@ describe('AwsLambdaReceiver', function () {
(_error, _result) => {},
);
assert.equal(response.statusCode, 401);
assert(spy.calledOnce);
});

it('should detect too old request timestamp', async (): Promise<void> => {
Expand Down
23 changes: 22 additions & 1 deletion src/receivers/AwsLambdaReceiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ export interface AwsEvent {

export type AwsCallback = (error?: Error | string | null, result?: any) => void;

export interface ReceiverInvalidRequestSignatureHandlerArgs {
rawBody: string;
signature: string;
ts: number;
}

export interface AwsResponse {
statusCode: number;
headers?: {
Expand Down Expand Up @@ -76,6 +82,7 @@ export interface AwsLambdaReceiverOptions {
* @default noop
*/
customPropertiesExtractor?: (request: AwsEvent) => StringIndexed;
invalidRequestSignatureHandler?: (args: ReceiverInvalidRequestSignatureHandlerArgs) => void;
}

/*
Expand All @@ -95,12 +102,15 @@ export default class AwsLambdaReceiver implements Receiver {

private customPropertiesExtractor: (request: AwsEvent) => StringIndexed;

private invalidRequestSignatureHandler: (args: ReceiverInvalidRequestSignatureHandlerArgs) => void;

public constructor({
signingSecret,
logger = undefined,
logLevel = LogLevel.INFO,
signatureVerification = true,
customPropertiesExtractor = (_) => ({}),
invalidRequestSignatureHandler,
}: AwsLambdaReceiverOptions) {
// Initialize instance variables, substituting defaults for each value
this.signingSecret = signingSecret;
Expand All @@ -112,6 +122,11 @@ export default class AwsLambdaReceiver implements Receiver {
return defaultLogger;
})();
this.customPropertiesExtractor = customPropertiesExtractor;
if (invalidRequestSignatureHandler) {
this.invalidRequestSignatureHandler = invalidRequestSignatureHandler;
} else {
this.invalidRequestSignatureHandler = this.defaultInvalidRequestSignatureHandler;
}
}

public init(app: App): void {
Expand Down Expand Up @@ -171,7 +186,7 @@ export default class AwsLambdaReceiver implements Receiver {
const signature = this.getHeaderValue(awsEvent.headers, 'X-Slack-Signature') as string;
const ts = Number(this.getHeaderValue(awsEvent.headers, 'X-Slack-Request-Timestamp'));
if (!this.isValidRequestSignature(this.signingSecret, rawBody, signature, ts)) {
this.logger.info(`Invalid request signature detected (X-Slack-Signature: ${signature}, X-Slack-Request-Timestamp: ${ts})`);
this.invalidRequestSignatureHandler({ rawBody, signature, ts });
return Promise.resolve({ statusCode: 401, body: '' });
}
}
Expand Down Expand Up @@ -313,4 +328,10 @@ export default class AwsLambdaReceiver implements Receiver {
const caseInsensitiveKey = Object.keys(headers).find((it) => key.toLowerCase() === it.toLowerCase());
return caseInsensitiveKey !== undefined ? headers[caseInsensitiveKey] : undefined;
}

private defaultInvalidRequestSignatureHandler(args: ReceiverInvalidRequestSignatureHandlerArgs): void {
const { signature, ts } = args;

this.logger.info(`Invalid request signature detected (X-Slack-Signature: ${signature}, X-Slack-Request-Timestamp: ${ts})`);
}
}

0 comments on commit 04820f1

Please sign in to comment.