response-url-validator.ts 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import { URL } from 'node:url';
  2. const ALLOWED_SLACK_HOST = 'hooks.slack.com';
  3. export function isValidResponseUrl(
  4. responseUrl: string,
  5. slackbotProxyUri?: string,
  6. ): boolean {
  7. try {
  8. const parsedUrl = new URL(responseUrl);
  9. // Case 1: Direct to Slack
  10. if (
  11. parsedUrl.protocol === 'https:' &&
  12. parsedUrl.hostname === ALLOWED_SLACK_HOST
  13. ) {
  14. return true;
  15. }
  16. // Case 2: Via slackbot-proxy
  17. if (slackbotProxyUri) {
  18. const parsedProxyUri = new URL(slackbotProxyUri);
  19. if (
  20. (parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:') &&
  21. parsedUrl.hostname === parsedProxyUri.hostname &&
  22. parsedUrl.pathname === '/g2s/respond'
  23. ) {
  24. const slackResponseUrlParam =
  25. parsedUrl.searchParams.get('response_url');
  26. if (slackResponseUrlParam) {
  27. // Recursively validate the response_url parameter
  28. return isValidResponseUrl(slackResponseUrlParam); // No proxy URI for the inner check
  29. }
  30. }
  31. }
  32. return false;
  33. } catch {
  34. // Invalid URL format
  35. return false;
  36. }
  37. }