Skip to content

Allow localhost in audio proxy#222

Open
Aiuanyu wants to merge 1 commit intomainfrom
feat-audio-proxy-localhost-4917574039415082794
Open

Allow localhost in audio proxy#222
Aiuanyu wants to merge 1 commit intomainfrom
feat-audio-proxy-localhost-4917574039415082794

Conversation

@Aiuanyu
Copy link
Copy Markdown
Owner

@Aiuanyu Aiuanyu commented Mar 21, 2026

Updated the audio proxy system to support localhost URLs, enabling local development and testing of audio features. The implementation whitelists http://localhost and https://localhost (including various ports) using a secure regex check in both the server-side proxy function and the client-side proxy application logic. verified that malicious domain-prefix attempts are blocked.

Fixes #221


PR created automatically by Jules for task 4917574039415082794 started by @Aiuanyu

Updated `functions/audio-proxy.js` and `main.js` to securely whitelist
`localhost` target URLs (both HTTP and HTTPS). The implementation uses a
regex to prevent domain-prefix bypasses (e.g., localhost.attacker.com).
This change facilitates local development and testing with local audio
assets.

Co-authored-by: Aiuanyu <93833368+Aiuanyu@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces crucial enhancements to the audio proxy system by integrating support for localhost URLs. This change significantly improves the local development and testing workflow for audio-related functionalities. The implementation ensures security by carefully whitelisting localhost addresses using a robust regex in both the server-side proxy function and the client-side application logic, while still preventing unauthorized access from other domains.

Highlights

  • Localhost Support: The audio proxy system now supports localhost URLs, enabling local development and testing of audio features.
  • Secure Whitelisting: Both server-side and client-side proxy logic have been updated to securely whitelist http://localhost and https://localhost (including various ports) using a regular expression.
  • Security Verification: Malicious domain-prefix attempts are verified to be blocked, maintaining security while adding flexibility.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying hakspring with  Cloudflare Pages  Cloudflare Pages

Latest commit: c1e777b
Status: ✅  Deploy successful!
Preview URL: https://04ffee11.hakspring.pages.dev
Branch Preview URL: https://feat-audio-proxy-localhost-4.hakspring.pages.dev

View logs

@claude
Copy link
Copy Markdown

claude bot commented Mar 21, 2026

PR Review: Allow localhost in audio proxy

Overall, the goal is clear and the regex is correctly constructed. However, there are a few issues worth addressing before merging.


🚨 Critical: server.log must not be committed

The PR includes server.log (379 lines of local development server output). This is a dev artifact and should not be in version control. Please:

  1. Remove server.log from this PR.
  2. Add server.log (or *.log) to .gitignore to prevent it happening again.

🔴 Security concern: localhost in the server-side proxy (functions/audio-proxy.js)

Allowing localhost in the server-side Cloudflare Pages function is a significant security risk that is different from allowing it on the client side.

When the proxy function runs on the server, localhost resolves to the proxy server itself, not the developer's machine. This means an attacker could craft a request like:

/audio-proxy?url=http://localhost:8080/internal-api

...and use your public proxy to probe or exfiltrate data from any internal services running on the same host. This is a classic Server-Side Request Forgery (SSRF) vector.

Recommendation: Remove the isLocalhost check from functions/audio-proxy.js entirely. Localhost audio files during local development should be served directly by the dev server without going through the proxy — there's no cross-origin restriction between localhost origins in a local dev setup.

// functions/audio-proxy.js — keep only the production allowlist
if (!targetUrl.startsWith('https://elearning.hakka.gov.tw/')) {
  return new Response('Invalid target URL', { status: 403 });
}

The isLocalhost check in main.js (client-side) is fine — it just decides whether to route through the proxy at all, and localhost URLs on the client won't reach the production proxy function.


✅ What's done well

  • Regex is correct: /^https?:\/\/localhost([:/]|$)/ properly anchors to the start and requires a port separator, path, or end-of-string after localhost, blocking subdomain abuse like localhost.evil.com. Good defensive thinking.
  • main.js early-return refactor: The if (!url) return url; extraction is a small but clean readability improvement.
  • Client-side logic: Routing localhost audio URLs through the proxy on the client side is reasonable for development and is harmless.

ℹ️ No tests added

The URL validation logic has no automated tests. Consider adding unit tests for the regex — specifically edge cases like:

  • http://localhost/
  • http://localhost:8080/audio.mp3
  • http://localhost.evil.com/ ❌ (must be blocked)
  • https://elearning.hakka.gov.tw.evil.com/ ❌ (already blocked by startsWith)

Summary

File Status
server.log ❌ Remove — do not commit dev artifacts
functions/audio-proxy.js ⚠️ Remove localhost allowlist — SSRF risk
main.js ✅ Looks good

Please remove server.log and drop the isLocalhost check from the server-side proxy function before merging.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly implements support for localhost URLs in the audio proxy, which is a valuable addition for local development. The changes in functions/audio-proxy.js and main.js are functional. However, I've found a critical issue with the inclusion of a server log file, which exposes local environment details and should be removed from version control. I've also noted that the URL validation logic is duplicated across two files, and I've provided suggestions to improve maintainability by refactoring this.

@@ -0,0 +1,379 @@
127.0.0.1 - - [21/Mar/2026 12:23:53] "GET / HTTP/1.1" 200 -
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

This log file should not be committed to the repository. It contains environment-specific information and does not belong in version control. Please remove this file from the pull request and add server.log (or a more general pattern like *.log) to your .gitignore file to prevent it from being accidentally committed in the future.

Comment on lines +11 to +12
const isHakkaGov = targetUrl.startsWith('https://elearning.hakka.gov.tw/');
const isLocalhost = /^https?:\/\/localhost([:/]|$)/.test(targetUrl);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To improve maintainability and avoid duplicating magic strings and regexes, consider defining the allowed domain and the localhost regex as constants. This logic is also duplicated in main.js. If possible, creating a shared utility function like isAllowedAudioUrl(url) would be even better to ensure consistency between client and server validation.

Comment on lines +397 to +398
const isHakkaGov = url.startsWith('https://elearning.hakka.gov.tw/');
const isLocalhost = /^https?:\/\/localhost([:/]|$)/.test(url);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This validation logic, including the domain string and regex, is duplicated from functions/audio-proxy.js. To improve maintainability, consider defining these as constants. If your project structure allows, creating a shared utility function would be the ideal way to keep client and server validation synchronized.

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.

分自動放送个 proxy 支援 localhost

1 participant