fiber/middleware/session/store_test.go
Jason McNeil b53802a5cb
Merge pull request from GHSA-98j2-3j3p-fw2v
* fix: token injection vulnerability GHSA-98j2-3j3p-fw2v

- Ensure session IDs are securely generated server-side.
- Add validation to prevent user-supplied session IDs.
- Update tests to verify correct session token use.

This update addresses the critical session middleware vulnerability identified in versions 2 and above of GoFiber.

* chore: Remove unused code and dependencies in session store

* test(middleware/csrf): Save session after generating new session ID

This commit saves the session after generating a new session ID to ensure that the updated session ID is persisted. This change is necessary to address a critical session middleware vulnerability identified in versions 2 and above of GoFiber.

* chore: Save session ID in context for middleware chain

The code changes add functionality to save the newly generated session ID in the context, allowing it to be accessible to subsequent middlewares in the chain. This improvement ensures that the session ID is available for use throughout the middleware stack.

* refactor(session.go): general clean-up

* chore: Revert session freshness behavior

The code changes in `session_test.go` fix the session freshness check by updating the assertions for `sess.Fresh()` and `sess.ID()`. The previous assertions were incorrect and have been corrected to ensure the session ID remains the same and the session is not fresh.

* chore: Update session.Get method signature to use fiber.Ctx instead of *fiber.Ctx
2024-06-26 09:17:41 +02:00

119 lines
2.8 KiB
Go

package session
import (
"fmt"
"testing"
"github.com/gofiber/fiber/v3"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
)
// go test -run Test_Store_getSessionID
func Test_Store_getSessionID(t *testing.T) {
t.Parallel()
expectedID := "test-session-id"
// fiber instance
app := fiber.New()
t.Run("from cookie", func(t *testing.T) {
t.Parallel()
// session store
store := New()
// fiber context
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
// set cookie
ctx.Request().Header.SetCookie(store.sessionName, expectedID)
require.Equal(t, expectedID, store.getSessionID(ctx))
})
t.Run("from header", func(t *testing.T) {
t.Parallel()
// session store
store := New(Config{
KeyLookup: "header:session_id",
})
// fiber context
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
// set header
ctx.Request().Header.Set(store.sessionName, expectedID)
require.Equal(t, expectedID, store.getSessionID(ctx))
})
t.Run("from url query", func(t *testing.T) {
t.Parallel()
// session store
store := New(Config{
KeyLookup: "query:session_id",
})
// fiber context
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
// set url parameter
ctx.Request().SetRequestURI(fmt.Sprintf("/path?%s=%s", store.sessionName, expectedID))
require.Equal(t, expectedID, store.getSessionID(ctx))
})
}
// go test -run Test_Store_Get
// Regression: https://github.com/gofiber/fiber/issues/1408
// Regression: https://github.com/gofiber/fiber/security/advisories/GHSA-98j2-3j3p-fw2v
func Test_Store_Get(t *testing.T) {
// Regression: https://github.com/gofiber/fiber/security/advisories/GHSA-98j2-3j3p-fw2v
t.Parallel()
unexpectedID := "test-session-id"
// fiber instance
app := fiber.New()
t.Run("session should be re-generated if it is invalid", func(t *testing.T) {
t.Parallel()
// session store
store := New()
// fiber context
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
// set cookie
ctx.Request().Header.SetCookie(store.sessionName, unexpectedID)
acquiredSession, err := store.Get(ctx)
require.NoError(t, err)
require.NotEqual(t, unexpectedID, acquiredSession.ID())
})
}
// go test -run Test_Store_DeleteSession
func Test_Store_DeleteSession(t *testing.T) {
t.Parallel()
// fiber instance
app := fiber.New()
// session store
store := New()
// fiber context
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
// Create a new session
session, err := store.Get(ctx)
require.NoError(t, err)
// Save the session ID
sessionID := session.ID()
// Delete the session
err = store.Delete(sessionID)
require.NoError(t, err)
// Try to get the session again
session, err = store.Get(ctx)
require.NoError(t, err)
// The session ID should be different now, because the old session was deleted
require.NotEqual(t, sessionID, session.ID())
}