Files
Jason McNeilandGitHub 7deaf5d634 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.

* 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.

* test: Fix session freshness check in session_test

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.

* 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.
2024-06-26 09:17:41 +02:00

120 lines
2.9 KiB
Go

package session
import (
"fmt"
"testing"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/utils"
"github.com/valyala/fasthttp"
)
// go test -run TestStore_getSessionID
func TestStore_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{})
defer app.ReleaseCtx(ctx)
// set cookie
ctx.Request().Header.SetCookie(store.sessionName, expectedID)
utils.AssertEqual(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{})
defer app.ReleaseCtx(ctx)
// set header
ctx.Request().Header.Set(store.sessionName, expectedID)
utils.AssertEqual(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{})
defer app.ReleaseCtx(ctx)
// set url parameter
ctx.Request().SetRequestURI(fmt.Sprintf("/path?%s=%s", store.sessionName, expectedID))
utils.AssertEqual(t, expectedID, store.getSessionID(ctx))
})
}
// go test -run TestStore_Get
// Regression: https://github.com/gofiber/fiber/issues/1408
// Regression: https://github.com/gofiber/fiber/security/advisories/GHSA-98j2-3j3p-fw2v
func TestStore_Get(t *testing.T) {
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{})
defer app.ReleaseCtx(ctx)
// set cookie
ctx.Request().Header.SetCookie(store.sessionName, unexpectedID)
acquiredSession, err := store.Get(ctx)
utils.AssertEqual(t, err, nil)
utils.AssertEqual(t, acquiredSession.ID() != unexpectedID, true)
})
}
// go test -run TestStore_DeleteSession
func TestStore_DeleteSession(t *testing.T) {
t.Parallel()
// fiber instance
app := fiber.New()
// session store
store := New()
// fiber context
ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(ctx)
// Create a new session
session, err := store.Get(ctx)
utils.AssertEqual(t, err, nil)
// Save the session ID
sessionID := session.ID()
// Delete the session
err = store.Delete(sessionID)
utils.AssertEqual(t, err, nil)
// Try to get the session again
session, err = store.Get(ctx)
utils.AssertEqual(t, err, nil)
// The session ID should be different now, because the old session was deleted
utils.AssertEqual(t, session.ID() == sessionID, false)
}