Profile pictures are now handled by the application to mitigate possible directory traversals
to other sub-directories of the static directory (Admins/Staff with the right to edit user accounts were able to set a path like ../static/favicon.png for the profile picture - this isn't a "i'm in, now i have root access and can hack your mom"-vulnerability, but better fix it before it evolves to one. or a dragon. it's too late for this crap.)
This commit is contained in:
parent
86ea7c0000
commit
9f270c12b4
8 changed files with 34 additions and 4 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -4,6 +4,7 @@
|
||||||
/archive/*
|
/archive/*
|
||||||
/logs/*
|
/logs/*
|
||||||
/packages/*
|
/packages/*
|
||||||
|
/profilepictures/*
|
||||||
/temp
|
/temp
|
||||||
/tmp
|
/tmp
|
||||||
__pycache__
|
__pycache__
|
||||||
|
@ -12,4 +13,5 @@ __pycache__
|
||||||
!/config/config.sample.sh
|
!/config/config.sample.sh
|
||||||
!/config/Caddyfile
|
!/config/Caddyfile
|
||||||
!/config/tls/
|
!/config/tls/
|
||||||
!.gitkeep
|
!/profilepictures/default.svg
|
||||||
|
!.gitkeep
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
<ul class="userlist">
|
<ul class="userlist">
|
||||||
{% for user_ in user_list %}
|
{% for user_ in user_list %}
|
||||||
<li class="userlistButton button" data-username="{{ user_.username }}">
|
<li class="userlistButton button" data-username="{{ user_.username }}">
|
||||||
<img src="{% static 'profilepictures/'|add:user_.profile_picture_filename %}">
|
<img src="{{ '/profilepictures?name='|add:user_.profile_picture_filename }}">
|
||||||
<div>
|
<div>
|
||||||
{% if user_.first_name %}
|
{% if user_.first_name %}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<div class="userPanel">
|
<div class="userPanel">
|
||||||
<div class="userInfo">
|
<div class="userInfo">
|
||||||
<img src="{% static 'profilepictures/'|add:user.profile_picture_filename %}">
|
<img src="{{ '/profilepictures?name='|add:user.profile_picture_filename }}">
|
||||||
<span>
|
<span>
|
||||||
{% if user.first_name != "" %}
|
{% if user.first_name != "" %}
|
||||||
{% translate "User" %}: {{ user.first_name }} {{ user.last_name }} ({{ user.username }})
|
{% translate "User" %}: {{ user.first_name }} {{ user.last_name }} ({{ user.username }})
|
||||||
|
|
|
@ -16,9 +16,10 @@ urlpatterns = [
|
||||||
path('accounts/password_change/', auth_views.PasswordChangeView.as_view(), name='password_change'),
|
path('accounts/password_change/', auth_views.PasswordChangeView.as_view(), name='password_change'),
|
||||||
path('accounts/password_change_done/', views.redirect_home, name='password_change_done'),
|
path('accounts/password_change_done/', views.redirect_home, name='password_change_done'),
|
||||||
path('admin/', adminSite.urls),
|
path('admin/', adminSite.urls),
|
||||||
|
# custom-handled resources
|
||||||
|
path('profilepictures', views.profile_pictures),
|
||||||
# API #
|
# API #
|
||||||
path('api/order-drink', views.api_order_drink),
|
path('api/order-drink', views.api_order_drink),
|
||||||
path('api/deposit', views.api_deposit),
|
path('api/deposit', views.api_deposit),
|
||||||
path('api/supply', views.api_supply)
|
path('api/supply', views.api_supply)
|
||||||
#path('api/get-statistics', views.api_get_statistics)
|
|
||||||
]
|
]
|
|
@ -1,12 +1,16 @@
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth import login
|
from django.contrib.auth import login
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.forms import AuthenticationForm
|
from django.contrib.auth.forms import AuthenticationForm
|
||||||
from django.http.response import HttpResponseRedirect
|
from django.http.response import HttpResponseRedirect
|
||||||
|
from django.http.response import FileResponse
|
||||||
from django.http.response import HttpResponse
|
from django.http.response import HttpResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
@ -20,6 +24,9 @@ from .models import Drink
|
||||||
from .models import Order
|
from .models import Order
|
||||||
from .models import RegisterTransaction
|
from .models import RegisterTransaction
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
profile_pictures_path = Path(settings.PROFILE_PICTURES).resolve()
|
||||||
|
|
||||||
# login view
|
# login view
|
||||||
|
|
||||||
|
@ -112,6 +119,23 @@ def redirect_home(request):
|
||||||
return HttpResponseRedirect("/")
|
return HttpResponseRedirect("/")
|
||||||
|
|
||||||
|
|
||||||
|
# Custom-Handled Resources
|
||||||
|
|
||||||
|
def profile_pictures(request):
|
||||||
|
if not "name" in request.GET:
|
||||||
|
return HttpResponse(b"", status=400)
|
||||||
|
print(request.GET["name"])
|
||||||
|
ppic_filepath = Path(profile_pictures_path / request.GET["name"]).resolve()
|
||||||
|
try:
|
||||||
|
ppic_filepath.relative_to(profile_pictures_path)
|
||||||
|
except:
|
||||||
|
return HttpResponse("No.", status=403)
|
||||||
|
if ppic_filepath.is_file():
|
||||||
|
return FileResponse(ppic_filepath.open('rb'))
|
||||||
|
else:
|
||||||
|
return FileResponse(b"", status=404)
|
||||||
|
|
||||||
|
|
||||||
# API for XHR requests #
|
# API for XHR requests #
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
|
|
@ -175,3 +175,5 @@ try:
|
||||||
CURRENCY_SUFFIX = os.environ["CURRENCY_SUFFIX"]
|
CURRENCY_SUFFIX = os.environ["CURRENCY_SUFFIX"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
CURRENCY_SUFFIX = "$"
|
CURRENCY_SUFFIX = "$"
|
||||||
|
|
||||||
|
PROFILE_PICTURES = os.environ["PROFILE_PICTURES"]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
export DJANGO_SK_ABS_FP="$(pwd)/config/secret_key.txt"
|
export DJANGO_SK_ABS_FP="$(pwd)/config/secret_key.txt"
|
||||||
|
export PROFILE_PICTURES="$(pwd)/profilepictures/"
|
||||||
export STATIC_FILES="$(pwd)/static/"
|
export STATIC_FILES="$(pwd)/static/"
|
||||||
export APP_VERSION="12"
|
export APP_VERSION="12"
|
||||||
export PYTHONPATH="$(pwd)/packages/"
|
export PYTHONPATH="$(pwd)/packages/"
|
||||||
|
|
Before Width: | Height: | Size: 740 B After Width: | Height: | Size: 740 B |
Loading…
Add table
Add a link
Reference in a new issue