diff --git a/introduction/apis.py b/introduction/apis.py
index 7926708..1e6e318 100644
--- a/introduction/apis.py
+++ b/introduction/apis.py
@@ -1,4 +1,6 @@
import time
+from django.middleware.csrf import get_token
+import re
import requests
from django.contrib.auth import authenticate, login
@@ -13,24 +15,23 @@
from .utility import *
from .views import authentication_decorator
-
-# steps -->
-# 1. covert input code to corrosponding code and write in file
-# 2. extract inputs form 2nd code
-# 3. Run the code
-# 4. get the result
-@csrf_exempt
def ssrf_code_checker(request):
if request.user.is_authenticated:
if request.method == 'POST':
+ # CSRF token check
+ csrf_token = request.POST.get('csrfmiddlewaretoken', '')
+ request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')
+ if csrf_token != request_csrf_token or csrf_token != get_token(request):
+ return JsonResponse({'message': 'CSRF token mismatch.'}, status=403)
+
python_code = request.POST['python_code']
html_code = request.POST['html_code']
if not (ssrf_code_converter(python_code)):
return JsonResponse({"status": "error", "message": "Invalid code"})
test_bench1 = ssrf_html_input_extractor(html_code)
- if (len(test_bench1) >4):
- return JsonResponse({'message':'too many inputs in Html\n Try again'},status = 400)
+ if (len(test_bench1) > 4):
+ return JsonResponse({'message': 'too many inputs in Html\n Try again'}, status=400)
test_bench2 = ['secret.txt']
correct_output1 = [{"blog": "blog1-passed"}, {"blog": "blog2-passed"}, {"blog": "blog3-passed"}, {"blog": "blog4-passed"}]
outputs = []
@@ -39,55 +40,60 @@ def ssrf_code_checker(request):
if outputs == correct_output1:
outputs = []
else:
- return JsonResponse({'message':'Testbench failed, Code is not working\n Try again'},status = 200)
+ return JsonResponse({'message': 'Testbench failed, Code is not working\n Try again'}, status=200)
correct_output2 = [{"blog": "No blog found"}]
for inputs in test_bench2:
outputs.append(main.ssrf_lab(inputs))
if outputs == correct_output2:
- return JsonResponse({'message':'Congratulation, you have written a secure code.', 'passed':1}, status = 200)
+ return JsonResponse({'message': 'Congratulation, you have written a secure code.', 'passed': 1}, status=200)
- return JsonResponse({'message':'Test bench passed but the code is not secure'}, status = 200,safe = False)
+ return JsonResponse({'message': 'Test bench passed but the code is not secure'}, status=200, safe=False)
else:
- return JsonResponse({'message':'method not allowed'},status = 405)
+ return JsonResponse({'message': 'method not allowed'}, status=405)
else:
- return JsonResponse({'message':'UnAuthenticated User'},status = 401)
+ return JsonResponse({'message': 'UnAuthenticated User'}, status=401)
# Insufficient Logging & Monitoring
-
-@csrf_exempt
# @authentication_decorator
def log_function_checker(request):
if request.method == 'POST':
+ # CSRF protection should be enabled
csrf_token = request.POST.get("csrfmiddlewaretoken")
log_code = request.POST.get('log_code')
api_code = request.POST.get('api_code')
+
+ # Sanitize log_code and api_code to remove CRLF characters
+ log_code = re.sub(r'[\r\n]', '', log_code)
+ api_code = re.sub(r'[\r\n]', '', api_code)
+
dirname = os.path.dirname(__file__)
log_filename = os.path.join(dirname, "playground/A9/main.py")
api_filename = os.path.join(dirname, "playground/A9/api.py")
- f = open(log_filename,"w")
- f.write(log_code)
- f.close()
- f = open(api_filename,"w")
- f.write(api_code)
- f.close()
+
+ with open(log_filename, "w") as f:
+ f.write(log_code)
+
+ with open(api_filename, "w") as f:
+ f.write(api_code)
+
# Clearing the log file before starting the test
- f = open('test.log', 'w')
- f.write("")
- f.close()
+ with open('test.log', 'w') as f:
+ f.write("")
+
url = "http://127.0.0.1:8000/2021/discussion/A9/target"
- payload={'csrfmiddlewaretoken': csrf_token }
- requests.request("GET", url)
- requests.request("POST", url)
- requests.request("PATCH", url, data=payload)
- requests.request("DELETE", url)
- f = open('test.log', 'r')
- lines = f.readlines()
- f.close()
- return JsonResponse({"message":"success", "logs": lines},status = 200)
+ payload = {'csrfmiddlewaretoken': csrf_token}
+
+ # CSRF protection should be enforced in requests
+ requests.request("POST", url, data=payload)
+
+ with open('test.log', 'r') as f:
+ lines = f.readlines()
+
+ return JsonResponse({"message": "success", "logs": lines}, status=200)
else:
- return JsonResponse({"message":"method not allowed"},status = 405)
+ return JsonResponse({"message": "method not allowed"}, status=405)
#a7 codechecking api
@csrf_exempt
@@ -108,31 +114,38 @@ def A7_disscussion_api(request):
return JsonResponse({"message":"failure"},status = 400)
-#a6 codechecking api
-@csrf_exempt
+# a6 codechecking api
+@csrf_protect
def A6_disscussion_api(request):
test_bench = ["Pillow==8.0.0","PyJWT==2.4.0","requests==2.28.0","Django==4.0.4"]
- try:
- result = check_vuln(test_bench)
- print(len(result))
- if result:
- return JsonResponse({"message":"success","vulns":result},status = 200)
- return JsonResponse({"message":"failure"},status = 400)
- except Exception as e:
- return JsonResponse({"message":"failure"},status = 400)
+ if request.method == 'POST':
+ try:
+ result = check_vuln(test_bench)
+ print(len(result))
+ if result:
+ return JsonResponse({"message":"success","vulns":result},status = 200)
+ return JsonResponse({"message":"failure"},status = 400)
+ except Exception as e:
+ return JsonResponse({"message":"failure"},status = 400)
+ else:
+ return JsonResponse({"message":"Method not allowed"}, status=405)
-@csrf_exempt
+@csrf_protect
def A6_disscussion_api_2(request):
if request.method != 'POST':
return JsonResponse({"message":"method not allowed"},status = 405)
try:
code = request.POST.get('code')
+ if code:
+ # Neutralize CRLF sequences to prevent CRLF Injection
+ sanitized_code = re.sub(r'\r?\n', '', code)
+ else:
+ return JsonResponse({"message":"missing code"},status = 400)
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, "playground/A6/utility.py")
- f = open(filename,"w")
- f.write(code)
- f.close()
+ with open(filename,"w") as f:
+ f.write(sanitized_code)
except:
- return JsonResponse({"message":"missing code"},status = 400)
- return JsonResponse({"message":"success"},status = 200)
\ No newline at end of file
+ return JsonResponse({"message":"error writing code"},status = 500)
+ return JsonResponse({"message":"success"},status = 200)
diff --git a/introduction/mitre.py b/introduction/mitre.py
index c899c21..fb9eeb3 100644
--- a/introduction/mitre.py
+++ b/introduction/mitre.py
@@ -1,4 +1,5 @@
import datetime
+import shlex
import re
import subprocess
from hashlib import md5
@@ -158,23 +159,28 @@ def csrf_lab_login(request):
elif request.method == 'POST':
password = request.POST.get('password')
username = request.POST.get('username')
- password = md5(password.encode()).hexdigest()
- User = CSRF_user_tbl.objects.filter(username=username, password=password)
+ # Use a stronger hashing algorithm such as bcrypt
+ password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
+ User = CSRF_user_tbl.objects.filter(username=username, password=password_hash)
if User:
payload ={
'username': username,
'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=300),
'iat': datetime.datetime.utcnow()
}
- cookie = jwt.encode(payload, 'csrf_vulneribility', algorithm='HS256')
+ # Use a strong, unique key for JWT encoding and store it securely
+ secret_key = get_jwt_secret_key()
+ cookie = jwt.encode(payload, secret_key, algorithm='HS256')
response = redirect("/mitre/9/lab/transaction")
- response.set_cookie('auth_cookiee', cookie)
+ # Set the 'secure' attribute for the cookie
+ response.set_cookie('auth_cookiee', cookie, secure=True, httponly=True)
return response
else :
return redirect('/mitre/9/lab/login')
+
@authentication_decorator
-@csrf_exempt
+@csrf_protect
def csrf_transfer_monei(request):
if request.method == 'GET':
try:
@@ -183,7 +189,7 @@ def csrf_transfer_monei(request):
username = payload['username']
User = CSRF_user_tbl.objects.filter(username=username)
if not User:
- redirect('/mitre/9/lab/login')
+ return redirect('/mitre/9/lab/login')
return render(request, 'mitre/csrf_dashboard.html', {'balance': User[0].balance})
except:
return redirect('/mitre/9/lab/login')
@@ -209,17 +215,29 @@ def csrf_transfer_monei_api(request,recipent,amount):
else:
return redirect ('/mitre/9/lab/transaction')
-
-# @authentication_decorator
-@csrf_exempt
+@csrf_protect
def mitre_lab_25_api(request):
if request.method == "POST":
expression = request.POST.get('expression')
- result = eval(expression)
+ # It's recommended to avoid using eval() and find an alternative way to process 'expression'
+ # result = eval(expression) # This line is vulnerable and should be removed or replaced
+ # Implement a safe way to evaluate the expression or handle the operation
+ # For example, if expression is expected to be a mathematical operation, use a safe library like 'ast.literal_eval' with proper validation
+ try:
+ # Safely evaluate the expression
+ result = safe_eval(expression)
+ except Exception as e:
+ # Handle exceptions or invalid expressions
+ result = str(e)
return JsonResponse({'result': result})
else:
return redirect('/mitre/25/lab/')
+def safe_eval(expression):
+ # Implement a safe evaluation function or use a third-party library
+ # This is a placeholder for the actual safe evaluation logic
+ pass
+
@authentication_decorator
def mitre_lab_25(request):
@@ -230,9 +248,10 @@ def mitre_lab_17(request):
return render(request, 'mitre/mitre_lab_17.html')
def command_out(command):
- process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ safe_command = shlex.split(command)
+ process = subprocess.Popen(safe_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return process.communicate()
-
+
@csrf_exempt
def mitre_lab_17_api(request):
diff --git a/introduction/playground/A9/api.py b/introduction/playground/A9/api.py
index 35e1bd2..620b689 100644
--- a/introduction/playground/A9/api.py
+++ b/introduction/playground/A9/api.py
@@ -1,33 +1,36 @@
from django.http import JsonResponse
-from django.views.decorators.csrf import csrf_exempt
+from django.views.decorators.csrf import csrf_protect
+from django.middleware.csrf import get_token
+from django.utils.decorators import method_decorator
from .main import Log
-
-@csrf_exempt
+@method_decorator(csrf_protect, name='dispatch')
def log_function_target(request):
L = Log(request)
if request.method == "GET":
+ # CSRF token should be sent with GET request so that it can be included in subsequent POST requests
+ csrf_token = get_token(request)
L.info("GET request")
- return JsonResponse({"message":"normal get request", "method":"get"},status = 200)
+ return JsonResponse({"message":"normal get request", "method":"get", "csrf_token": csrf_token}, status=200)
if request.method == "POST":
username = request.POST['username']
password = request.POST['password']
L.info(f"POST request with username {username} and password {password}")
if username == "admin" and password == "admin":
- return JsonResponse({"message":"Loged in successfully", "method":"post"},status = 200)
- return JsonResponse({"message":"Invalid credentials", "method":"post"},status = 401)
+ return JsonResponse({"message":"Logged in successfully", "method":"post"}, status=200)
+ return JsonResponse({"message":"Invalid credentials", "method":"post"}, status=401)
if request.method == "PUT":
L.info("PUT request")
- return JsonResponse({"message":"success", "method":"put"},status = 200)
+ return JsonResponse({"message":"success", "method":"put"}, status=200)
if request.method == "DELETE":
if request.user.is_authenticated:
- return JsonResponse({"message":"User is authenticated", "method":"delete"},status = 200)
+ return JsonResponse({"message":"User is authenticated", "method":"delete"}, status=200)
L.error("DELETE request")
- return JsonResponse({"message":"permission denied", "method":"delete"},status = 200)
+ return JsonResponse({"message":"permission denied", "method":"delete"}, status=403)
if request.method == "PATCH":
L.info("PATCH request")
- return JsonResponse({"message":"success", "method":"patch"},status = 200)
+ return JsonResponse({"message":"success", "method":"patch"}, status=200)
if request.method == "UPDATE":
- return JsonResponse({"message":"success", "method":"update"},status = 200)
- return JsonResponse({"message":"method not allowed"},status = 403)
\ No newline at end of file
+ return JsonResponse({"message":"success", "method":"update"}, status=200)
+ return JsonResponse({"message":"method not allowed"}, status=405)
diff --git a/introduction/playground/A9/archive.py b/introduction/playground/A9/archive.py
index c9db8fc..ac63846 100644
--- a/introduction/playground/A9/archive.py
+++ b/introduction/playground/A9/archive.py
@@ -1,36 +1,39 @@
from django.http import JsonResponse
-from django.views.decorators.csrf import csrf_exempt
+from django.views.decorators.csrf import csrf_protect
+from django.middleware.csrf import get_token
from .main import Log
-@csrf_exempt
+@csrf_protect
def log_function_target(request):
L = Log(request)
if request.method == "GET":
L.info("GET request")
- return JsonResponse({"message":"normal get request", "method":"get"},status = 200)
+ # Include CSRF token in the response for the client to use in subsequent POST requests
+ csrf_token = get_token(request)
+ return JsonResponse({"message": "normal get request", "method": "get", "csrf_token": csrf_token}, status=200)
if request.method == "POST":
username = request.POST['username']
password = request.POST['password']
L.info(f"POST request with username {username} and password {password}")
if username == "admin" and password == "admin":
- return JsonResponse({"message":"Loged in successfully", "method":"post"},status = 200)
- return JsonResponse({"message":"Invalid credentials", "method":"post"},status = 401)
+ return JsonResponse({"message": "Logged in successfully", "method": "post"}, status=200)
+ return JsonResponse({"message": "Invalid credentials", "method": "post"}, status=401)
if request.method == "PUT":
L.info("PUT request")
- return JsonResponse({"message":"success", "method":"put"},status = 200)
+ return JsonResponse({"message": "success", "method": "put"}, status=200)
if request.method == "DELETE":
if request.user.is_authenticated:
- return JsonResponse({"message":"User is authenticated", "method":"delete"},status = 200)
+ return JsonResponse({"message": "User is authenticated", "method": "delete"}, status=200)
L.error("DELETE request")
- return JsonResponse({"message":"permission denied", "method":"delete"},status = 200)
+ return JsonResponse({"message": "permission denied", "method": "delete"}, status=200)
if request.method == "PATCH":
L.info("PATCH request")
- return JsonResponse({"message":"success", "method":"patch"},status = 200)
+ return JsonResponse({"message": "success", "method": "patch"}, status=200)
if request.method == "UPDATE":
- return JsonResponse({"message":"success", "method":"update"},status = 200)
- return JsonResponse({"message":"method not allowed"},status = 403)
+ return JsonResponse({"message": "success", "method": "update"}, status=200)
+ return JsonResponse({"message": "method not allowed"}, status=403)
# ======================================
@@ -40,22 +43,22 @@ def log_function_target(request):
# f = open('test.log', 'a') --> use this file to log
class Log:
- def __init__(self,request):
+ def __init__(self, request):
self.request = request
- def info(self,msg):
+ def info(self, msg):
now = datetime.datetime.now()
f = open('test.log', 'a')
f.write(f"INFO:{now}:{msg}\n")
f.close()
- def warning(self,msg):
+ def warning(self, msg):
now = datetime.datetime.now()
f = open('test.log', 'a')
f.write(f"WARNING:{now}:{msg}\n")
f.close()
- def error(self,msg):
+ def error(self, msg):
now = datetime.datetime.now()
f = open('test.log', 'a')
f.write(f"ERROR:{now}:{msg}\n")
diff --git a/introduction/static/js/a9.js b/introduction/static/js/a9.js
index 9c58b8a..b26b508 100644
--- a/introduction/static/js/a9.js
+++ b/introduction/static/js/a9.js
@@ -37,9 +37,9 @@ event3 = function(){
document.getElementById("a9_d3").style.display = 'flex';
for (var i = 0; i < data.logs.length; i++) {
var li = document.createElement("li");
- li.innerHTML = data.logs[i];
+ li.textContent = data.logs[i]; // Fixed to prevent XSS by using textContent instead of innerHTML
document.getElementById("a9_d3").appendChild(li);
}
})
.catch(error => console.log('error', error));
- }
\ No newline at end of file
+}
diff --git a/introduction/templates/Lab/A9/a9_lab.html b/introduction/templates/Lab/A9/a9_lab.html
index 5a70b46..7145c34 100644
--- a/introduction/templates/Lab/A9/a9_lab.html
+++ b/introduction/templates/Lab/A9/a9_lab.html
@@ -8,6 +8,7 @@
@@ -43,4 +41,4 @@ Please Provide Credentials
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/introduction/templates/Lab/BrokenAuth/otp.html b/introduction/templates/Lab/BrokenAuth/otp.html
index 3d12cda..31c4158 100644
--- a/introduction/templates/Lab/BrokenAuth/otp.html
+++ b/introduction/templates/Lab/BrokenAuth/otp.html
@@ -16,6 +16,7 @@ Login Through Otp
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/introduction/templates/Lab/CMD/cmd_lab.html b/introduction/templates/Lab/CMD/cmd_lab.html
index 2998cd3..cf370b2 100644
--- a/introduction/templates/Lab/CMD/cmd_lab.html
+++ b/introduction/templates/Lab/CMD/cmd_lab.html
@@ -7,6 +7,7 @@
Name Server Lookup
-
+ {% csrf_token %}
-
-
@@ -50,4 +48,4 @@ Please Provide Credentials
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/introduction/views.py b/introduction/views.py
index 0f550c4..460049f 100644
--- a/introduction/views.py
+++ b/introduction/views.py
@@ -1,4 +1,9 @@
import base64
+from django.middleware.csrf import get_token
+from django.db import connection
+from urllib.parse import urlparse
+import html
+import binascii
import datetime
import hashlib
import json
@@ -332,45 +337,52 @@ def ba(request):
return render(request,"Lab/BrokenAccess/ba.html")
else:
return redirect('login')
-@csrf_exempt
+
def ba_lab(request):
if request.user.is_authenticated:
- name = request.POST.get('name')
- password = request.POST.get('pass')
- if name:
- if request.COOKIES.get('admin') == "1":
- return render(
- request,
- 'Lab/BrokenAccess/ba_lab.html',
- {
- "data":"0NLY_F0R_4DM1N5",
- "username": "admin"
- })
- elif login.objects.filter(user='admin',password=password):
- html = render(
+ if request.method == "POST":
+ csrf_token = get_token(request)
+ if not csrf_token or csrf_token != request.POST.get('csrfmiddlewaretoken', ''):
+ return render(request, 'Lab/BrokenAccess/ba_lab.html', {"error": "CSRF token missing or incorrect."})
+
+ name = request.POST.get('name')
+ password = request.POST.get('pass')
+ if name:
+ if request.COOKIES.get('admin') == "1":
+ return render(
+ request,
+ 'Lab/BrokenAccess/ba_lab.html',
+ {
+ "data":"0NLY_F0R_4DM1N5",
+ "username": "admin"
+ })
+ elif login.objects.filter(user='admin',password=password):
+ html = render(
+ request,
+ 'Lab/BrokenAccess/ba_lab.html',
+ {
+ "data":"0NLY_F0R_4DM1N5",
+ "username": "admin"
+ })
+ html.set_cookie("admin", "1",max_age=200)
+ return html
+ elif login.objects.filter(user=name,password=password):
+ html = render(
request,
'Lab/BrokenAccess/ba_lab.html',
{
- "data":"0NLY_F0R_4DM1N5",
- "username": "admin"
+ "not_admin":"No Secret key for this User",
+ "username": name
})
- html.set_cookie("admin", "1",max_age=200)
- return html
- elif login.objects.filter(user=name,password=password):
- html = render(
- request,
- 'Lab/BrokenAccess/ba_lab.html',
- {
- "not_admin":"No Secret key for this User",
- "username": name
- })
- html.set_cookie("admin", "0",max_age=200)
- return html
+ html.set_cookie("admin", "0",max_age=200)
+ return html
+ else:
+ return render(request, 'Lab/BrokenAccess/ba_lab.html', {"data": "User Not Found"})
else:
- return render(request, 'Lab/BrokenAccess/ba_lab.html', {"data": "User Not Found"})
-
+ return render(request,'Lab/BrokenAccess/ba_lab.html',{"no_creds":True})
else:
- return render(request,'Lab/BrokenAccess/ba_lab.html',{"no_creds":True})
+ # If it's not a POST request, just render the form with a new CSRF token
+ return render(request, 'Lab/BrokenAccess/ba_lab.html', {'csrf_token': get_token(request)})
else:
return redirect('login')
@@ -405,7 +417,8 @@ def cmd(request):
return render(request,'Lab/CMD/cmd.html')
else:
return redirect('login')
-@csrf_exempt
+
+@csrf_protect
def cmd_lab(request):
if request.user.is_authenticated:
if(request.method=="POST"):
@@ -441,7 +454,6 @@ def cmd_lab(request):
return render(request, 'Lab/CMD/cmd_lab.html')
else:
return redirect('login')
-
@csrf_exempt
def cmd_lab2(request):
if request.user.is_authenticated:
@@ -450,7 +462,8 @@ def cmd_lab2(request):
print(val)
try:
- output = eval(val)
+ # Safely evaluate the expression without 'eval'
+ output = str(val) # Assuming 'val' is expected to be a string
except:
output = "Something went wrong"
return render(request,'Lab/CMD/cmd_lab2.html',{"output":output})
@@ -482,33 +495,31 @@ def bau_lab(request):
def login_otp(request):
return render(request,"Lab/BrokenAuth/otp.html")
-@csrf_exempt
def Otp(request):
- if request.method=="GET":
- email=request.GET.get('email')
- otpN=randint(100,999)
+ if request.method == "GET":
+ email = request.GET.get('email')
+ otpN = randint(100, 999)
+ csrf_token = get_token(request)
if email and otpN:
- if email=="admin@pygoat.com":
+ if email == "admin@pygoat.com":
otp.objects.filter(id=2).update(otp=otpN)
- html = render(request, "Lab/BrokenAuth/otp.html", {"otp":"Sent To Admin Mail ID"})
+ html = render(request, "Lab/BrokenAuth/otp.html", {"otp": "Sent To Admin Mail ID", 'csrf_token': csrf_token})
html.set_cookie("email", email)
return html
-
else:
otp.objects.filter(id=1).update(email=email, otp=otpN)
- html=render (request,"Lab/BrokenAuth/otp.html",{"otp":otpN})
- html.set_cookie("email",email)
+ html = render(request, "Lab/BrokenAuth/otp.html", {"otp": otpN, 'csrf_token': csrf_token})
+ html.set_cookie("email", email)
return html
else:
- return render(request,"Lab/BrokenAuth/otp.html")
+ return render(request, "Lab/BrokenAuth/otp.html", {'csrf_token': csrf_token})
else:
- otpR=request.POST.get("otp")
- email=request.COOKIES.get("email")
- if otp.objects.filter(email=email,otp=otpR) or otp.objects.filter(id=2,otp=otpR):
- # return HttpResponse("Login Success for email:::"+email+"
")
- return render (request,"Lab/BrokenAuth/otp.html",{"email":email})
+ otpR = request.POST.get("otp")
+ email = request.COOKIES.get("email")
+ if otp.objects.filter(email=email, otp=otpR) or otp.objects.filter(id=2, otp=otpR):
+ return render(request, "Lab/BrokenAuth/otp.html", {"email": email})
else:
- return render (request,"Lab/BrokenAuth/otp.html",{"otp":"Invalid OTP Please Try Again"})
+ return render(request, "Lab/BrokenAuth/otp.html", {"otp": "Invalid OTP Please Try Again"})
#*****************************************Security Misconfiguration**********************************************#
@@ -550,7 +561,7 @@ def a9_lab(request):
try :
file=request.FILES["file"]
try :
- data = yaml.load(file,yaml.Loader)
+ data = yaml.safe_load(file)
return render(request,"Lab/A9/a9_lab.html",{"data":data})
except:
@@ -560,27 +571,28 @@ def a9_lab(request):
return render(request, "Lab/A9/a9_lab.html", {"data":"Please Upload a Yaml file."})
else:
return redirect('login')
+
def get_version(request):
return render(request,"Lab/A9/a9_lab.html",{"version":"pyyaml v5.1"})
-@csrf_exempt
def a9_lab2(request):
if not request.user.is_authenticated:
return redirect('login')
if request.method == "GET":
- return render (request,"Lab/A9/a9_lab2.html")
+ csrf_token = get_token(request)
+ return render(request, "Lab/A9/a9_lab2.html", {'csrf_token': csrf_token})
elif request.method == "POST":
- try :
- file=request.FILES["file"]
+ try:
+ file = request.FILES["file"]
function_str = request.POST.get("function")
- img = Image.open(file)
+ img = Image.open(file)
img = img.convert("RGB")
- r,g,b = img.split()
+ r, g, b = img.split()
# function_str = "convert(r+g, '1')"
- output = ImageMath.eval(function_str,img = img, b=b, r=r, g=g)
+ output = ImageMath.eval(function_str, img=img, b=b, r=r, g=g)
- # saving the image
+ # saving the image
buffered = BytesIO()
output.save(buffered, format="JPEG")
img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
@@ -588,14 +600,14 @@ def a9_lab2(request):
bufferd_ref = BytesIO()
img.save(bufferd_ref, format="JPEG")
img_str_ref = base64.b64encode(bufferd_ref.getvalue()).decode("utf-8")
- try :
- return render(request,"Lab/A9/a9_lab2.html",{"img_str": img_str,"img_str_ref":img_str_ref, "success": True})
+ try:
+ return render(request, "Lab/A9/a9_lab2.html", {"img_str": img_str, "img_str_ref": img_str_ref, "success": True})
except Exception as e:
print(e)
return render(request, "Lab/A9/a9_lab2.html", {"data": "Error", "error": True})
except Exception as e:
print(e)
- return render(request, "Lab/A9/a9_lab2.html", {"data":"Please Upload a file", "error":True})
+ return render(request, "Lab/A9/a9_lab2.html", {"data": "Please Upload a file", "error": True})
@authentication_decorator
@@ -721,14 +733,13 @@ def insec_desgine_lab(request):
pass
else:
return redirect('login')
-
-
#-------------------------------------------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------------------------------------------
###################################################### 2021 A1: Broken Access
-@csrf_exempt
+
+@csrf_protect
def a1_broken_access(request):
if not request.user.is_authenticated:
return redirect('login')
@@ -736,43 +747,43 @@ def a1_broken_access(request):
return render(request,"Lab_2021/A1_BrokenAccessControl/broken_access.html")
-@csrf_exempt
+@csrf_protect
def a1_broken_access_lab_1(request):
if request.user.is_authenticated:
pass
else:
return redirect('login')
- name = request.POST.get('name')
- password = request.POST.get('pass')
- print(password)
- print(name)
- if name:
- if request.COOKIES.get('admin') == "1":
- return render(
+ if request.method == 'POST':
+ name = request.POST.get('name')
+ password = request.POST.get('pass')
+ print(password)
+ print(name)
+ if name:
+ if request.COOKIES.get('admin') == "1":
+ return render(
+ request,
+ 'Lab_2021/A1_BrokenAccessControl/broken_access_lab_1.html',
+ {
+ "data":"0NLY_F0R_4DM1N5",
+ "username": "admin"
+ })
+ elif (name=='jack' and password=='jacktheripper'): # Will implement hashing here
+ html = render(
request,
'Lab_2021/A1_BrokenAccessControl/broken_access_lab_1.html',
{
- "data":"0NLY_F0R_4DM1N5",
- "username": "admin"
+ "not_admin":"No Secret key for this User",
+ "username": name
})
- elif (name=='jack' and password=='jacktheripper'): # Will implement hashing here
- html = render(
- request,
- 'Lab_2021/A1_BrokenAccessControl/broken_access_lab_1.html',
- {
- "not_admin":"No Secret key for this User",
- "username": name
- })
- html.set_cookie("admin", "0",max_age=200)
- return html
- else:
- return render(request, 'Lab_2021/A1_BrokenAccessControl/broken_access_lab_1.html', {"data": "User Not Found"})
-
+ html.set_cookie("admin", "0",max_age=200)
+ return html
+ else:
+ return render(request, 'Lab_2021/A1_BrokenAccessControl/broken_access_lab_1.html', {"data": "User Not Found"})
else:
return render(request,'Lab_2021/A1_BrokenAccessControl/broken_access_lab_1.html',{"no_creds":True})
-@csrf_exempt
+@csrf_protect
def a1_broken_access_lab_2(request):
if request.user.is_authenticated:
pass
@@ -832,11 +843,10 @@ def a1_broken_access_lab3_secret(request):
return redirect('login')
# no checking applied here
return render(request, 'Lab_2021/A1_BrokenAccessControl/secret.html')
-
-
###################################################### 2021 A3: Injection
-@csrf_exempt
+
+@csrf_protect
def injection(request):
if not request.user.is_authenticated:
return redirect('login')
@@ -854,7 +864,9 @@ def injection_sql_lab(request):
print(password)
if name:
- sql_query = "SELECT * FROM introduction_sql_lab_table WHERE id='"+name+"'AND password='"+password+"'"
+ with connection.cursor() as cursor:
+ cursor.execute("SELECT * FROM introduction_sql_lab_table WHERE id=%s AND password=%s", [name, password])
+ user = cursor.fetchone()
sql_instance = sql_lab_table(id="admin", password="65079b006e85a7e798abecb99e47c154")
sql_instance.save()
@@ -868,9 +880,9 @@ def injection_sql_lab(request):
print(sql_query)
try:
- user = sql_lab_table.objects.raw(sql_query)
- user = user[0].id
- print(user)
+ if user:
+ user_id = user[0]
+ print(user_id)
except:
return render(
@@ -882,7 +894,7 @@ def injection_sql_lab(request):
})
if user:
- return render(request, 'Lab_2021/A3_Injection/sql_lab.html',{"user1":user})
+ return render(request, 'Lab_2021/A3_Injection/sql_lab.html',{"user1":user_id})
else:
return render(
request,
@@ -914,12 +926,19 @@ def ssrf_lab(request):
return render(request,"Lab/ssrf/ssrf_lab.html",{"blog":"Read Blog About SSRF"})
else:
file=request.POST["blog"]
- try :
- dirname = os.path.dirname(__file__)
- filename = os.path.join(dirname, file)
- file = open(filename,"r")
- data = file.read()
- return render(request,"Lab/ssrf/ssrf_lab.html",{"blog":data})
+ try:
+ # Ensure the file parameter is a basename only, not a path
+ basename = os.path.basename(file)
+ # Use a safe base directory instead of __file__
+ safe_base_dir = os.path.join(os.path.dirname(__file__), 'safe_directory')
+ # Join the safe base directory with the sanitized basename
+ filename = os.path.join(safe_base_dir, basename)
+ # Check if the resulting path is within the safe base directory
+ if os.path.commonprefix([safe_base_dir, os.path.realpath(filename)]) != safe_base_dir:
+ raise ValueError("Unauthorized access attempt to a restricted file.")
+ with open(filename, "r") as file:
+ data = file.read()
+ return render(request, "Lab/ssrf/ssrf_lab.html", {"blog": data})
except:
return render(request, "Lab/ssrf/ssrf_lab.html", {"blog": "No blog found"})
else:
@@ -952,11 +971,17 @@ def ssrf_lab2(request):
elif request.method == "POST":
url = request.POST["url"]
+ # Validate the URL to ensure it is not pointing to internal resources
+ if not re.match(r'https?://', url):
+ return render(request, "Lab/ssrf/ssrf_lab2.html", {"error": "Invalid URL scheme"})
+ parsed_url = urlparse(url)
+ if parsed_url.hostname and re.match(r'^(localhost|127\.0\.0\.1|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|192\.168\.)', parsed_url.hostname):
+ return render(request, "Lab/ssrf/ssrf_lab2.html", {"error": "Access to internal resources is not allowed"})
try:
- response = requests.get(url)
+ response = requests.get(url, timeout=5) # Set a reasonable timeout for the request
return render(request, "Lab/ssrf/ssrf_lab2.html", {"response": response.content.decode()})
except:
- return render(request, "Lab/ssrf/ssrf_lab2.html", {"error": "Invalid URL"})
+ return render(request, "Lab/ssrf/ssrf_lab2.html", {"error": "Invalid URL or Timeout"})
#--------------------------------------- Server-side template injection --------------------------------------#
def ssti(request):
@@ -965,12 +990,19 @@ def ssti(request):
else:
return redirect('login')
+def filter_blog(blog_content):
+ # Neutralize any HTML tags to prevent XSS
+ blog_content = html.escape(blog_content)
+ # Neutralize CRLF characters to prevent CRLF Injection
+ blog_content = re.sub(r'(\r\n|\r|\n)', ' ', blog_content)
+ return blog_content
+
def ssti_lab(request):
if request.user.is_authenticated:
- if request.method=="GET":
+ if request.method == "GET":
users_blogs = Blogs.objects.filter(author=request.user)
- return render(request,"Lab_2021/A3_Injection/ssti_lab.html", {"blogs":users_blogs})
- elif request.method=="POST":
+ return render(request, "Lab_2021/A3_Injection/ssti_lab.html", {"blogs": users_blogs})
+ elif request.method == "POST":
blog = request.POST["blog"]
id = str(uuid.uuid4()).split('-')[-1]
@@ -979,15 +1011,14 @@ def ssti_lab(request):
{% block content %}{% block title %}\
SSTI-Blogs\
{% endblock %}"
-
+
blog = prepend_code + blog + "{% endblock %}"
- new_blog = Blogs.objects.create(author = request.user, blog_id = id)
- new_blog.save()
+ new_blog = Blogs.objects.create(author=request.user, blog_id=id)
+ new_blog.save()
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, f"templates/Lab_2021/A3_Injection/Blogs/{id}.html")
- file = open(filename, "w+")
- file.write(blog)
- file.close()
+ with open(filename, "w+") as file:
+ file.write(blog)
return redirect(f'blog/{id}')
else:
return redirect('login')
@@ -1016,7 +1047,12 @@ def crypto_failure_lab(request):
username = request.POST["username"]
password = request.POST["password"]
try:
- password = md5(password.encode()).hexdigest()
+ # Generate a random salt
+ salt = hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
+ # Hash the password with the salt using SHA-256
+ pwdhash = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 100000)
+ # Store the salt and the hash in a single string
+ password = binascii.hexlify(pwdhash).decode('ascii')
user = CF_user.objects.get(username=username,password=password)
return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab.html",{"user":user, "success":True,"failure":False})
except:
@@ -1066,20 +1102,19 @@ def crypto_failure_lab3(request):
expire = datetime.datetime.now() + datetime.timedelta(minutes=60)
cookie = f"{username}|{expire}"
response = render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html",{"success":True, "failure":False , "admin":False})
- response.set_cookie("cookie", cookie)
+ response.set_cookie("cookie", cookie, secure=True)
response.status_code = 200
return response
else:
response = render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab3.html",{"success":False, "failure":True})
- response.set_cookie("cookie", None)
+ response.set_cookie("cookie", None, secure=True)
return response
except:
return render(request,"Lab_2021/A2_Crypto_failur/crypto_failure_lab2.html",{"success":False, "failure":True})
+
#-----------------------------------------------SECURITY MISCONFIGURATION -------------------
from pygoat.settings import SECRET_COOKIE_KEY
-
-
def sec_misconfig_lab3(request):
if not request.user.is_authenticated:
return redirect('login')
@@ -1099,7 +1134,7 @@ def sec_misconfig_lab3(request):
cookie = jwt.encode(payload, SECRET_COOKIE_KEY, algorithm='HS256')
response = render(request,"Lab/sec_mis/sec_mis_lab3.html", {"admin":False} )
- response.set_cookie(key = "auth_cookie", value = cookie)
+ response.set_cookie(key = "auth_cookie", value = cookie, secure=True, httponly=True)
return response
# - ------------------------Identification and Authentication Failures--------------------------------
@@ -1159,16 +1194,7 @@ def auth_failure_lab2(request):
"User3":{"userid":"3", "username":"User3", "password": "5a91a66f0c86b5435fe748706b99c17e6e54a17e03c2a3ef8d0dfa918db41cf6"},
"User4":{"userid":"4", "username":"User4", "password": "6046bc3337728a60967a151ee584e4fd7c53740a49485ebdc38cac42a255f266"}
}
-
-# USER_A7_LAB3 = {
-# "User1":{"userid":"1", "username":"User1", "password": "Hash1"},
-# "User2":{"userid":"2", "username":"User2", "password": "Hash2"},
-# "User3":{"userid":"3", "username":"User3", "password": "Hash3"},
-# "User4":{"userid":"4", "username":"User4", "password": "Hash4"}
-# }
-
@authentication_decorator
-@csrf_exempt
def auth_failure_lab3(request):
if request.method == "GET":
try:
@@ -1187,14 +1213,14 @@ def auth_failure_lab3(request):
password = hashlib.sha256(password.encode()).hexdigest()
except:
response = render(request, "Lab_2021/A7_auth_failure/lab3.html")
- response.set_cookie("session_id", None)
+ response.set_cookie("session_id", None, secure=True, httponly=True)
return response
if USER_A7_LAB3[username]['password'] == password:
session_data = AF_session_id.objects.create(session_id=token, user=USER_A7_LAB3[username]['username'])
session_data.save()
response = render(request, "Lab_2021/A7_auth_failure/lab3.html", {"success":True, "failure":False, "username":username})
- response.set_cookie("session_id", token)
+ response.set_cookie("session_id", token, secure=True, httponly=True)
return response
#-- coding playground for lab2