Commit b119ecd1 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

feat: limit max POST size and put timeouts on requests in irma server

parent 30d2b590
package sessiontest
import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"net/http"
"reflect"
"testing"
......@@ -453,3 +455,24 @@ func TestIssuedCredentialIsStored(t *testing.T) {
id := irma.NewAttributeTypeIdentifier("irma-demo.MijnOverheid.fullName.familyname")
sessionHelper(t, getDisclosureRequest(id), "verification", client)
}
func TestPOSTSizeLimit(t *testing.T) {
StartRequestorServer(IrmaServerConfiguration)
defer StopRequestorServer()
req, err := http.NewRequest(
http.MethodPost,
"http://localhost:48682/session/",
bytes.NewReader(make([]byte, server.PostSizeLimit+1, server.PostSizeLimit+1)),
)
require.NoError(t, err)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
require.NoError(t, err)
bts, err := ioutil.ReadAll(res.Body)
require.NoError(t, err)
var rerr irma.RemoteError
require.NoError(t, json.Unmarshal(bts, &rerr))
require.Equal(t, "http: request body too large", rerr.Message)
}
......@@ -55,6 +55,17 @@ type LogOptions struct {
Response, Headers, From, EncodeBinary bool
}
// Remove this when dropping support for legacy pre-condiscon session requests
type LegacySessionResult struct {
Token string `json:"token"`
Status Status `json:"status"`
Type irma.Action `json:"type"`
ProofStatus irma.ProofStatus `json:"proofStatus,omitempty"`
Disclosed []*irma.DisclosedAttribute `json:"disclosed,omitempty"`
Signature *irma.SignedMessage `json:"signature,omitempty"`
Err *irma.RemoteError `json:"error,omitempty"`
}
const (
StatusInitialized Status = "INITIALIZED" // The session has been started and is waiting for the client
StatusConnected Status = "CONNECTED" // The client has retrieved the session request, we wait for its response
......@@ -69,16 +80,11 @@ const (
ComponentStatic = "static"
)
// Remove this when dropping support for legacy pre-condiscon session requests
type LegacySessionResult struct {
Token string `json:"token"`
Status Status `json:"status"`
Type irma.Action `json:"type"`
ProofStatus irma.ProofStatus `json:"proofStatus,omitempty"`
Disclosed []*irma.DisclosedAttribute `json:"disclosed,omitempty"`
Signature *irma.SignedMessage `json:"signature,omitempty"`
Err *irma.RemoteError `json:"error,omitempty"`
}
const (
PostSizeLimit = 10 << 20 // 10 MB
ReadTimeout = 5 * time.Second
WriteTimeout = 10 * time.Second
)
// Remove this when dropping support for legacy pre-condiscon session requests
func (r *SessionResult) Legacy() *LegacySessionResult {
......@@ -439,6 +445,13 @@ func NewLogger(verbosity int, quiet bool, json bool) *logrus.Logger {
return logger
}
var SizeLimitMiddleware = func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(w, r.Body, PostSizeLimit)
next.ServeHTTP(w, r)
})
}
// LogMiddleware is middleware for logging HTTP requests and responses.
func LogMiddleware(typ string, opts LogOptions) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
......
......@@ -101,6 +101,8 @@ func (s *Server) HandlerFunc() http.HandlerFunc {
r.Use(server.LogMiddleware("client", opts))
}
r.Use(server.SizeLimitMiddleware)
notfound := &irma.RemoteError{Status: 404, ErrorName: string(server.ErrorInvalidRequest.Type)}
notallowed := &irma.RemoteError{Status: 405, ErrorName: string(server.ErrorInvalidRequest.Type)}
r.NotFound(errorWriter(notfound, server.WriteResponse))
......
......@@ -100,6 +100,9 @@ func (s *Server) startServer(handler http.Handler, name, addr string, port int,
Addr: fulladdr,
Handler: handler,
TLSConfig: tlsConf,
// See https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/
ReadTimeout: server.ReadTimeout,
WriteTimeout: server.WriteTimeout,
}
go func() {
......@@ -189,6 +192,7 @@ func (s *Server) Handler() http.Handler {
// while not adding it to the endpoints already added above (which do their own logging).
router.Group(func(r chi.Router) {
r.Use(server.SizeLimitMiddleware)
r.Use(cors.New(corsOptions).Handler)
if s.conf.Verbose >= 2 {
r.Use(server.LogMiddleware("requestor", log))
......@@ -212,6 +216,7 @@ func (s *Server) Handler() http.Handler {
})
router.Group(func(r chi.Router) {
r.Use(server.SizeLimitMiddleware)
r.Use(cors.New(corsOptions).Handler)
if s.conf.Verbose >= 2 {
r.Use(server.LogMiddleware("revocation", log))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment