diff --git a/docker-compose.yml b/docker-compose.yml index 3d39f83..8172fb0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,6 +9,9 @@ services: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres + security_opt: + - no-new-privileges:true + read_only: true web: build: . image: pygoat/pygoat @@ -20,6 +23,9 @@ services: depends_on: - migration - db + security_opt: + - no-new-privileges:true + read_only: true migration: image: pygoat/pygoat command: python pygoat/manage.py migrate --noinput @@ -27,3 +33,6 @@ services: - .:/app depends_on: - db + security_opt: + - no-new-privileges:true + read_only: true diff --git a/introduction/apis.py b/introduction/apis.py index 7926708..a3b90e6 100644 --- a/introduction/apis.py +++ b/introduction/apis.py @@ -12,14 +12,6 @@ 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': @@ -55,8 +47,6 @@ def ssrf_code_checker(request): # Insufficient Logging & Monitoring - -@csrf_exempt # @authentication_decorator def log_function_checker(request): if request.method == 'POST': @@ -67,10 +57,10 @@ def log_function_checker(request): 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.write(escape(log_code)) f.close() f = open(api_filename,"w") - f.write(api_code) + f.write(escape(api_code)) f.close() # Clearing the log file before starting the test f = open('test.log', 'w') @@ -90,7 +80,6 @@ def log_function_checker(request): return JsonResponse({"message":"method not allowed"},status = 405) #a7 codechecking api -@csrf_exempt def A7_disscussion_api(request): if request.method != 'POST': return JsonResponse({"message":"method not allowed"},status = 405) @@ -109,7 +98,6 @@ def A7_disscussion_api(request): return JsonResponse({"message":"failure"},status = 400) #a6 codechecking api -@csrf_exempt def A6_disscussion_api(request): test_bench = ["Pillow==8.0.0","PyJWT==2.4.0","requests==2.28.0","Django==4.0.4"] @@ -122,7 +110,6 @@ def A6_disscussion_api(request): except Exception as e: return JsonResponse({"message":"failure"},status = 400) -@csrf_exempt def A6_disscussion_api_2(request): if request.method != 'POST': return JsonResponse({"message":"method not allowed"},status = 405) @@ -131,8 +118,8 @@ def A6_disscussion_api_2(request): dirname = os.path.dirname(__file__) filename = os.path.join(dirname, "playground/A6/utility.py") f = open(filename,"w") - f.write(code) + f.write(escape(code)) f.close() except: return JsonResponse({"message":"missing code"},status = 400) - return JsonResponse({"message":"success"},status = 200) \ No newline at end of file + return JsonResponse({"message":"success"},status = 200) diff --git a/introduction/mitre.py b/introduction/mitre.py index c899c21..3a830c8 100644 --- a/introduction/mitre.py +++ b/introduction/mitre.py @@ -150,7 +150,6 @@ def mitre_top24(request): def mitre_top25(request): if request.method == 'GET': return render(request, 'mitre/mitre_top25.html') - @authentication_decorator def csrf_lab_login(request): if request.method == 'GET': @@ -158,7 +157,7 @@ def csrf_lab_login(request): elif request.method == 'POST': password = request.POST.get('password') username = request.POST.get('username') - password = md5(password.encode()).hexdigest() + password = hashlib.scrypt(password.encode(), salt=os.environ.get('SALT').encode(), n=16384, r=8, p=1).hex() User = CSRF_user_tbl.objects.filter(username=username, password=password) if User: payload ={ @@ -166,15 +165,14 @@ def csrf_lab_login(request): 'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=300), 'iat': datetime.datetime.utcnow() } - cookie = jwt.encode(payload, 'csrf_vulneribility', algorithm='HS256') + cookie = jwt.encode(payload, os.environ.get('JWT_SECRET'), algorithm='HS256') response = redirect("/mitre/9/lab/transaction") - response.set_cookie('auth_cookiee', cookie) + response.set_cookie('auth_cookiee', cookie, secure=True, httponly=True, samesite='Lax') return response else : return redirect('/mitre/9/lab/login') @authentication_decorator -@csrf_exempt def csrf_transfer_monei(request): if request.method == 'GET': try: @@ -188,6 +186,7 @@ def csrf_transfer_monei(request): except: return redirect('/mitre/9/lab/login') + def csrf_transfer_monei_api(request,recipent,amount): if request.method == "GET": cookie = request.COOKIES['auth_cookiee'] @@ -208,19 +207,20 @@ def csrf_transfer_monei_api(request,recipent,amount): return redirect('/mitre/9/lab/transaction') else: return redirect ('/mitre/9/lab/transaction') - - # @authentication_decorator -@csrf_exempt def mitre_lab_25_api(request): if request.method == "POST": expression = request.POST.get('expression') - result = eval(expression) + try: + result = ast.literal_eval(expression) + except (SyntaxError, ValueError): + return JsonResponse({'error': 'Invalid expression'}, status=400) return JsonResponse({'result': result}) else: return redirect('/mitre/25/lab/') + @authentication_decorator def mitre_lab_25(request): return render(request, 'mitre/mitre_lab_25.html') @@ -228,13 +228,11 @@ def mitre_lab_25(request): @authentication_decorator 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) + process = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) return process.communicate() -@csrf_exempt def mitre_lab_17_api(request): if request.method == "POST": ip = request.POST.get('ip') @@ -244,4 +242,4 @@ def mitre_lab_17_api(request): err = err.decode() pattern = "STATE SERVICE.*\\n\\n" ports = re.findall(pattern, res,re.DOTALL)[0][14:-2].split('\n') - return JsonResponse({'raw_res': str(res), 'raw_err': str(err), 'ports': ports}) \ No newline at end of file + return JsonResponse({'raw_res': str(res), 'raw_err': str(err), 'ports': ports}) diff --git a/introduction/playground/A9/api.py b/introduction/playground/A9/api.py index 35e1bd2..758fbb9 100644 --- a/introduction/playground/A9/api.py +++ b/introduction/playground/A9/api.py @@ -4,7 +4,6 @@ from .main import Log -@csrf_exempt def log_function_target(request): L = Log(request) if request.method == "GET": @@ -30,4 +29,4 @@ def log_function_target(request): 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":"method not allowed"},status = 403) diff --git a/introduction/playground/A9/archive.py b/introduction/playground/A9/archive.py index c9db8fc..1d99ead 100644 --- a/introduction/playground/A9/archive.py +++ b/introduction/playground/A9/archive.py @@ -4,7 +4,6 @@ from .main import Log -@csrf_exempt def log_function_target(request): L = Log(request) if request.method == "GET": @@ -60,3 +59,4 @@ def error(self,msg): f = open('test.log', 'a') f.write(f"ERROR:{now}:{msg}\n") f.close() + diff --git a/introduction/static/js/a9.js b/introduction/static/js/a9.js index 9c58b8a..738109d 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]; 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 @@