#Spring Cloud Gateway DOS protection

1 messages · Page 1 of 1 (latest)

proud topaz
#

I have a simple DOS attack implementation that opens ssl connections, keeps them opened forever and sends a lot of data through them. My Spring app RAM was consumed very fast. I implemented this protection:

@Bean
public NettyServerCustomizer floodProtectionServerCustomizer() {
    return httpServer -> httpServer
            .option(ChannelOption.SO_RCVBUF, BYTES)
            .option(ChannelOption.SO_SNDBUF, BYTES)
            .doOnConnection(conn -> {
                conn.channel()
                        .pipeline()
                        .addFirst(new ReadTimeoutHandler(5, TimeUnit.SECONDS));

                conn.channel()
                        .pipeline()
                        .addFirst(new FloodDetector());
            });

}

@ChannelHandler.Sharable
static class FloodDetector extends ChannelInboundHandlerAdapter {
    private final LongAdder bytesRead = new LongAdder();

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof ByteBuf buf) {
            bytesRead.add(buf.readableBytes());
            if (bytesRead.sum() > BYTES) {
                ctx.channel().close();
                ReferenceCountUtil.release(msg);
                return;
            }
        }
        ctx.fireChannelRead(msg);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        bytesRead.reset();
        ctx.fireChannelInactive();
    }
}

It worked, but I'm not sure this is a very good approach. Is it a good solution?

proven cypressBOT
# proud topaz I have a simple DOS attack implementation that opens ssl connections, keeps them...

Detected code, here are some useful tools:

[WARNING] The code couldn't end properly...

Problematic source code:



@ChannelHandler.Sharable
static class FloodDetector extends ChannelInboundHandlerAdapter {
    private final LongAdder bytesRead = new LongAdder();

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof ByteBuf buf) {
            bytesRead.add(buf.readableBytes());
            if (bytesRead.sum() > BYTES) {
                ctx.channel().close();
                ReferenceCountUtil.release(msg);
                return;
            }
        }
        ctx.fireChannelRead(msg);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        bytesRead.reset();
        ctx.fireChannelInactive();
    }
}```
Cause:
The code doesn't compile:
repeated modifier
cannot find symbol
  symbol:   class ChannelInboundHandlerAdapter
  location: class 
package ChannelHandler does not exist
cannot find symbol
  symbol:   class LongAdder
  location: class FloodDetector
cannot find symbol
  symbol:   class ChannelHandlerContext
  location: class FloodDetector
cannot find symbol
  symbol:   class ChannelHandlerContext
  location: class FloodDetector
cannot find symbol
  symbol:   class LongAdder
  location: class FloodDetector
method does not override or implement a method from a supertype
cannot find symbol
  symbol:   class ByteBuf
  location: class FloodDetector
cannot find symbol
  symbol:   variable BYTES
  location: class FloodDetector
cannot find symbol
  symbol:   variable ReferenceCountUtil
  location: class FloodDetector
method does not override or implement a method from a supertype

## System out
[Nothing]
#

<@&1004656351647117403> please have a look, thanks.

sinful rivet
#

Add a rate limit on the speed user can send, and add a limit to the size you can receive total.

#

Add a timeout on the connection.

proud topaz
proud topaz
#

I'll send my application.yaml

#
spring:
  application:
    name: gateway
  cloud:
    gateway:
      server:
        webflux:
          routes:
            - id: spring
              uri: http://localhost:8080
              predicates:
                - Path=/**
              filters:
                - name: RequestRateLimiter
                  args:
                    key-resolver: '#{@ipKeyResolver}'
                    redis-rate-limiter.replenishRate: 20
                    redis-rate-limiter.burstCapacity: 40
                    redis-rate-limiter.requestTokens: 1
          default-filters:
            - name: RequestRateLimiter
              args:
                key-resolver: '#{@ipKeyResolver}'
                redis-rate-limiter.replenishRate: 5
                redis-rate-limiter.burstCapacity: 10
  data:
    redis:
      lettuce:
        pool:
          enabled: true
          max-wait: 5000
      host: localhost
      port: 6379
  http:
    codecs:
      max-in-memory-size: 32KB
server:
  ssl:
    key-store-type: PKCS12
    key-store: classpath:/keystore.p12
    key-alias: spring-https
    key-store-password: changeit
    enabled: true
  port: 443
  netty:
    connection-timeout: 5000

  reactive:
    session:
      timeout: 30s
  servlet:
    session:
      timeout: 30s
resilience4j:
  circuitbreaker:
    instances:
      backendCircuitBreaker:
        sliding-window-size: 10
        failure-rate-threshold: 50
        wait-duration-in-open-state: 30s
        automatic-transition-from-open-to-half-open-enabled: true
logging:
  level:
    io.netty.util.ResourceLeakDetector: info
proven cypressBOT
proven cypressBOT
#

@proud topaz

Your question has been closed due to inactivity.

If it was not resolved yet, feel free to just post a message below
to reopen it, or create a new thread.

Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.

When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.

Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.

With enough info, someone knows the answer for sure 👍

proud topaz
#

Dump