Skip to content

Commit

Permalink
[SEC] enforces secure token to be transmitted to trigger an action
Browse files Browse the repository at this point in the history
  • Loading branch information
dameyerdave committed Sep 28, 2023
1 parent 0042014 commit 73250a8
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 15 deletions.
8 changes: 7 additions & 1 deletion .env.TEMPLATE
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,10 @@
ACINT_ALLOWED_ACTIONS=

# The proxy path for the service, default: /acint
ACINT_PROXY_PATH=
ACINT_PROXY_PATH=

# The security token to be used to authenticate
ACINT_TOKEN=

# The environment to use dev | prod, default: prod
ACINT_ENV=
58 changes: 44 additions & 14 deletions app/acint.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#!/usr/bin/env python3

import cherrypy
import os
import cherrypy
from uuid import uuid4


DO_PATH = os.path.join(os.path.sep, "do")
os.makedirs(DO_PATH, exist_ok=True)
Expand All @@ -12,6 +14,24 @@
else:
allowed_actions = os.environ.get("ACINT_ALLOWED_ACTIONS", ".deploy").split(",")
proxy_path = os.environ.get("ACINT_PROXY_PATH", None) or "/"
secure_token = os.environ.get("ACINT_TOKEN", None) or uuid4().hex
environment = os.environ.get("ACINT_ENV", None) or "prod"

env_config = {
"environments": {
"dev": {
"tools.log_headers.on": True,
},
"prod": {
"engine.autoreload.on": False,
"checker.on": False,
"tools.log_headers.on": False,
"request.show_tracebacks": False,
"request.show_mismatched_params": False,
"log.screen": False,
},
},
}


def handle_an_exception():
Expand All @@ -25,36 +45,46 @@ def handle_default(status=None, message=None, version=None, traceback=None):
return f"{status}".encode("UTF-8")


@cherrypy.popargs("action")
@cherrypy.tools.register("before_finalize", priority=60)
def secureheaders():
headers = cherrypy.response.headers
headers["X-Frame-Options"] = "DENY"
headers["X-XSS-Protection"] = "1; mode=block"
headers["Content-Security-Policy"] = "default-src 'self';"


@cherrypy.popargs("action", "")
class AcInt(object):
_cp_config = {
# handler for an unhandled exception
"request.error_response": handle_an_exception,
# default handler for any other HTTP error
"error_page.default": handle_default,
}

@cherrypy.expose
def index(self, action=None):
if action not in allowed_actions:
@cherrypy.tools.allow(methods=["POST"])
@cherrypy.tools.json_in()
def index(self):
print("request", cherrypy.request.json)
data = cherrypy.request.json
if data["action"] not in allowed_actions:
raise cherrypy.HTTPError(403, "Forbidden")
if data["token"] != secure_token:
raise cherrypy.HTTPError(403, "Forbidden")
os.close(os.open(os.path.join(DO_PATH, action), os.O_CREAT))
return f"Triggerd action {action}."

os.close(os.open(os.path.join(DO_PATH, data["action"]), os.O_CREAT))
return f"Triggerd action {data['action']}."


if __name__ == "__main__":
print("Allowed actions:", allowed_actions)
print("Proxy path:", proxy_path)
print("Token:", secure_token)
print("Environment:", environment)
cherrypy.config.update(
{
"server.socket_host": "0.0.0.0",
"server.socket_port": 80,
"engine.autoreload.on": False,
"checker.on": False,
"tools.log_headers.on": False,
"request.show_tracebacks": False,
"request.show_mismatched_params": False,
"log.screen": False,
}
)
cherrypy.config.update(env_config["environments"][environment])
cherrypy.quickstart(AcInt(), proxy_path)

0 comments on commit 73250a8

Please sign in to comment.