== Analysis

For the analysis section, the project will be evaluated under the scope of the V3 (Session Management) chapter of the OWASP ASVS, using version v4.0.3. This will include an assessment of the session management mechanisms implemented, as well as any vulnerabilities identified and possible mitigations.

=== Session Management

==== Fundamental Session Management Security

[cols="^1,10,^1,^1", options="header", source]
|===
| Requirement | Description | Applicable | Implemented

| 3.1.1
| Verify the application never reveals session tokens in URL parameters.
| ✔
| ✔

|===

===== 3.1.1

The current implementation meets the requirement, as the session tokens are not exposed in the URL parameters but instead are sent in the Authorization header.

==== Session Binding

[cols="^1,10,^1,^1", options="header", source]
|===
| Requirement | Description | Applicable | Implemented

| 3.2.1
| Verify the application generates a new session token on user authentication.
| ✔
| ✔

| 3.2.2
| Verify that session tokens possess at least 64 bits of entropy.
| ✔
| ✔

| 3.2.3
| Verify the application only stores session tokens in the browser using secure methods such as appropriately secured cookies (see section 3.4) or HTML 5 session storage.
| ✗
| ✗

| 3.2.4
| Verify that session tokens are generated using approved cryptographic algorithms.
| ✔
| ✔
|===

===== 3.2.1, 3.2.2, 3.2.4

The application generates a new session token on session creation when a user logs in.

This token is generated using the `secrets.token_hex(128)`
function, which generates a 256-character hexadecimal string, providing more than 64 bits of entropy. This function has been certified as secure by OWASP in their link:https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#secure-random-number-generation[cheat sheet series].

This generation is implemented in the code as follows:

[source,python]
----
def create_session(user: User, org: Organization) -> Session:
    session = Session(
        user_id=user.id,
        org_id=org.id,
        token=secrets.token_hex(128),
        roles=[],
        challenge=secrets.token_hex(128),
        verified=False
    )
    db.add(session)
    db.commit()
    db.refresh(session)
    return session
----

==== Session Termination

[cols="^1,10,^1,^1", options="header", source]
|===
| Requirement | Description | Applicable | Implemented

| 3.3.1
| Verify that logout and expiration invalidate the session token, such that the back button or a downstream relying party does not resume an authenticated session, including across relying parties.
| ✔
| ✔

| 3.3.2
| If authenticators permit users to remain logged in, verify that re-authentication occurs periodically both when actively used or after an idle period.
| ✔
| ✗

| 3.3.3
| Verify that the application gives the option to terminate all other active sessions after a successful password change (including change via password reset/recovery), and that this is effective across the application, federated login (if present), and any relying parties.
| ✗
| ✗

| 3.3.4
| Verify that users are able to view and (having re-entered login credentials) log out of any or all currently active sessions and devices.
| ✔
| ✗
|===

===== 3.3.1

Upon logout, or any session deletion, the session data is completely removed from the database also deleting the session token, thus invalidating the session.

This is implemented in the code as follows, and accessed through the `POST /user/logout` endpoint:

[source,python]
----
def delete_session(session: Session) -> None:
    db.delete(session)
    db.commit()
----

===== 3.3.2

The application does not currently implement re-authentication after a period of inactivity.

This could be implemented by storing, for each session, the last time it was used, and checking this timestamp against the current time when a request is made. If the time difference exceeds the threshold defined in ASVS (12 hours or 15 minutes of inactivity, with 2FA), the user would be required to re-authenticate. This could be implemented in the code as follows:

[source,python]
----
def check_session_timeout(session: Session) -> bool:
    return (datetime.now() - session.last_used).total_seconds() > SESSION_TIMEOUT
----

===== 3.3.4

Currently, there isn't a mechanism to view and log out of active sessions and devices.

This could be implemented by storing the device information in the session data and enabling an endpoint for the user to view all active sessions and devices, and then revoke access to them.

==== Cookie-based Session Management

NOTE: None of the requirements in this section are applicable to the current implementation.

[cols="^1,10,^1,^1", options="header", source]
|===
| Requirement | Description | Applicable | Implemented

| 3.4.1
| Verify that cookie-based session tokens have the 'Secure' attribute set.
| ✗
| ✗

| 3.4.2
| Verify that cookie-based session tokens have the 'HttpOnly' attribute set.
| ✗
| ✗

| 3.4.3
| Verify that cookie-based session tokens utilize the 'SameSite' attribute to limit exposure to cross-site request forgery attacks.
| ✗
| ✗

| 3.4.4
| Verify that cookie-based session tokens use the "__Host-" prefix so cookies are only sent to the host that initially set the cookie.
| ✗
| ✗

| 3.4.5
| Verify that if the application is published under a domain name with other applications that set or use session cookies that might disclose the session cookies, set the path attribute in cookie-based session tokens using the most precise path possible.
| ✗
| ✗
|===

==== Token-based Session Management

[cols="^1,10,^1,^1", options="header", source]
|===
| Requirement | Description | Applicable | Implemented

| 3.5.1
| Verify the application allows users to revoke OAuth tokens that form trust relationships with linked applications.
| ✗
| ✗

| 3.5.2
| Verify the application uses session tokens rather than static API secrets and keys, except with legacy implementations.
| ✔
| ✔

| 3.5.3
| Verify that stateless session tokens use digital signatures, encryption, and other countermeasures to protect against tampering, enveloping, replay, null cipher, and key substitution attacks.
| ✔
| ✗
|===

===== 3.5.2

The application uses that exact implementation, using session tokens instead of static API secrets and keys to manage sessions.

===== 3.5.3

TBD

==== Federated Re-authentication

NOTE: None of the requirements in this section are applicable to the current implementation.

[cols="^1,10,^1,^1", options="header", source]
|===
| Requirement | Description | Applicable | Implemented

| 3.6.1
| Verify that Relying Parties (RPs) specify the maximum authentication time to Credential Service Providers (CSPs) and that CSPs re- authenticate the user if they haven't used a session within that period.
| ✗
| ✗

| 3.6.2
| Verify that Credential Service Providers (CSPs) inform Relying Parties (RPs) of the last authentication event, to allow RPs to determine if they need to re-authenticate the user.
| ✗
| ✗
|===

==== Defenses Against Session Management Exploits

[cols="^1,10,^1,^1", options="header", source]
|===
| Requirement | Description | Applicable | Implemented

| 3.7.1
| Verify the application ensures a full, valid login session or requires re-authentication or secondary verification before allowing any sensitive transactions or account modifications.
| ✔
| ✗
|===

===== 3.7.1

Currently, the application does not require re-authentication or secondary verification before allowing sensitive transactions or account modifications, it just checks if the user is authenticated and has the required permissions.

This could be implemented by adding a challenge signature to the request using the rsa key pair, which would be verified by the server before allowing the transaction. This is the same mechanism already used for the login endpoint.