[GH-ISSUE #5037] [Feature Request] Security concern: FRP TCP proxy allows bypassing Nginx HTTPS and auth_basic #3962

Closed
opened 2026-05-05 14:31:15 -06:00 by gitea-mirror · 3 comments
Owner

Originally created by @MMMMMoris on GitHub (Oct 30, 2025).
Original GitHub issue: https://github.com/fatedier/frp/issues/5037

Describe the feature request

Hi FRP team,

First, thank you for your hard work on this project! It's been really helpful in exposing internal services to the public network. I have encountered an issue with my current setup and hope to get some guidance.

Environment & Setup:

I am using Cloudflare for DNS resolution, with Cloudflare CDN proxy and HTTPS certificates enabled.

I have a Proxmox VM on my LAN, and I expose its management panel to the internet via FRP TCP proxy.

My frpc configuration is:

[[proxies]] 
name = "PROXMOX"
type = "tcp"
localIP = "192.168.11.11"
localPort = 8006
remotePort = 12357

I access it via https://proxmox.test.com:8443, which is handled by Nginx listening on port 8443 and forwarding requests to FRPS port 12357. This works perfectly, and HTTPS is valid. Nginx and FRPS are deployed on the same linux server.

Here is the nginx config.

server {
    listen 8443 ssl;
    listen [::]:8443 ssl;
    server_name proxmox.test.com;

    include /etc/nginx/conf.d/test.com/ssl.conf;

    proxy_redirect off;
    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass https://127.0.0.1:12357;
        proxy_buffering off;
        client_max_body_size 0;
        proxy_connect_timeout  3600s;
        proxy_read_timeout  3600s;
        proxy_send_timeout  3600s;
        send_timeout  3600s;
    }
}

Issue:
I also have another domain direct.test.com pointing directly to the FRP server. When I access https://direct.test.com:12357, I can still reach my Proxmox panel. However:

The HTTPS connection shows a certificate warning.

This access bypasses the Nginx auth_basic authentication that I added.

This is a security concern, as it allows direct access to the service without authentication.

Question:
How can I prevent users from accessing the service directly via direct.test.com:12357 and enforce that all traffic goes through Nginx with HTTPS and authentication?

Thanks again for your help!

Describe alternatives you've considered

No response

Affected area

  • Docs
  • Installation
  • Performance and Scalability
  • Security
  • User Experience
  • Test and Release
  • Developer Infrastructure
  • Client Plugin
  • Server Plugin
  • Extensions
  • Others
Originally created by @MMMMMoris on GitHub (Oct 30, 2025). Original GitHub issue: https://github.com/fatedier/frp/issues/5037 ### Describe the feature request Hi FRP team, First, thank you for your hard work on this project! It's been really helpful in exposing internal services to the public network. I have encountered an issue with my current setup and hope to get some guidance. Environment & Setup: I am using Cloudflare for DNS resolution, with Cloudflare CDN proxy and HTTPS certificates enabled. I have a Proxmox VM on my LAN, and I expose its management panel to the internet via FRP TCP proxy. My frpc configuration is: ```toml [[proxies]] name = "PROXMOX" type = "tcp" localIP = "192.168.11.11" localPort = 8006 remotePort = 12357 ``` I access it via https://proxmox.test.com:8443, which is handled by Nginx listening on port 8443 and forwarding requests to FRPS port 12357. This works perfectly, and HTTPS is valid. Nginx and FRPS are deployed on the same linux server. Here is the nginx config. ```nginx server { listen 8443 ssl; listen [::]:8443 ssl; server_name proxmox.test.com; include /etc/nginx/conf.d/test.com/ssl.conf; proxy_redirect off; location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass https://127.0.0.1:12357; proxy_buffering off; client_max_body_size 0; proxy_connect_timeout 3600s; proxy_read_timeout 3600s; proxy_send_timeout 3600s; send_timeout 3600s; } } ``` Issue: I also have another domain direct.test.com pointing directly to the FRP server. When I access https://direct.test.com:12357, I can still reach my Proxmox panel. However: The HTTPS connection shows a certificate warning. This access bypasses the Nginx auth_basic authentication that I added. This is a security concern, as it allows direct access to the service without authentication. Question: How can I prevent users from accessing the service directly via direct.test.com:12357 and enforce that all traffic goes through Nginx with HTTPS and authentication? Thanks again for your help! ### Describe alternatives you've considered _No response_ ### Affected area - [ ] Docs - [ ] Installation - [ ] Performance and Scalability - [x] Security - [ ] User Experience - [ ] Test and Release - [ ] Developer Infrastructure - [ ] Client Plugin - [ ] Server Plugin - [ ] Extensions - [ ] Others
gitea-mirror 2026-05-05 14:31:15 -06:00
Author
Owner

@fatedier commented on GitHub (Oct 31, 2025):

What you’re seeing is expected behavior for a TCP proxy in frp: frps opens a listening port (remotePort, e.g. 12357) and transparently forwards raw TCP to the upstream. If that port is reachable from the Internet, clients can connect without going through your nginx reverse proxy—so nginx’s HTTPS termination and auth_basic are bypassed. This isn’t a vulnerability in frp; it’s a deployment/edge-exposure issue.

Recommended fixes (pick one):

Bind proxy ports to loopback (best):

  1. TOML (frps.toml)

    bindPort = 7000
    proxyBindAddr = "127.0.0.1"

    This makes all frps “proxy ports” (including 12357) listen only on localhost, so external clients can’t connect directly; traffic must come via nginx on the same host.

  2. Firewall the direct port (quick alternative):

    Block public access to 12357 at the host firewall / security group, allowing only localhost (or your reverse proxy host).

  3. Use STCP (if the service shouldn’t be public at all):

    Switch this proxy to stcp so no public listener is exposed; only authenticated frpc clients can reach it.

<!-- gh-comment-id:3471130741 --> @fatedier commented on GitHub (Oct 31, 2025): What you’re seeing is expected behavior for a TCP proxy in frp: frps opens a listening port (remotePort, e.g. 12357) and transparently forwards raw TCP to the upstream. If that port is reachable from the Internet, clients can connect without going through your nginx reverse proxy—so nginx’s HTTPS termination and auth_basic are bypassed. This isn’t a vulnerability in frp; it’s a deployment/edge-exposure issue. Recommended fixes (pick one): Bind proxy ports to loopback (best): 1. TOML (frps.toml) bindPort = 7000 proxyBindAddr = "127.0.0.1" This makes all frps “proxy ports” (including 12357) listen only on localhost, so external clients can’t connect directly; traffic must come via nginx on the same host. 2. Firewall the direct port (quick alternative): Block public access to 12357 at the host firewall / security group, allowing only localhost (or your reverse proxy host). 3. Use STCP (if the service shouldn’t be public at all): Switch this proxy to stcp so no public listener is exposed; only authenticated frpc clients can reach it.
Author
Owner

@MMMMMoris commented on GitHub (Nov 4, 2025):

What you’re seeing is expected behavior for a TCP proxy in frp: frps opens a listening port (remotePort, e.g. 12357) and transparently forwards raw TCP to the upstream. If that port is reachable from the Internet, clients can connect without going through your nginx reverse proxy—so nginx’s HTTPS termination and auth_basic are bypassed. This isn’t a vulnerability in frp; it’s a deployment/edge-exposure issue.

Recommended fixes (pick one):

Bind proxy ports to loopback (best):

  1. TOML (frps.toml)
    bindPort = 7000
    proxyBindAddr = "127.0.0.1"
    This makes all frps “proxy ports” (including 12357) listen only on localhost, so external clients can’t connect directly; traffic must come via nginx on the same host.
  2. Firewall the direct port (quick alternative):
    Block public access to 12357 at the host firewall / security group, allowing only localhost (or your reverse proxy host).
  3. Use STCP (if the service shouldn’t be public at all):
    Switch this proxy to stcp so no public listener is exposed; only authenticated frpc clients can reach it.

Thanks for your reply. I will try with your suggestions. Really appreciated.

<!-- gh-comment-id:3484165217 --> @MMMMMoris commented on GitHub (Nov 4, 2025): > What you’re seeing is expected behavior for a TCP proxy in frp: frps opens a listening port (remotePort, e.g. 12357) and transparently forwards raw TCP to the upstream. If that port is reachable from the Internet, clients can connect without going through your nginx reverse proxy—so nginx’s HTTPS termination and auth_basic are bypassed. This isn’t a vulnerability in frp; it’s a deployment/edge-exposure issue. > > Recommended fixes (pick one): > > Bind proxy ports to loopback (best): > > 1. TOML (frps.toml) > bindPort = 7000 > proxyBindAddr = "127.0.0.1" > This makes all frps “proxy ports” (including 12357) listen only on localhost, so external clients can’t connect directly; traffic must come via nginx on the same host. > 2. Firewall the direct port (quick alternative): > Block public access to 12357 at the host firewall / security group, allowing only localhost (or your reverse proxy host). > 3. Use STCP (if the service shouldn’t be public at all): > Switch this proxy to stcp so no public listener is exposed; only authenticated frpc clients can reach it. Thanks for your reply. I will try with your suggestions. Really appreciated.
Author
Owner

@github-actions[bot] commented on GitHub (Nov 19, 2025):

Issues go stale after 14d of inactivity. Stale issues rot after an additional 3d of inactivity and eventually close.

<!-- gh-comment-id:3550052701 --> @github-actions[bot] commented on GitHub (Nov 19, 2025): Issues go stale after 14d of inactivity. Stale issues rot after an additional 3d of inactivity and eventually close.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/frp#3962
No description provided.