jgneff opened a new issue, #4890:
URL: https://github.com/apache/netbeans/issues/4890

   ### Apache NetBeans version
   
   Apache NetBeans 16 release candidate
   
   ### What happened
   
   Building NetBeans in an environment that defines both proxy variables causes 
a brief denial-of-service (DoS) attack on one of the Web servers hosted by the 
Oregon State University (OSU) [Open Source Lab](https://osuosl.org/). Below is 
a typical example of the variables being defined and exported to the 
environment:
   
   ```bash
   export http_proxy=http://10.10.10.1:8222/
   export https_proxy=http://10.10.10.1:8222/
   ```
   
   The same build also causes an attack on the Sonatype Maven Central 
Repository, although the files in Maven Central are hosted by the Fastly 
Content Delivery Network (CDN), allowing it to continue serving its content 
regardless.
   
   The attack is a timeout-exploiting connection flood, which works by 
establish pending connections with the target server. It is similar to the 
[Slowloris](https://en.wikipedia.org/wiki/Slowloris_(computer_security)) 
attack, but less effective because it doesn't avoid timeouts through the use of 
partial requests. Instead, the NetBeans build opens hundreds of connections to 
the target Web servers and never sends any request headers at all. The 
connections are closed only when they time out on the server side or when the 
process that created them terminates on the build side.
   
   Specifically, the build opens 469 unused connections to `repo1.maven.org` 
(an alias for `sonatype.map.fastly.net`), sends no request headers, and leaves 
them open. The connections eventually time out on the server side, but that can 
take up to 20 seconds. This attack is unsuccessful in my experience, likely due 
to the Fastly CDN.
   
   The build opens only 95 unused connections to `netbeans.osuosl.org` (an 
alias for `ftp.osuosl.org`). Because the Open Source Lab hosts its files 
directly, though, the attack is usually successful in exhausting all request 
handlers. The Web server then returns an HTTP response status code of 503, 
which terminates the build. Even when the Web server is able to handle the load 
and the build is successful, it can take up to 20 seconds for the superfluous 
connections to time out on the server side.
   
   An unaware developer can assume that the build failure is a transient error 
and repeat the build until it's successful, as I did before uncovering the 
source of the problem. That has the unfortunate effect of turning a brief, 
one-time attack into a dozen or more repeated attacks throughout the day.
   
   Furthermore, the build attempts to make 564 direct connections to the remote 
Web servers even when a proxy server is defined and working, which results in a 
waste of resources on the build machine itself. The build also creates more 
than 1,692 unnecessary operating system threads, even when no proxy servers are 
defined, and leaves them waiting in the system until the build completes.
   
   
   ### How to reproduce
   
   There are three ways to reproduce the problem:
   
   1. run a remote build on **Launchpad**,
   2. run my **netbeans-proxies** stand-alone program, or
   3. run the **download-all-extbins** target of the NetBeans build.
   
   The second and third methods require setting up a local firewall and proxy 
server.
   
   ### Launchpad
   
   One way to reproduce the problem is to run a remote build on 
[Launchpad](https://launchpad.net/builders), which has a strict firewall and 
permits outbound connections only through its proxy server. Launchpad runs the 
build in an LXD container as follows:
   
   ```console
   $ lxc exec lp-bionic-amd64 \
       --env LANG=C.UTF-8 \
       --env SHELL=/bin/sh \
       --env http_proxy=http://10.10.10.1:8222/ \
       --env https_proxy=http://10.10.10.1:8222/ \
       --env GIT_PROXY_COMMAND=/usr/local/bin/lpbuildd-git-proxy \
       ...
   ```
   
   That's how I discovered the problem, but this method provides no diagnostic 
information other than the 503 response code when the build fails. To find out 
what's really going on, you need to reproduce it locally.
   
   ### netbeans-proxies
   
   I wrote a simple program, called *netbeans-proxies*, that safely illustrates 
the problem without creating a burden on the target server. The program 
downloads just 14 kilobytes in five files, whereas a clean build of NetBeans 
downloads at least 754 megabytes in 564 files.
   
   The program makes it easy to run, test, and debug the NetBeans build task 
and even step through its code one statement at a time. See the GitHub 
repository 
[jgneff/netbeans-proxies](https://github.com/jgneff/netbeans-proxies) for 
details on setting up its environment and running the tests.
   
   ### download-all-extbins
   
   To reproduce the problem using the actual NetBeans build, run the build on 
the same system that you set up for the *netbeans-proxies* program above. 
Disable the firewall long enough to clone the [NetBeans 
repository](https://github.com/apache/netbeans):
   
   ```console
   $ sudo ufw disable
   $ git clone https://github.com/apache/netbeans.git
   $ sudo ufw enable
   ```
   
   Then double check that the firewall is active, save a backup of the original 
repository, set the proxy environment variables, and run just the downloading 
task as follows:
   
   ```console
   $ sudo ufw status
   $ rsync -av netbeans/ netbeans-original/
   $ . ~/bin/proxy.env
   $ cd netbeans
   $ git switch release160
   $ ant -quiet -Dmetabuild.branch=release160 download-all-extbins
   ```
   
   Before running the build a second time, you'll need to remove the cached 
files and start with a fresh copy of the repository, thereby removing the files 
that were downloaded into its subdirectories. For example:
   
   ```console
   $ rm -r ~/.hgexternalcache
   $ rsync -av --delete ../netbeans-original/ ./
   $ git switch release160
   $ ant -quiet -Dmetabuild.branch=release160 download-all-extbins
   ```
   
   If the build fails, you'll see an error message like the following:
   
   ```
   java.io.IOException: Skipping download from 
https://netbeans.osuosl.org/binaries/
       89BC047153217F5254506F4C622A771A78883CBC-ValidationAPI-
       b26b94cc001a41ab9138496b11e2ae256a159ffd.jar due to response code 503
   
   BUILD FAILED
   ```
   
   
   ### Did this work correctly in an earlier version?
   
   No / Don't know
   
   ### Operating System
   
   Ubuntu 20.04.5 LTS (Focal Fossa)
   
   ### JDK
   
   OpenJDK Runtime Environment (build 11.0.16+8-post-Ubuntu-0ubuntu120.04)
   
   ### Apache NetBeans packaging
   
   Own source build
   
   ### Anything else
   
   Although the DoS attacks occur with every build when both proxy variables 
are defined, the build itself fails for me in about three out of every four 
runs.
   
   ### Web servers
   
   The NetBeans build downloads:
   
   * 469 files from `repo1.maven.org`, and
   * 95 files from `netbeans.osuosl.org`.
   
   Whether the build works or fails may depend partly on which address you 
receive for the Open Source Lab Web server:
   
   ```console
   $ host netbeans.osuosl.org
   netbeans.osuosl.org is an alias for ftp.osuosl.org.
   ftp.osuosl.org has address 140.211.166.134
   ftp.osuosl.org has address 64.50.233.100
   ftp.osuosl.org has address 64.50.236.52
   ftp.osuosl.org has IPv6 address 2605:bc80:3010::134
   ftp.osuosl.org has IPv6 address 2600:3402:200:227::2
   ftp.osuosl.org has IPv6 address 2600:3404:200:237::2
   ```
   
   One set of addresses is owned by the University of Oregon in Eugene, Oregon, 
while the other two sets of addresses are owned by TDS TELECOM in Madison, 
Wisconsin.
   
   The Maven Central Repository is hosted behind the Fastly CDN, which seems 
capable of handling the connection flood:
   
   ```console
   $ host repo1.maven.org
   repo1.maven.org is an alias for sonatype.map.fastly.net.
   sonatype.map.fastly.net has address 199.232.192.209
   sonatype.map.fastly.net has address 199.232.196.209
   ```
   
   ### Workaround
   
   There is a partial workaround for the problem: simply unset one of the proxy 
environment variables, like so:
   
   ```console
   $ unset https_proxy
   ```
   
   Even with this workaround, though, the build still tries to make hundreds of 
direct connections to the remote Web servers, but those are presumably blocked 
by the firewall.
   
   ### Access logs
   
   Below are the Squid access log files that I recorded from three full builds 
of NetBeans:
   
   1. **access-bypass.log** - bypassed the bug with the workaround
   2. **access-failed.log** - failed due to response code 503
   3. **access-worked.log** - worked despite the connection flood
   
   The complete log files are included below. The hundreds of superfluous 
connections can be identified by those to `netbeans.osuosl.org` that 
transferred only 176 bytes and those to `repo1.maven.org` that transferred only 
180 bytes. There are other unused connections in the log files, but those are 
the easiest to identify.
   
   The exchange on the unused connections starts with an outgoing request to 
the proxy server:
   
   ```http
   CONNECT netbeans.osuosl.org:443 HTTP/1.1
   User-Agent: Java/11.0.16
   Host: netbeans.osuosl.org
   Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
   Proxy-Connection: keep-alive
   ```
   
   followed by the response from the proxy server:
   
   ```http
   HTTP/1.1 200 Connection established
   ```
   
   followed by what appears to be an abbreviated TLS handshake, after which the 
connection is idle until it's closed by the remote Web server due to a timeout.
   
   The first log file can be included inline, but the other two are too big for 
an issue comment and must be included as an attachment.
   
   #### access-bypass.log
   
   23 connections, all of them good:
   
   ```
   1666216766.882   1579 10.203.206.244 TCP_TUNNEL/200 36662 CONNECT 
gitbox.apache.org:443 - HIER_DIRECT/65.108.73.173 -
   1666216767.468   2604 10.203.206.244 TCP_TUNNEL/200 5775 CONNECT 
gitbox.apache.org:443 - HIER_DIRECT/65.108.73.173 -
   1666216767.654   6024 10.203.206.244 TCP_TUNNEL/200 570407 CONNECT 
netbeans.osuosl.org:443 - HIER_DIRECT/64.50.233.100 -
   1666216801.004   6986 10.203.206.244 TCP_TUNNEL/200 227530 CONNECT 
netbeans.osuosl.org:443 - HIER_DIRECT/64.50.233.100 -
   1666216812.906  60610 10.203.206.244 TCP_TUNNEL/200 1601172 CONNECT 
repo1.maven.org:443 - HIER_DIRECT/199.232.192.209 -
   1666216823.385     93 10.203.206.244 TCP_TUNNEL/200 3038 CONNECT 
services.gradle.org:443 - HIER_DIRECT/104.18.191.9 -
   1666216862.403   5357 10.203.206.244 TCP_TUNNEL/200 107906 CONNECT 
netbeans.osuosl.org:443 - HIER_DIRECT/64.50.236.52 -
   1666216917.039  21523 10.203.206.244 TCP_TUNNEL/200 15861152 CONNECT 
netbeans.osuosl.org:443 - HIER_DIRECT/64.50.236.52 -
   1666216919.684  63779 10.203.206.244 TCP_TUNNEL/200 2443597 CONNECT 
repo.gradle.org:443 - HIER_DIRECT/104.18.191.9 -
   1666216919.686  96300 10.203.206.244 TCP_TUNNEL/200 116001697 CONNECT 
downloads.gradle-dn.com:443 - HIER_DIRECT/104.18.165.99 -
   1666216939.136  16733 10.203.206.244 TCP_TUNNEL/200 14409257 CONNECT 
netbeans.osuosl.org:443 - HIER_DIRECT/64.50.233.100 -
   1666216955.328  15259 10.203.206.244 TCP_TUNNEL/200 3733155 CONNECT 
netbeans.osuosl.org:443 - HIER_DIRECT/64.50.233.100 -
   1666216964.251   5648 10.203.206.244 TCP_TUNNEL/200 348769 CONNECT 
netbeans.osuosl.org:443 - HIER_DIRECT/64.50.233.100 -
   1666216982.681   7515 10.203.206.244 TCP_TUNNEL/200 1727695 CONNECT 
netbeans.osuosl.org:443 - HIER_DIRECT/64.50.233.100 -
   1666216995.907  11511 10.203.206.244 TCP_TUNNEL/200 4737625 CONNECT 
netbeans.osuosl.org:443 - HIER_DIRECT/2600:3404:200:237::2 -
   1666217019.945  18265 10.203.206.244 TCP_TUNNEL/200 10818236 CONNECT 
netbeans.osuosl.org:443 - HIER_DIRECT/2600:3404:200:237::2 -
   1666217063.608 310645 10.203.206.244 TCP_TUNNEL/200 572986695 CONNECT 
repo1.maven.org:443 - HIER_DIRECT/199.232.192.209 -
   1666217126.510  62896 10.203.206.244 TCP_TUNNEL/200 123171 CONNECT 
repo1.maven.org:443 - HIER_DIRECT/199.232.196.209 -
   1666217447.971    208 10.203.206.244 TCP_MISS/200 9384 GET 
http://www.w3.org/2001/xml.xsd - HIER_DIRECT/128.30.52.100 application/xml
   1666217448.180    101 10.203.206.244 TCP_MISS/200 9384 GET 
http://www.w3.org/2001/xml.xsd - HIER_DIRECT/128.30.52.100 application/xml
   1666217449.280    204 10.203.206.244 TCP_MISS/200 9384 GET 
http://www.w3.org/2001/xml.xsd - HIER_DIRECT/128.30.52.100 application/xml
   1666217449.709    103 10.203.206.244 TCP_MISS/200 9384 GET 
http://www.w3.org/2001/xml.xsd - HIER_DIRECT/128.30.52.100 application/xml
   1666217450.058    103 10.203.206.244 TCP_MISS/200 9384 GET 
http://www.w3.org/2001/xml.xsd - HIER_DIRECT/128.30.52.100 application/xml
   ```
   
   #### access-failed.log
   
   566 connections, at least 543 of them unused:
   
   
[access-failed.log](https://github.com/apache/netbeans/files/9896668/access-failed.log)
   
   #### access-worked.log
   
   573 connections, at least 541 of them unused:
   
   
[access-worked.log](https://github.com/apache/netbeans/files/9896670/access-worked.log)
   
   
   ### Are you willing to submit a pull request?
   
   Yes
   
   ### Code of Conduct
   
   Yes


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscr...@netbeans.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@netbeans.apache.org
For additional commands, e-mail: notifications-h...@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to