Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Corrige validação de URL para permitir localhost e endereços IP #1290

Merged
merged 1 commit into from
Mar 6, 2025

Conversation

jrCleber
Copy link
Contributor

@jrCleber jrCleber commented Mar 6, 2025

O isUrl do class-validator não valida URLs com localhost porque ele segue a especificação da WHATWG URL, que considera localhost um nome de host especial e pode não tratá-lo como um domínio válido.

Se você quiser uma validação mais rigorosa, que permita localhost, IPs e domínios válidos, pode usar esta regex aprimorada:

/^(https?:\/\/)(localhost|(\d{1,3}\.){3}\d{1,3}|([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,})(:\d+)?(\/.*)?$/

Este PR substitui a validação de URL que utilizava isUrl do class-validator por uma regex personalizada. A motivação para essa mudança é que isUrl, mesmo com a opção protocols: ['http', 'https'], não validava URLs que usam localhost.

A nova regex implementada agora permite:

  • URLs com http e https
  • localhost com ou sem porta (http://localhost, http://localhost:3000)
  • Endereços IP (http://192.168.1.1, https://10.0.0.1:8080)
  • Domínios válidos (https://example.com, http://sub.example.org)
  • Caminhos opcionais (https://example.com/api)

Essa alteração garante maior flexibilidade na configuração de webhooks, permitindo URLs locais e ambientes de desenvolvimento sem comprometer a segurança ou funcionalidade.

Alterações principais:

  • Substituição de isUrl pela regex /^(https?:\/\/)(localhost|(\d{1,3}\.){3}\d{1,3}|([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,})(:\d+)?(\/.*)?$/
  • Manutenção da compatibilidade com domínios, IPs e diferentes formatos de URL

Testes realizados:
✅ Testado com URLs locais (http://localhost, http://localhost:3000)
✅ Testado com IPs (http://127.0.0.1, https://192.168.0.1:8000)
✅ Testado com domínios (https://example.com, http://api.test.net)
✅ Testado com portas e caminhos opcionais

Impacto:
Esta mudança melhora a compatibilidade com ambientes locais e configurações personalizadas de webhook, garantindo uma validação mais robusta sem restringir casos de uso comuns

Summary by Sourcery

Replaces the isUrl validation with a custom regex to allow localhost and IP addresses in webhook URLs.

Bug Fixes:

  • Fixes an issue where the isUrl validator does not validate URLs with localhost.
  • Fixes an issue where the isUrl validator does not validate URLs with IP addresses.

Copy link

sourcery-ai bot commented Mar 6, 2025

Reviewer's Guide by Sourcery

The pull request replaces the isURL validator from class-validator with a custom regex to allow localhost and IP addresses in webhook URLs. This change enhances the flexibility of webhook configurations, particularly in local development environments, without compromising security.

Sequence diagram for webhook URL validation

sequenceDiagram
  participant User
  participant WebhookController
  participant CustomRegex

  User->>WebhookController: Sends webhook data with URL
  WebhookController->>CustomRegex: Validates URL using regex
  alt URL is valid
    WebhookController->>WebhookController: Processes webhook
  else URL is invalid
    WebhookController-->>User: Returns error
  end
Loading

File-Level Changes

Change Details Files
Replaced the class-validator's isURL validator with a custom regex to allow localhost and IP addresses in webhook URLs.
  • Replaced isURL(data.webhook.url, { require_tld: false }) with a regex test regex.test(data.webhook.url) to validate the webhook URL in the set method.
  • Replaced isURL(instance.url, { require_tld: false }) with a regex test regex.test(instance.url) to validate the webhook URL before sending the request.
  • Replaced isURL(globalURL) with a regex test regex.test(globalURL) to validate the global webhook URL before sending the request.
  • Added a regex /^(https?://)/ to validate URLs.
src/api/integrations/event/webhook/webhook.controller.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @jrCleber - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Consider defining the regex in a single place and reusing it to avoid inconsistencies.
  • The new regex only checks for https? at the beginning, which is less strict than the original isURL validation.
Here's what I looked at during the review
  • 🟡 General issues: 2 issues found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@@ -18,7 +17,7 @@ export class WebhookController extends EventController implements EventControlle
}

override async set(instanceName: string, data: EventDto): Promise<wa.LocalWebHook> {
if (!isURL(data.webhook.url, { require_tld: false })) {
if (!/^(https?:\/\/)/.test(data.webhook.url)) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question (bug_risk): Review the new URL validation logic using regex.

The previous implementation used isURL with specific options, which may have been more comprehensive. This regex only checks for the presence of a protocol prefix, so please ensure that this simplified check meets all your validation requirements.

@@ -78,6 +77,7 @@ export class WebhookController extends EventController implements EventControlle
const we = event.replace(/[.-]/gm, '_').toUpperCase();
const transformedWe = we.replace(/_/gm, '-').toLowerCase();
const enabledLog = configService.get<Log>('LOG').LEVEL.includes('WEBHOOKS');
const regex = /^(https?:\/\/)/;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consolidate URL validation logic.

Consider declaring and using a shared, well-documented constant for the URL validation regex across all methods. This will help avoid inconsistent usage, as the set method uses a literal regex while other parts rely on the declared variable.

Suggested implementation:

/**
 * Regex pattern for validating URLs starting with "http://" or "https://"
 */
const URL_VALIDATION_REGEX = /^(https?:\/\/)/;

// (Existing imports remain unchanged)
    if (!URL_VALIDATION_REGEX.test(data.webhook.url)) {
    // Removed local regex constant in favor of shared URL_VALIDATION_REGEX
          if (instance?.enabled && URL_VALIDATION_REGEX.test(instance.url)) {

Make sure that the new constant declaration is positioned appropriately (e.g. at the top of the file after the imports) and that no other part of the file uses a hard-coded regex. Adjust the location if your project's conventions require constants to be declared in a separate file.

@DavidsonGomes DavidsonGomes changed the base branch from main to develop March 6, 2025 19:59
@DavidsonGomes DavidsonGomes merged commit 13bdbc2 into EvolutionAPI:develop Mar 6, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants