CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/session-management-test-author

Build-an-X for session management tests per OWASP ASVS V3 - cookie attribute coverage (Secure / HttpOnly / SameSite=Strict|Lax), session-fixation defense (regenerate session ID on login), absolute + idle timeout, concurrent-session limits, logout invalidation across devices, CSRF token handling, session-binding to TLS / IP / device fingerprint. Use when authoring tests for any web app's session layer, regardless of framework (Express session, Django sessions, Spring Security, ASP.NET, Rails, etc.).

80

Quality

100%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

session-test-patterns.mdreferences/

Session-management extended test patterns

Extends SKILL.md Steps 4, 5, and 7. Core patterns (cookie attributes, session-fixation, timeouts, CSRF, single-device logout) stay in SKILL.md.

Concurrent-session limits (Step 4)

def test_concurrent_session_limit(client_a, client_b, base_url):
    client_a.login("alice", "alicepass")
    client_b.login("alice", "alicepass")   # second session

    # Per app config: either client_a's session is revoked, OR the
    # second login is rejected. Document the policy + test it:
    response_a = client_a.get(f"{base_url}/dashboard")
    response_b = client_b.get(f"{base_url}/dashboard")

    if app_policy == "single_session":
        assert response_a.status_code == 401   # a was revoked
        assert response_b.status_code == 200
    elif app_policy == "limited_concurrent":
        # both work; assert correct behavior
        ...

Logout across all devices (Step 5)

def test_logout_all_devices_invalidates_other_sessions(client_a, client_b, base_url):
    # alice logs in on two devices
    client_a.login("alice", "alicepass")
    client_b.login("alice", "alicepass")

    # alice triggers "logout from all devices" on client_a
    client_a.post(f"{base_url}/account/logout-all")

    # Both sessions must be dead
    assert client_a.get(f"{base_url}/dashboard").status_code == 401
    assert client_b.get(f"{base_url}/dashboard").status_code == 401

Session binding (Step 7)

def test_session_bound_to_user_agent(client, base_url):
    client.login("alice", "alicepass", user_agent="Mozilla/5.0 ...")
    cookie_value = client.cookies.get("sessionid")

    response = requests.get(
        f"{base_url}/dashboard",
        cookies={"sessionid": cookie_value},
        headers={"User-Agent": "Different-UA"},   # different UA
    )
    assert response.status_code == 401   # if UA-binding is enforced

Anti-patterns

Anti-patternWhy it failsFix
Skip Set-Cookie attribute testSessions transmitted insecurely; XSS-stealable cookiesStep 1 baseline
Logout = clear cookie only (no server-side invalidation)Cookie replay continues to workStep 5 negative test
Same session ID before + after loginSession-fixation vulnerableStep 2 regenerate test
No absolute timeoutSessions live forever; account-takeover blast radius hugeStep 3
State-changing GET requestsAlways vulnerable to CSRFConvert to POST + CSRF token (Step 6)

SKILL.md

tile.json