Skip to content

Instantly share code, notes, and snippets.

@freakynit
Created February 25, 2025 03:11
Show Gist options
  • Save freakynit/626fd70ada4d691663da8b1444795438 to your computer and use it in GitHub Desktop.
Save freakynit/626fd70ada4d691663da8b1444795438 to your computer and use it in GitHub Desktop.
o3-mini-high generated review for https://github.com/BH3GEI/CloudflareWorkerProxy

1. Overall Architecture

  • Structure & Flow:
    Your code follows a common Cloudflare Workers pattern:

    • An event listener intercepts fetch events.
    • The handleRequest() function rewrites the incoming URL, creates a new request with modified headers, forwards it to the target server, and then post-processes the response (rewriting redirects, CORS, cookies, and even HTML content).
  • HTML Rewriting:
    You’re using Cloudflare’s HTMLRewriter to adjust links (a[href]), images (img[src]), and form actions (form[action]). This is a good approach for making proxied HTML interactive through your proxy.


2. Potential Issues & Bugs

URL Handling

  • Target URL Extraction:
    When the request’s host matches myURL.host, you do:

    if (url.pathname.startsWith('/')) {
      targetURL = new URL(url.pathname.substring(1))
    } else {
      targetURL = new URL(url.pathname)
    }
    • Issue: The substring (e.g. "https://example.com/path" when passed as "https://example.com/path" without a leading protocol) assumes the path will always contain a full URL. If the user submits a relative URL or an unexpected format, new URL(...) may throw an error.
    • Suggestion: Consider providing an explicit base URL when constructing new URLs or add extra validation to ensure you’re dealing with a valid absolute URL.
  • Relative URL Fallback:
    The block:

    if (!targetURL.toString().startsWith('http')) {
      targetURL = new URL(targetURL, `https://${myURL.hostname}/${new URL(request.url).protocol}////${request.url.host.toString()}/`)
    }

    is intended to “fix” relative URLs, but:

    • Issue: The string used as the base (with multiple slashes and mixing in the protocol) is confusing and may lead to malformed URLs.
    • Suggestion: Refactor this logic for clarity. Use a consistent method to construct absolute URLs from relative ones (possibly with a well-defined base URL) rather than relying on string concatenation with odd slash patterns.

Header & Request Modifications

  • Host and Origin Headers:
    You set:

    newHeader.set('host', targetURL.host)
    newHeader.set('origin', targetURL.host)
    • Issue: Overriding these headers might cause issues if the target server expects the original host or a specific origin.
    • Suggestion: Verify that the target service accepts these modifications. Sometimes preserving the original Host header (or using a custom header) can be beneficial.
  • SSL Verification Disabled:
    You disable SSL verification with:

    cf: { ssl: { verify: false } }
    • Issue: This is insecure in production unless you have a specific reason (e.g., testing against a self‐signed certificate).
    • Suggestion: Only disable SSL verification when absolutely necessary, and document why it’s disabled.
  • Redirect Handling:
    When a Location header exists in the response:

    location = new URL(myURL.toString() + response.url).toString()
    • Issue: This concatenation may not properly handle relative URLs or complex query strings.
    • Suggestion: Consider using URL resolution (e.g. new URL(location, myURL)) to better manage relative/absolute paths.
  • Cookie Handling:
    You split the Set-Cookie header on commas:

    const cookies = setCookieHeader.split(',').map()
    • Issue: Cookie values can legally contain commas. Splitting on commas might break cookies that include such characters.
    • Suggestion: Handle multiple Set-Cookie headers individually. The Headers API in Cloudflare Workers supports multiple headers with the same name.

HTML Rewriting

  • URL Rewrite Condition:
    In your rewriteSomething class:

    if (!eleThings.startsWith('http') || !eleThings.startsWith('https')) {  }
    • Issue: This condition is logically flawed. For example, if eleThings is "http://example.com", it starts with "http", so the first part is false—but it does not start with "https", making the second part true. Overall, the condition always ends up true (except for URLs starting with both, which is impossible).
    • Suggestion: Change the logic to use AND instead of OR:
      if (!eleThings.startsWith('http://') && !eleThings.startsWith('https://')) {  }
      This way, you correctly detect relative URLs.
  • Inconsistent Attribute Handling in Form Rewriting:
    In your rewriteAction class:

    if (!action.startsWith('http')) {
      element.setAttribute('action', `https://${myURL.hostname}/${new URL(this.request).protocol}//${this.request.host.toString()}${action}`)
    } else {
      element.setAttribute('href', `https://${myURL.hostname}/${action}`)
    }
    • Issue: For form elements, you should consistently update the action attribute. The else branch mistakenly sets the href attribute, which doesn’t affect form submission.
    • Suggestion: Modify the else branch to update action instead of href.
  • Multiple Slash Patterns:
    The URL rewriting uses patterns like //// or //.

    • Issue: These patterns can be confusing and may lead to unexpected URL formats.
    • Suggestion: Clearly document why these extra slashes are used (if they’re needed to avoid path collisions or for other reasons) or refactor to a more standardized URL construction approach.

Miscellaneous

  • Debug Logging:
    You have several console.log statements.

    • Issue: While useful for debugging, leaving these in production code can clutter logs and potentially leak sensitive information.
    • Suggestion: Remove or conditionally enable these logs based on an environment variable or debug flag.
  • Handling of Request Body:
    Passing request.body directly works in many cases, but be mindful that if the body is a stream and has been read earlier, it might not be available when forwarding the request. Ensure that the request’s body hasn’t been consumed before you pass it to the new Request.


3. Recommendations for Improvement

  • Refactor URL Parsing:

    • Use a consistent and robust method for converting incoming paths into absolute target URLs.
    • Consider validating the URL early and handling errors more gracefully.
  • Correct Logical Operators:

    • Update the URL rewriting conditions in both rewriteSomething and rewriteAction to properly detect relative URLs (i.e. use && instead of ||).
  • Standardize HTML Rewriting:

    • Ensure that form elements always have their action attribute rewritten, not the href attribute.
  • Cookie Parsing:

    • Look into more robust cookie parsing methods that account for commas within cookie values. Alternatively, if Cloudflare Workers support multiple headers for cookies, use that feature.
  • Security Considerations:

    • Revisit the decision to disable SSL verification. If you must disable it, make sure it’s clearly documented and ideally limited to non-production environments.
  • Clean Up Logging:

    • Remove or conditionally include debug logging to avoid unnecessary output in production.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment