#!/usr/bin/python3 from flask import Flask, render_template, request, redirect, abort import requests as r app = Flask(__name__, template_folder='files') database_node_port = 5002 content_node_port = 5004 database_node = "database:" + str(database_node_port) # PATCH V1/V5: template_folder ('files') — это тот же том, где лежит db/users/<логин>. # Раньше render_template(path) с путём из URL позволял отрендерить файл юзера # как Jinja-шаблон => SSTI => RCE. Рендерим только реально существующие страницы. ALLOWED_TEMPLATES = {"index.html", "login.html", "register.html", "specific.html"} # PATCH V8: сколько картинок реально есть в db/images IMG_MIN, IMG_MAX = 1, 16 def get_login(): """Возвращает имя юзера или None. Никогда не бросает исключение.""" session = request.cookies.get("session") if session is None: return None parts = session.split("||") if len(parts) != 2: # PATCH V8: раньше тут был ValueError -> 500 return None username, password = parts if not username: return None try: resp = r.get(f"http://{database_node}/users/{username}/password", timeout=5) if resp.status_code != 200: # PATCH V8: раньше KeyError -> 500 return None if resp.json().get("data") != password: return None except (r.RequestException, ValueError): return None return username def _field(username, name): try: resp = r.get(f"http://{database_node}/users/{username}/{name}", timeout=5) return resp.json()["data"] if resp.status_code == 200 else "" except (r.RequestException, ValueError, KeyError): return "" @app.route('/', methods=["GET", "POST"]) def route(path): if path == "index.html": if (username := get_login()) is None: return redirect("/login.html", code=302) imgs = list() for i in range(IMG_MIN, IMG_MAX + 1): try: imgs.append(r.get(f"http://{database_node}/images/{i}", timeout=5).json()["data"]) except (r.RequestException, ValueError, KeyError): continue imgs[-1]["id"] = str(i).zfill(2) user = dict() user["first_name"] = _field(username, "first_name") user["second_name"] = _field(username, "second_name") user["email"] = _field(username, "email") user["msg"] = _field(username, "msg") return render_template("index.html", data=imgs, user=user) elif path == "specific.html": if get_login() is None: return redirect("/login.html", code=302) # PATCH V8: img приходит из URL. Раньше любое нечисловое/вне диапазона # значение давало 500, а незакавыченная подстановка {{img['id']}} внутрь #