Skip to content

Relax monitor URL validation #2632

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

Merged

Conversation

Yasir-Rafique
Copy link
Contributor

@Yasir-Rafique Yasir-Rafique commented Jul 18, 2025

Describe your changes

Relaxed the monitor URL validation logic to allow Docker internal hostnames (such as containername) in addition to fully qualified domains and IP addresses. This makes it possible to monitor Docker containers by name in local/dev environments, as requested.

Write your issue number after "Fixes "

Fixes #2605

Please ensure all items are checked off before requesting a review. "Checked off" means you need to add an "x" character between brackets so they turn into checkmarks.

  • (Do not skip this or your PR will be closed) I deployed the application locally.
  • (Do not skip this or your PR will be closed) I have performed a self-review and testing of my code.
  • I have included the issue # in the PR.
  • I have added i18n support to visible strings (instead of <div>Add</div>, use):
const { t } = useTranslation();
<div>{t('add')}</div>
  • I have not included any files that are not related to my pull request, including package-lock and package-json if dependencies have not changed
  • I didn't use any hardcoded values (otherwise it will not scale, and will make it difficult to maintain consistency across the application).
  • I made sure font sizes, color choices etc are all referenced from the theme. I don't have any hardcoded dimensions.
  • My PR is granular and targeted to one specific feature.
  • I ran npm run format in server and client directories, which automatically formats your code.
  • I took a screenshot or a video and attached to this PR if there is a UI change.

Summary by CodeRabbit

  • Bug Fixes
    • Improved URL validation to support both full URLs with protocols and Docker/internal hostnames without protocols.
    • Enhanced error messages to provide clearer guidance on invalid or empty URL inputs.

Copy link

coderabbitai bot commented Jul 18, 2025

Walkthrough

The URL validation logic in the monitor creation form was replaced with a new approach that distinguishes URLs starting with "http://" or "https://" and validates them using URL.canParse(). URLs without protocol are validated as Docker/internal hostnames with detailed label checks, rejecting invalid formats and providing clearer error messages.

Changes

File(s) Summary of Changes
client/src/Validation/validation.js Replaced single regex URL validation with a three-case validation: protocol URLs parsed by URL.canParse(), non-protocol URLs validated as Docker/internal hostnames with label checks, else invalid URL error.
server/validation/joi.js Updated createMonitorBodyValidation schema to use a custom validator that checks URLs with protocol via URL.canParse() and validates Docker/internal hostnames without protocol, adding detailed label checks and custom error messages.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Form
    participant Validation

    User->>Form: Enter URL in monitor form
    Form->>Validation: Validate URL
    alt URL starts with http:// or https://
        Validation->>Validation: Use URL.canParse() to validate
        alt Valid URL
            Validation->>Form: Accept value
        else
            Validation->>Form: Return "string.invalidUrl" error
        end
    else URL without protocol
        Validation->>Validation: Validate as Docker/internal hostname with label checks
        alt Valid hostname
            Validation->>Form: Accept value
        else
            Validation->>Form: Return "string.invalidUrl" error
        end
    end
Loading

Why did the Canadian developer apologize to the American developer after changing the validation logic? Because he didn’t want to cause any regex border issues, eh!


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ffd9a5 and 945cff9.

📒 Files selected for processing (2)
  • client/src/Validation/validation.js (1 hunks)
  • server/validation/joi.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/validation/joi.js
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: ceskyDJ
PR: bluewave-labs/Checkmate#2410
File: client/src/Pages/Settings/SettingsAbout.jsx:23-25
Timestamp: 2025-06-08T14:56:37.007Z
Learning: User ceskyDJ appropriately manages PR scope by focusing on i18n changes and not addressing unrelated pre-existing technical debt in the same PR, demonstrating good software development practices.
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 200a933 and 066df2c.

📒 Files selected for processing (1)
  • client/src/Validation/validation.js (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: ceskyDJ
PR: bluewave-labs/Checkmate#2410
File: client/src/Pages/Settings/SettingsAbout.jsx:23-25
Timestamp: 2025-06-08T14:56:37.007Z
Learning: User ceskyDJ appropriately manages PR scope by focusing on i18n changes and not addressing unrelated pre-existing technical debt in the same PR, demonstrating good software development practices.
🔇 Additional comments (1)
client/src/Validation/validation.js (1)

160-165: LGTM! The fallback validation logic is well-implemented.

The fallback to the original complex regex and proper error handling maintains backward compatibility while supporting the new Docker container name validation. This two-step approach is like having both a friendly Canadian greeting and a formal American handshake - it covers all the bases!

Comment on lines 131 to 135
const noProtocol = value.replace(/^(https?:\/\/)/, "");

if (/^[a-zA-Z0-9-]+(:\d{1,5})?$/.test(noProtocol)) {
return value;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix port range validation and improve hostname pattern.

The current simple validation has a couple of issues that need addressing:

  1. Port range validation: The regex :\d{1,5} allows ports up to 99999, but valid ports are 1-65535. Like a Canadian apologizing for American healthcare costs, this is way too generous!

  2. Hostname validation: The pattern doesn't prevent hostnames from starting/ending with hyphens or having consecutive hyphens, which violates RFC standards.

Apply this diff to fix the validation:

-				if (/^[a-zA-Z0-9-]+(:\d{1,5})?$/.test(noProtocol)) {
+				if (/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])*(:(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}))?$/.test(noProtocol)) {
					return value;
				}

This ensures:

  • Hostnames don't start/end with hyphens
  • Port numbers are within the valid range (1-65535)
  • Maintains support for Docker container names
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const noProtocol = value.replace(/^(https?:\/\/)/, "");
if (/^[a-zA-Z0-9-]+(:\d{1,5})?$/.test(noProtocol)) {
return value;
}
const noProtocol = value.replace(/^(https?:\/\/)/, "");
if (/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])*(:(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}))?$/.test(noProtocol)) {
return value;
}
🤖 Prompt for AI Agents
In client/src/Validation/validation.js around lines 131 to 135, the current
regex for validating hostnames and ports is too permissive, allowing invalid
port numbers up to 99999 and hostnames starting or ending with hyphens or
containing consecutive hyphens. Update the regex to enforce that hostnames do
not start or end with hyphens and do not have consecutive hyphens, and refine
the port validation to only allow numbers from 1 to 65535. This will ensure
compliance with RFC standards and proper port range validation while still
supporting Docker container names.

Copy link

@llamapreview llamapreview bot left a comment

Choose a reason for hiding this comment

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

Auto Pull Request Review from LlamaPReview

1. Overview

1.1 Core Changes

  • Primary purpose and scope: Relax URL validation for monitor URLs to allow Docker internal hostnames (like containername) in addition to FQDNs and IP addresses
  • Key components modified: Client-side validation logic in client/src/Validation/validation.js
  • Cross-component impacts: Requires corresponding server-side validation updates for security consistency
  • Business value alignment: Improves developer experience in local/Docker environments per user request (#2605)

1.2 Technical Architecture

  • System design modifications: Validation logic now supports two distinct URL patterns
  • Component interaction changes: Client validation no longer rejects Docker internal names
  • Integration points impact: Monitor creation API needs matching validation rules
  • Dependency changes and implications: Server must resolve Docker internal hostnames

2. Critical Findings

2.1 Must Fix (P0🔴)

Issue: Flawed regex for Docker hostnames blocks valid patterns like containername.localhost

  • Analysis Confidence: High
  • Impact: Fails to solve original issue #2605 as common Docker patterns remain invalid
  • Resolution: Update regex to ^[a-zA-Z0-9.-]+(:\d{1,5})?$ to allow dots in hostnames

Issue: Missing server-side validation for relaxed URL format

  • Analysis Confidence: High
  • Impact: Security vulnerability (SSRF risk) if client validation bypassed via direct API calls
  • Resolution: Implement matching server-side validation with protocol/IP restrictions

Issue: No unit tests for new validation logic

  • Analysis Confidence: High
  • Impact: High risk of regressions and undetected edge case failures
  • Resolution: Add comprehensive test cases covering Docker, FQDN, IP, and invalid URLs

2.2 Should Fix (P1🟡)

Issue: Generic error message for URL validation failures

  • Analysis Confidence: Medium
  • Impact: Poor UX when users can't distinguish between hostname/port/format issues
  • Suggested Solution: Implement specific error messages for different failure types

2.3 Consider (P2🟢)

Area: Documentation of validation logic

  • Analysis Confidence: Medium
  • Improvement Opportunity: Better maintainability through comments explaining two-step validation approach

2.4 Summary of Action Items

  1. Immediately fix Docker hostname regex and add server-side validation (P0)
  2. Implement unit tests before merge (P0)
  3. Improve error messaging (P1 - can be post-merge)
  4. Add code comments (P2 - optional)

3. Technical Analysis

3.1 Code Logic Analysis

📁 client/src/Validation/validation.js - URL validation logic

  • Submitted PR Code:
    custom((value, helpers) => {
      const noProtocol = value.replace(/^(https?:\/\/)/, "");
      
      if (/^[a-zA-Z0-9-]+(:\d{1,5})?$/.test(noProtocol)) {
        return value;
      }
      
      // Existing complex URL validation
      if (urlRegex.test(value)) {
        return value;
      }
      return helpers.error("string.invalidUrl");
    })
  • Analysis:
    • Current logic incorrectly blocks valid Docker hostnames with dots (e.g., service.network)
    • Error message doesn't help users diagnose specific validation failures
    • Lack of tests makes regression likely during future changes
    • Server-side validation missing creates security gap
  • LlamaPReview Suggested Improvements:
    custom((value, helpers) => {
      // Strip protocol prefix if present
      const noProtocol = value.replace(/^(https?:\/\/)/, "");
      
      // Updated regex allows dots in hostnames (e.g., 'service.network:8080')
      if (/^[a-zA-Z0-9.-]+(:\d{1,5})?$/.test(noProtocol)) {
        return value;
      }
      
      // Existing complex URL validation as fallback
      if (urlRegex.test(value)) {
        return value;
      }
      
      // Provide more specific error (implementation details in 2.2)
      return helpers.error("string.invalidUrl");
    })
  • Improvement rationale:
    • Allows Docker-compatible hostnames with dots per original requirement
    • Maintains backward compatibility with existing URL formats
    • Reduces false negatives while preserving security

3.2 Key Quality Aspects

  • Testing strategy and coverage: Must add unit tests covering:
    • Valid: containername, service.network, 192.168.1.1:8080, https://example.com
    • Invalid: http:///invalid, bad$hostname, :portonly
  • Security considerations: Server must validate URLs before use to prevent SSRF attacks

4. Overall Evaluation

  • Technical assessment: Solution partially addresses requirement but introduces security gaps and incomplete validation
  • Business impact: Critical for Docker-based deployments once validation issues resolved
  • Risk evaluation: High risk in current state (security + incomplete solution)
  • Notable positive aspects: Good two-step validation approach, clean implementation
  • Implementation quality: Requires improvements to validation logic and testing
  • Final recommendation: Request Changes - Must fix regex, add server validation, and implement tests

💡 LlamaPReview Community
Have feedback on this AI Code review tool? Join our GitHub Discussions to share your thoughts and help shape the future of LlamaPReview.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
server/validation/joi.js (1)

171-216: Great implementation of relaxed URL validation!

The two-step validation approach effectively addresses the PR objective of allowing Docker container names while maintaining backward compatibility. The logic is sound and the custom error messages provide clear guidance to users.

However, there are a few areas for improvement:

  1. Simple pattern could be more restrictive: The current pattern /^[a-zA-Z0-9.-]+(:\d{1,5})?$/ allows consecutive dots (e.g., container..name), which aren't valid in hostnames.

  2. Complex regex maintainability: That regex is longer than a Canadian winter! Consider extracting it to a constant or using a well-tested URL validation library.

Consider tightening the simple pattern:

-			if (/^[a-zA-Z0-9.-]+(:\d{1,5})?$/.test(noProtocol)) {
+			if (/^[a-zA-Z0-9]([a-zA-Z0-9.-]*[a-zA-Z0-9])?(:\d{1,5})?$/.test(noProtocol)) {

This prevents consecutive dots and ensures hostnames start/end with alphanumeric characters.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 066df2c and b823f0f.

📒 Files selected for processing (2)
  • client/src/Validation/validation.js (1 hunks)
  • server/validation/joi.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • client/src/Validation/validation.js
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: ceskyDJ
PR: bluewave-labs/Checkmate#2410
File: client/src/Pages/Settings/SettingsAbout.jsx:23-25
Timestamp: 2025-06-08T14:56:37.007Z
Learning: User ceskyDJ appropriately manages PR scope by focusing on i18n changes and not addressing unrelated pre-existing technical debt in the same PR, demonstrating good software development practices.

Copy link
Collaborator

@ajhollid ajhollid left a comment

Choose a reason for hiding this comment

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

I think this is a bit to permissive, this will allow many invalid URLs to be entered.

Why don't we consider using URL.canParse to validate here insteaed of regex?

Using that as a first pass with some regex for things like protocol after that should be sufficient.

@Yasir-Rafique
Copy link
Contributor Author

I’ve updated the validation to use URL.canParse() as the primary check for all standard URLs (as suggested), and a strict, label-wise regex for Docker/internal hostnames (including checks for consecutive dots and leading/trailing dashes or empty labels).
All edge cases are covered, and the logic is easy to maintain.

@Yasir-Rafique Yasir-Rafique requested a review from ajhollid July 19, 2025 06:56
Copy link
Collaborator

@ajhollid ajhollid left a comment

Choose a reason for hiding this comment

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

This seems to be a good balance of permisiveness and validation, let's go with this for now unless issues arise.

Thanks for your contribution!

@ajhollid ajhollid merged commit 1eea0b6 into bluewave-labs:develop Jul 21, 2025
1 check passed
@ajhollid
Copy link
Collaborator

@Yasir-Rafique this validation is disallowing URLs like www.google.com/404, I'm going to have to revert this.

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.

Remove validation from Monitor URL field
2 participants