diff --git a/pycardium/modules/fat_file.c b/pycardium/modules/fat_file.c
index a5ddcd8ae7684f183b00a38ff5c3eba64568d5ca..b030466fa407de2da598fbb1f8d1e15754e21378 100644
--- a/pycardium/modules/fat_file.c
+++ b/pycardium/modules/fat_file.c
@@ -1,5 +1,5 @@
 /*
- * based on micropytohn/ports/unix/file.c
+ * based on micropython/ports/unix/file.c
  */
 
 #include <stdio.h>
@@ -12,6 +12,24 @@
 
 #include "epicardium.h"
 
+#include <strings.h>
+
+bool filename_restricted(const char *fname)
+{
+	// files that cannot be opened in write modes
+	const char *const forbidden_files[] = {
+		"cardio.bin", "menu.py", "main.py", "cardio.cfg"
+	};
+	for (int i = 0;
+	     i < sizeof(forbidden_files) / sizeof(forbidden_files[0]);
+	     i++) {
+		if (strcasecmp(fname, forbidden_files[i]) == 0) {
+			return true;
+		}
+	}
+	return false;
+}
+
 extern const mp_obj_type_t mp_type_textio;
 #if MICROPY_PY_IO_FILEIO
 extern const mp_obj_type_t mp_type_fileio;
@@ -120,8 +138,9 @@ STATIC const mp_arg_t file_open_args[] = {
 
 STATIC mp_obj_t file_open(const mp_obj_type_t *type, mp_arg_val_t *args)
 {
-	const char *modeString = mp_obj_str_get_str(args[1].u_obj);
-	const char *mode_s     = modeString;
+	bool potentially_critical_access = false;
+	const char *modeString           = mp_obj_str_get_str(args[1].u_obj);
+	const char *mode_s               = modeString;
 	// modes r w x a + are handled on epicardium side, binary / text
 	// is relevant for python type so look for these here
 	while (*mode_s) {
@@ -134,6 +153,12 @@ STATIC mp_obj_t file_open(const mp_obj_type_t *type, mp_arg_val_t *args)
 		case 't':
 			type = &mp_type_textio;
 			break;
+		case 'w':
+		case 'x':
+		case 'a':
+		case '+':
+			potentially_critical_access = true;
+			break;
 		}
 	}
 
@@ -141,7 +166,12 @@ STATIC mp_obj_t file_open(const mp_obj_type_t *type, mp_arg_val_t *args)
 	o->base.type         = type;
 
 	const char *fname = mp_obj_str_get_str(args[0].u_obj);
-	int res           = epic_file_open(fname, modeString);
+
+	if (potentially_critical_access && filename_restricted(fname)) {
+		mp_raise_OSError(-EPERM);
+	}
+
+	int res = epic_file_open(fname, modeString);
 	if (res < 0) {
 		m_del_obj(fat_py_file_obj_t, o);
 		mp_raise_OSError(-res);