diff --git a/test-images/demo-python3/Dockerfile b/test-images/demo-python3/Dockerfile
index 89033a2cfe0c3cfe64cde534bbbf1cfbc81597b2..471854b2cf1772a7e4075625fbeb34296a66cac1 100644
--- a/test-images/demo-python3/Dockerfile
+++ b/test-images/demo-python3/Dockerfile
@@ -1,5 +1,11 @@
 FROM python:3.13.0b3-alpine3.20
+
+# Create a less-privileged user to run student's code and install sudo
+RUN addgroup -S student && adduser -S student -G student
+RUN apk add --no-cache --update sudo
+
 WORKDIR /usr/src/app
 COPY ./grade.sh grade.sh
 RUN chmod +x grade.sh
+
 CMD ["./grade.sh"]
diff --git a/test-images/demo-python3/README.md b/test-images/demo-python3/README.md
index d85e6996aa5d685b41753e7e6c7fd4c1568d556a..5f81582726073041b0dc013817a1c234a049c613 100644
--- a/test-images/demo-python3/README.md
+++ b/test-images/demo-python3/README.md
@@ -19,8 +19,9 @@ After building the image you can try out the grading image locally, by mounting
 Example submissions are provided in `./test_submissions`. For instance, to grade the correct submission `/test_submissions/correct.py` using the image, run the following command:
 
 ```bash
+rm -rf feedback
 mkdir feedback
-docker run -v ./feedback:/data/feedback -v ./test_submissions/correct.py:/data/submission/script.py demo-python3
+docker run --rm -v ./feedback:/data/feedback -v ./test_submissions/correct.py:/data/submission/script.py demo-python3
 cat feedback/grade.json
 ```
 
diff --git a/test-images/demo-python3/grade.sh b/test-images/demo-python3/grade.sh
index c9e792a7995cf046123d2c297cccc783fa13c68c..aec09ff0c527e6449d5a55ebcdbf821e1d422bbd 100644
--- a/test-images/demo-python3/grade.sh
+++ b/test-images/demo-python3/grade.sh
@@ -3,32 +3,42 @@
 save_feedback() {
     grade=$1
     feedback=$2
+
     # Feedback must be saved in `/data/feedback`.
     # - `grade.json`, must be a JSON file with {"grade": grade_as_a_number}
     # - other file are attached as feedback files
+    echo "[*] Saving grade $grade and feedback \"$feedback\""
     mkdir -p /data/feedback
     echo "{\"grade\": $grade}" > /data/feedback/grade.json
     echo "$feedback" > /data/feedback/feedback.txt
+    exit 0
 }
 
 grade() {
     # Files submitted by the student are mounted in `/data/submission`.
-    if [ -f /data/submission/script.py ]; then
-        output=$(python3 /data/submission/script.py)
-        echo "[*] Python output: $output"
-        if [ "Hello World!" == "$output" ]; then
-            save_feedback 100 "The output is correct, well done! :)"
-        else
-            save_feedback 0 "The output is not correct :'("
-        fi
-    else
+
+    if [ ! -f /data/submission/script.py ]; then
         save_feedback 0 "I have not found the script.py file :'("
     fi
+
+    # Run the script under the restricted `student` user with a timeout of 1
+    # minute, and capture the output.
+    cp /data/submission/script.py /home/student/script.py
+    chmod -R 700 /data
+    chmod 755 /home/student/script.py
+    output=$(timeout 1m sudo -u student python3 /home/student/script.py 2>&1)
+
+    echo "[*] Python output: $output"
+    if [ "$output" == "Hello World!" ]; then
+        save_feedback 100 "The output is correct, well done! :)"
+    else
+        save_feedback 0 "The output is not correct :'("
+    fi
 }
 
 handle_internal_error() {
-    save_feedback 0 "An internal error occurred, please contact your teacher."
+    save_feedback 0 "An internal error occurred, please contact the teaching team."
 }
 
-# Important: always exit with 0
+# Important: make sure to always exit with 0
 grade || handle_internal_error
diff --git a/test-images/demo-python3/test_submissions/malicious.py b/test-images/demo-python3/test_submissions/malicious.py
new file mode 100755
index 0000000000000000000000000000000000000000..3951052e7f548bcc87a23c075b9567103714ea88
--- /dev/null
+++ b/test-images/demo-python3/test_submissions/malicious.py
@@ -0,0 +1,13 @@
+import os
+import json
+
+os.system("ls -l /data/submission")
+os.system("whoami")
+
+os.makedirs('/data/feedback', exist_ok=True)
+
+with open("/data/feedback/grade.json", "w") as f:
+    json.dump({"grade": 100}, f)
+
+with open("/data/feedback/ahah.txt", "w") as f:
+    f.write("Ahah")