Skip to content

Commit

Permalink
fix: consider query strings in Twilio request validation (RocketChat#…
Browse files Browse the repository at this point in the history
  • Loading branch information
julio-cfa authored Oct 15, 2024
1 parent bafbedc commit 50c4441
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 13 deletions.
5 changes: 5 additions & 0 deletions .changeset/grumpy-lamps-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixed Twilio request validation by accepting URLs with query strings
Original file line number Diff line number Diff line change
Expand Up @@ -245,19 +245,21 @@ export class Twilio implements ISMSProvider {
};
}

isRequestFromTwilio(signature: string, requestBody: object): boolean {
isRequestFromTwilio(signature: string, request: Request): boolean {
const authToken = settings.get<string>('SMS_Twilio_authToken');
const siteUrl = settings.get<string>('Site_Url');
let siteUrl = settings.get<string>('Site_Url');
if (siteUrl.endsWith('/')) {
siteUrl = siteUrl.replace(/.$/, '');
}

if (!authToken || !siteUrl) {
SystemLogger.error(`(Twilio) -> URL or Twilio token not configured.`);
return false;
}

const twilioUrl = siteUrl.endsWith('/')
? `${siteUrl}api/v1/livechat/sms-incoming/twilio`
: `${siteUrl}/api/v1/livechat/sms-incoming/twilio`;
return twilio.validateRequest(authToken, signature, twilioUrl, requestBody);
const twilioUrl = request.originalUrl ? `${siteUrl}${request.originalUrl}` : `${siteUrl}/api/v1/livechat/sms-incoming/twilio`;

return twilio.validateRequest(authToken, signature, twilioUrl, request.body);
}

validateRequest(request: Request): boolean {
Expand All @@ -267,7 +269,7 @@ export class Twilio implements ISMSProvider {
}
const twilioHeader = request.headers['x-twilio-signature'] || '';
const twilioSignature = Array.isArray(twilioHeader) ? twilioHeader[0] : twilioHeader;
return this.isRequestFromTwilio(twilioSignature, request.body);
return this.isRequestFromTwilio(twilioSignature, request);
}

error(error: Error & { reason?: string }): SMSProviderResponse {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,34 @@ describe('Twilio Request Validation', () => {
expect(twilio.validateRequest(request)).to.be.true;
});

it('should not validate a request when process.env.TEST_MODE is true', () => {
process.env.TEST_MODE = 'true';
it('should validate a request when process.env.TEST_MODE is false', () => {
process.env.TEST_MODE = 'false';

settingsStub.get.withArgs('SMS_Twilio_authToken').returns('test');
settingsStub.get.withArgs('Site_Url').returns('https://example.com');

const twilio = new Twilio();
const requestBody = {
To: 'test',
From: 'test',
Body: 'test',
};

const request = {
headers: {
'x-twilio-signature': 'test',
'x-twilio-signature': getSignature('test', 'https://example.com/api/v1/livechat/sms-incoming/twilio', requestBody),
},
body: requestBody,
};

expect(twilio.validateRequest(request)).to.be.true;
});

it('should validate a request when process.env.TEST_MODE is false', () => {
it('should validate a request when query string is present', () => {
process.env.TEST_MODE = 'false';

settingsStub.get.withArgs('SMS_Twilio_authToken').returns('test');
settingsStub.get.withArgs('Site_Url').returns('https://example.com');
settingsStub.get.withArgs('Site_Url').returns('https://example.com/');

const twilio = new Twilio();
const requestBody = {
Expand All @@ -93,8 +103,9 @@ describe('Twilio Request Validation', () => {
};

const request = {
originalUrl: '/api/v1/livechat/sms-incoming/twilio?department=1',
headers: {
'x-twilio-signature': getSignature('test', 'https://example.com/api/v1/livechat/sms-incoming/twilio', requestBody),
'x-twilio-signature': getSignature('test', 'https://example.com/api/v1/livechat/sms-incoming/twilio?department=1', requestBody),
},
body: requestBody,
};
Expand Down

0 comments on commit 50c4441

Please sign in to comment.