Skip to content

Commit a70bfc7

Browse files
authored
security: limit max content length to prevent a possible dos attack (#423)
**Relative Issues:** Resolve #412 **Describe the pull request** This pull request addresses a potential security vulnerability by limiting the maximum content length accepted by the application. This measure helps to prevent possible Denial of Service (DoS) attacks that could be executed by sending excessively large payloads to the server. By enforcing a reasonable content length limit, we can maintain the application's stability and security while minimizing the risk of disruption from malicious actors. **Checklist** - [x] I have linked the relative issue to this pull request - [x] I have made the modifications or added tests related to my PR - [x] I have added/updated the documentation for my RP - [x] I put my PR in Ready for Review only when all the checklist is checked **Breaking changes ?** no **Additional context** A Directive Overloading occurs when a user can send a query with many consecutive directives and overload the parser of the app. Actually `gqlgen` don't allow us to add a fixed limit. I will work on gqlgen project to see if this can be implemented to respect the GraphQL 16 specifications about Directive Overloading.
1 parent f7696e4 commit a70bfc7

File tree

8 files changed

+106
-55
lines changed

8 files changed

+106
-55
lines changed

cmd/api.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
package cmd
22

33
import (
4+
"bytes"
45
"fmt"
6+
"io/ioutil"
57
"net/http"
68
"os"
79
"strings"
10+
"time"
811

912
"entgo.io/contrib/entgql"
1013
"github.com/99designs/gqlgen/graphql/handler"
1114
"github.com/99designs/gqlgen/graphql/handler/extension"
1215
"github.com/99designs/gqlgen/graphql/playground"
1316
sentryhttp "github.com/getsentry/sentry-go/http"
1417
"github.com/go-chi/chi/v5"
18+
"github.com/go-chi/chi/v5/middleware"
1519
_ "github.com/lib/pq"
1620
"github.com/rs/cors"
1721
"github.com/rs/zerolog/log"
@@ -67,12 +71,47 @@ var apiCmd = &cobra.Command{
6771
AllowCredentials: true,
6872
Debug: os.Getenv("DEBUG") == "true",
6973
}).Handler)
74+
75+
router.Use(middleware.Timeout(60*time.Second), middleware.RealIP)
7076
router.Use(api.AuthzByPolicyMiddleware)
7177
router.Use(api.AuthenticationMiddleware)
7278
if os.Getenv("DEBUG") == "true" {
7379
router.Use(api.LoggingMiddleware)
7480
}
7581

82+
if os.Getenv("DEBUG_PPROF") == "true" {
83+
router.Mount("/debug", middleware.Profiler())
84+
}
85+
86+
// Limit the request body size for all requests to the
87+
// This is based on the chi middleware.RequestSize. Way this middleware is
88+
// added to the router to use it
89+
// https://github.com/go-chi/chi/blob/master/middleware/request_size.go
90+
router.Use(func(h http.Handler) http.Handler {
91+
fn := func(w http.ResponseWriter, r *http.Request) {
92+
93+
// When image transfer is enabled, the request body size is limited.
94+
// This is done to prevent the server from being overloaded by large
95+
// DoS attack over the network.
96+
const _50KB = (1 << 10) * 50
97+
98+
limitedBody := http.MaxBytesReader(w, r.Body, _50KB)
99+
bodyBytes, err := ioutil.ReadAll(limitedBody)
100+
limitedBody.Close()
101+
102+
// if r.Body reach the max size limit, the request will be canceled
103+
// and the error will be returned to the client
104+
if r.ContentLength > _50KB || err != nil {
105+
http.Error(w, http.StatusText(http.StatusRequestEntityTooLarge), http.StatusRequestEntityTooLarge)
106+
return
107+
}
108+
109+
r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
110+
h.ServeHTTP(w, r)
111+
}
112+
return http.HandlerFunc(fn)
113+
})
114+
76115
if *playgroudActive {
77116
router.Handle("/", playground.Handler("GraphQL playground", "/graphql"))
78117
log.Info().Msgf("connect to http://localhost:%s/ for GraphQL playground", *apiPortFlag)

deploy/stacks/apps/s42/api.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module "api" {
1616
replicas = 1
1717
autoscaling = {
1818
enabled = true
19-
minReplicas = 1
19+
minReplicas = 2
2020
maxReplicas = 10
2121
metrics = {
2222
cpu = {

deploy/stacks/apps/s42/interface.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ module "interface" {
3535
replicas = 1
3636
autoscaling = {
3737
enabled = true
38-
minReplicas = 1
38+
minReplicas = 2
3939
maxReplicas = 10
4040
metrics = {
4141
cpu = {

deploy/stacks/apps/s42/jwtks_service.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ module "jwtks_service" {
1717
replicas = 1
1818
autoscaling = {
1919
enabled = true
20-
minReplicas = 1
20+
minReplicas = 2
2121
maxReplicas = 10
2222
metrics = {
2323
cpu = {

go.mod

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ go 1.18
55
require (
66
entgo.io/contrib v0.3.0
77
entgo.io/ent v0.11.4
8-
github.com/99designs/gqlgen v0.17.5-0.20220428154617-9250f9ac1f90
8+
github.com/99designs/gqlgen v0.17.28
99
github.com/bwmarrin/discordgo v0.25.0
1010
github.com/getsentry/sentry-go v0.13.0
11-
github.com/go-chi/chi v1.5.4
12-
github.com/go-chi/chi/v5 v5.0.7
11+
github.com/go-chi/chi/v5 v5.0.8
1312
github.com/google/go-github/v47 v47.0.1-0.20220822225427-243bda850b1f
1413
github.com/google/uuid v1.3.0
1514
github.com/hashicorp/go-multierror v1.1.1
@@ -22,16 +21,16 @@ require (
2221
github.com/spf13/cobra v1.6.1
2322
github.com/spf13/viper v1.10.1
2423
github.com/streadway/amqp v1.0.0
25-
github.com/stretchr/testify v1.8.1
26-
github.com/vektah/gqlparser/v2 v2.4.3-0.20220508162109-d3d9eb001575
24+
github.com/stretchr/testify v1.8.2
25+
github.com/vektah/gqlparser/v2 v2.5.1
2726
github.com/vmihailenco/msgpack/v5 v5.0.0-beta.9
2827
go.opentelemetry.io/otel v1.9.0
2928
go.opentelemetry.io/otel/exporters/jaeger v1.9.0
3029
go.opentelemetry.io/otel/sdk v1.9.0
3130
go.opentelemetry.io/otel/trace v1.9.0
3231
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
3332
google.golang.org/grpc v1.47.0
34-
google.golang.org/protobuf v1.28.0
33+
google.golang.org/protobuf v1.28.1
3534
)
3635

3736
require (
@@ -53,7 +52,7 @@ require (
5352
github.com/google/go-querystring v1.1.0 // indirect
5453
github.com/gorilla/websocket v1.5.0 // indirect
5554
github.com/hashicorp/errwrap v1.1.0 // indirect
56-
github.com/hashicorp/golang-lru v0.5.4 // indirect
55+
github.com/hashicorp/golang-lru/v2 v2.0.1 // indirect
5756
github.com/hashicorp/hcl v1.0.0 // indirect
5857
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
5958
github.com/inconshreveable/mousetrap v1.0.1 // indirect
@@ -80,11 +79,11 @@ require (
8079
github.com/vmihailenco/tagparser v0.1.2 // indirect
8180
github.com/zclconf/go-cty v1.8.0 // indirect
8281
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 // indirect
83-
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
84-
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
85-
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
86-
golang.org/x/text v0.3.7 // indirect
87-
golang.org/x/tools v0.1.13-0.20220804200503-81c7dc4e4efa // indirect
82+
golang.org/x/mod v0.8.0 // indirect
83+
golang.org/x/net v0.6.0 // indirect
84+
golang.org/x/sys v0.5.0 // indirect
85+
golang.org/x/text v0.7.0 // indirect
86+
golang.org/x/tools v0.6.0 // indirect
8887
google.golang.org/appengine v1.6.7 // indirect
8988
google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4 // indirect
9089
gopkg.in/ini.v1 v1.66.2 // indirect

0 commit comments

Comments
 (0)