Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use more-clever cookie for CookieGuard #245

Open
MurphyMc opened this issue May 14, 2020 · 1 comment
Open

Use more-clever cookie for CookieGuard #245

MurphyMc opened this issue May 14, 2020 · 1 comment

Comments

@MurphyMc
Copy link
Collaborator

POX CookieGuard currently just uses a single secret. While PCG is not really meant as a generic authentication mechanism, we could pretty easily limit the secret to a given client IP address. Especially if the web server is running without encryption, there may be some benefit to this...

@ljluestc
Copy link


class CookieGuard (object):
  COOKIE_NAME = 'pox-cookie-guard'

  def __init__ (self):
    self.secrets = {}

  def set_secret (self, ip_address, secret):
    self.secrets[ip_address] = secret

  def get_secret (self, ip_address):
    return self.secrets.get(ip_address)

  def send_secret (self, connection, secret):
    # Send the secret to the client in a cookie
    connection.send_header('Set-Cookie', '{}={}; Path=/'.format(self.COOKIE_NAME, secret))

  def receive_secret (self, headers):
    # Get the cookie from the headers
    cookie = headers.get('Cookie')
    if cookie:
        cookie_pairs = cookie.split(';')
        for pair in cookie_pairs:
            key, value = pair.strip().split('=')
            if key == self.COOKIE_NAME:
                return value
    return None

  def verify_secret (self, ip_address, secret):
    # Verify if the provided secret matches the stored secret for the client IP address
    stored_secret = self.get_secret(ip_address)
    if stored_secret and stored_secret == secret:
        return True
    return False

  def handle_request (self, connection, request):
    ip_address = connection.getpeername()[0]
    secret = self.receive_secret(request.headers)
    if secret:
        if self.verify_secret(ip_address, secret):
            connection.send_response(200)
            connection.end_headers()
            connection.wfile.write(b'Success: Authorized\n')
        else:
            connection.send_response(403)
            connection.end_headers()
            connection.wfile.write(b'Error: Forbidden\n')
    else:
        connection.send_response(401)
        connection.end_headers()
        connection.wfile.write(b'Error: Unauthorized\n')

  def handle_post (self, connection, request):
    ip_address = connection.getpeername()[0]
    content_length = int(request.headers.get('Content-Length', 0))
    post_data = request.rfile.read(content_length).decode('utf-8')
    secret = self.receive_secret(request.headers)
    if secret:
        if self.verify_secret(ip_address, secret):
            # Process the POST request
            connection.send_response(200)
            connection.end_headers()
            connection.wfile.write(b'Success: POST request processed\n')
        else:
            connection.send_response(403)
            connection.end_headers()
            connection.wfile.write(b'Error: Forbidden\n')
    else:
        connection.send_response(401)
        connection.end_headers()
        connection.wfile.write(b'Error: Unauthorized\n')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants