Flooding and Denial of Service

This section outlines the approaches to address flooding and denial of service attacks within the go-events package.

Rate Limiting

Motivation: Prevent malicious actors from overwhelming the system with excessive event submissions.

Implementation: The go-events package employs rate limiting to control the number of events that can be processed per unit of time. This ensures that legitimate users are not impacted by a flood of events.

Configuration:

  • maxEventsPerSecond: This setting controls the maximum number of events allowed per second. It can be adjusted based on the expected traffic and system capacity.

Example:

package main
          
          import (
              "fmt"
              "time"
          
              "github.com/docker/go-events"
          )
          
          func main() {
              // Create an event emitter with a rate limit of 10 events per second.
              emitter := events.NewEmitter(
                  events.WithRateLimit(10, time.Second),
              )
          
              // ... (emit events as needed)
              for i := 0; i < 10; i++ {
                  emitter.Emit("my-event", fmt.Sprintf("event-%d", i))
                  time.Sleep(100 * time.Millisecond)
              }
          }
          

Source: emitter.go

Event Queue Management

Motivation: Ensure that event processing is efficient and avoids backlogs that could lead to denial of service.

Implementation: go-events utilizes a queue to handle incoming events. The queue is managed to prevent it from growing indefinitely and overwhelming system resources.

Configuration:

  • queueSize: The maximum size of the event queue.

Example:

package main
          
          import (
              "fmt"
          
              "github.com/docker/go-events"
          )
          
          func main() {
              // Create an event emitter with a queue size of 100.
              emitter := events.NewEmitter(
                  events.WithQueueSize(100),
              )
          
              // ... (emit events as needed)
              for i := 0; i < 1000; i++ {
                  emitter.Emit("my-event", fmt.Sprintf("event-%d", i))
              }
          }
          

Source: emitter.go

Event Filtering

Motivation: Reduce the processing load by filtering out unnecessary or potentially malicious events.

Implementation: Event filtering allows the system to discard events that do not meet specified criteria. This can be based on event type, source, or other attributes.

Example:

package main
          
          import (
              "fmt"
          
              "github.com/docker/go-events"
          )
          
          func main() {
              // Create an event emitter with a filter that only allows events of type "my-event".
              emitter := events.NewEmitter(
                  events.WithFilter(func(event events.Event) bool {
                      return event.Type() == "my-event"
                  }),
              )
          
              // ... (emit events as needed)
              emitter.Emit("my-event", "event-1")
              emitter.Emit("other-event", "event-2")
          }
          

Source: emitter.go

Event Validation

Motivation: Prevent the injection of invalid or malicious data into the system.

Implementation: Event validation checks the format and content of events to ensure they meet predefined rules. This helps mitigate potential vulnerabilities.

Example:

package main
          
          import (
              "fmt"
          
              "github.com/docker/go-events"
          )
          
          func main() {
              // Create an event emitter with a validator that checks if the event data is a string.
              emitter := events.NewEmitter(
                  events.WithValidator(func(event events.Event) error {
                      _, ok := event.Data().(string)
                      if !ok {
                          return fmt.Errorf("event data must be a string")
                      }
                      return nil
                  }),
              )
          
              // ... (emit events as needed)
              emitter.Emit("my-event", "event-1")
              emitter.Emit("other-event", 123)
          }
          

Source: emitter.go