Skip to content

Commit

Permalink
feat: Encrypt session data
Browse files Browse the repository at this point in the history
  • Loading branch information
null2264 committed Jul 21, 2023
1 parent 43782ba commit fc9e3a9
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 7 deletions.
2 changes: 1 addition & 1 deletion nexus/core/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import zmq
import zmq.asyncio
from fastapi import FastAPI, HTTPException, Response
from fastapi import FastAPI, Response
from fastapi.middleware.cors import CORSMiddleware
from starlette.requests import Request

Expand Down
21 changes: 16 additions & 5 deletions nexus/core/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
from base64 import b64decode, b64encode

from cryptography.fernet import Fernet
from itsdangerous import BadSignature
from redis import asyncio as aioredis
from starlette.datastructures import MutableHeaders
Expand Down Expand Up @@ -30,9 +31,14 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
data = connection.cookies[self.session_cookie].encode("utf-8")
try:
data = self.signer.unsign(data, max_age=self.max_age)
sessionId = json.loads(b64decode(data)).get("__ssid")
scope["session"] = json.loads(await self.redis.get(str(sessionId)) or "{}")
_internal = json.loads(b64decode(data))
sessionId = _internal.get("__ssid")
sessionKey = _internal.get("__sskey").encode("utf-8")
scope["session"] = json.loads(
Fernet(sessionKey).decrypt(await self.redis.get(str(sessionId)) or b"").decode("utf-8")
)
scope["__ssid"] = sessionId
scope["__sskey"] = sessionKey
initial_session_was_empty = False
except BadSignature:
scope["session"] = {}
Expand All @@ -41,13 +47,18 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:

async def send_wrapper(message: Message) -> None:
if message["type"] == "http.response.start":
sessionId = scope.pop("__ssid", snowflake())
sessionId: int = scope.pop("__ssid", snowflake())
sessionKey: bytes = scope.pop("__sskey", Fernet.generate_key())

if scope["session"]:
# We have session data to persist.

await self.redis.set(str(sessionId), json.dumps(scope["session"]), ex=self.max_age)
cookieData = {"__ssid": sessionId}
await self.redis.set(
str(sessionId),
Fernet(sessionKey).encrypt(json.dumps(scope["session"]).encode("utf-8")),
ex=self.max_age,
)
cookieData = {"__ssid": sessionId, "__sskey": sessionKey.decode("utf-8")}

data = b64encode(json.dumps(cookieData).encode("utf-8"))
data = self.signer.sign(data)
Expand Down
36 changes: 35 additions & 1 deletion pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ dependencies = [
"Pillow>=10.0.0",
"pydantic>=1.10,<=2.0",
"redis>=4.6.0",
"cryptography>=41.0.2",
]

[tool.pdm.scripts]
Expand Down

0 comments on commit fc9e3a9

Please sign in to comment.