From d54bb270219fa069124de636832f9a23a7fd354e Mon Sep 17 00:00:00 2001 From: njomac Date: Tue, 28 Jul 2026 20:15:17 +0200 Subject: [PATCH] fix: login u Web GUI izbacivao van panela + nginx rate limit prenizak 1) Nakon uspjesnog logina redirect je isao na sirovi 'next' parametar. 'next' dolazi iz request.path, dakle bez SCRIPT_NAME prefiksa, pa je /guacadmin/login?next=/ nakon prijave vodio na / -> /guacamole/. Korisnik bi se prijavio i zavrsio na Guacamole login ekranu umjesto na dashboardu. Sad se dodaje request.script_root, uz provjeru da je next relativna putanja (open-redirect). 2) limit_req_zone je bio rate=10r/m - deset zahtjeva po MINUTI. Guacamole je Angular SPA i na jedno otvaranje ispali desetke zahtjeva, pa je nginx redom vracao 503 na app.js, app.css, api/tokens i translations. Podignuto na 10r/s, burst 50. Brute-force i dalje pokrivaju basic auth + fail2ban. Provjereno: /guacadmin/ -> login -> /guacadmin/dashboard (200), svih osam GUI stranica 200, 40 paralelnih zahtjeva na Guacamole API sve 200. Co-Authored-By: Claude Opus 5 --- install.sh | 16 ++++++++++++---- webgui/app.py | 8 +++++++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/install.sh b/install.sh index 1cdf6a3..5de9d02 100755 --- a/install.sh +++ b/install.sh @@ -352,7 +352,9 @@ map $http_upgrade $connection_upgrade { default upgrade; '' close; } -limit_req_zone $binary_remote_addr zone=guac_req:10m rate=10r/m; +# Guacamole je Angular SPA i na jedno otvaranje ispali desetke +# zahtjeva; 10r/m je rusilo ucitavanje. Brute-force pokriva fail2ban. +limit_req_zone $binary_remote_addr zone=guac_req:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=guac_ws:10m rate=30r/m; EOF @@ -381,7 +383,7 @@ server { location /guacamole/ { auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.guac_htpasswd; - limit_req zone=guac_req burst=20 nodelay; + limit_req zone=guac_req burst=50 nodelay; proxy_pass http://127.0.0.1:${GUAC_PORT}/guacamole/; proxy_buffering off; @@ -530,7 +532,7 @@ server { location /guacamole/ { auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.guac_htpasswd; - limit_req zone=guac_req burst=20 nodelay; + limit_req zone=guac_req burst=50 nodelay; proxy_pass http://127.0.0.1:${GUAC_PORT}/guacamole/; proxy_buffering off; @@ -781,7 +783,13 @@ def login(): request.form.get('password') == cfg['password']): session.permanent = True session['logged_in'] = True - return redirect(request.args.get('next') or url_for('dashboard')) + # 'next' je PATH_INFO bez prefiksa; bez script_roota redirect + # izlazi izvan GUI_PATH-a i korisnik zavrsi na Guacamole loginu. + target = request.args.get('next') or '' + if not target.startswith('/') or target.startswith('//'): + target = '' + return redirect(request.script_root + target if target + else url_for('dashboard')) flash('Pogrešno korisničko ime ili lozinka', 'danger') return render_template('login.html') diff --git a/webgui/app.py b/webgui/app.py index 7b2e458..31a9387 100644 --- a/webgui/app.py +++ b/webgui/app.py @@ -169,7 +169,13 @@ def login(): request.form.get('password') == cfg['password']): session.permanent = True session['logged_in'] = True - return redirect(request.args.get('next') or url_for('dashboard')) + # 'next' je PATH_INFO bez prefiksa; bez script_roota redirect + # izlazi izvan GUI_PATH-a i korisnik zavrsi na Guacamole loginu. + target = request.args.get('next') or '' + if not target.startswith('/') or target.startswith('//'): + target = '' + return redirect(request.script_root + target if target + else url_for('dashboard')) flash('Pogrešno korisničko ime ili lozinka', 'danger') return render_template('login.html')