diff -upr a/configure.ac b/configure.ac
--- a/configure.ac	Sat Feb 14 19:51:08 2026
+++ b/configure.ac	Thu Feb 19 13:51:55 2026
@@ -44,6 +44,11 @@ AC_ARG_ENABLE([insure],
   [enable_insure=$enableval],
   [enable_insure=no])
 
+AC_ARG_ENABLE([unveil],
+  [AS_HELP_STRING([--enable-unveil], [Build with support for unveil])],
+  [enable_unveil=$enableval],
+  [enable_unveil=no])
+
 AC_ARG_ENABLE([ipv6],
   [AS_HELP_STRING([--enable-ipv6], [Build with support for IPv6 (default: auto)])],
   [enable_ipv6=$enableval],
@@ -794,6 +799,9 @@ if test "x$enable_insure" = "xyes" ; then
   CC="insure -Zoi \"compiler $CC\""
   LIBS="$LIBS -lstdc++-2-libc6.1-1-2.9.0"
 fi
+if test "x$enable_unveil" = "xyes" ; then
+  AC_DEFINE([ENABLE_UNVEIL], [1], [Enable unveil])
+fi
 if test "x$enable_threaded_dns" = "xyes" ; then
   CFLAGS="$CFLAGS -DD_DNS_THREADED"
 fi
@@ -938,5 +946,6 @@ _AS_ECHO([  SVG enabled    : ${enable_svg}])
 _AS_ECHO([  WEBP enabled   : ${webp_ok}])
 _AS_ECHO([  Brotli enabled : ${brotli_ok}])
 _AS_ECHO([  IPv6 enabled   : ${enable_ipv6}])
+_AS_ECHO([  Unveil enabled : ${enable_unveil}])
 _AS_ECHO([  Control socket : ${enable_control_socket} (experimental)])
 _AS_ECHO([])
diff -upr a/dlib/dlib.c b/dlib/dlib.c
--- a/dlib/dlib.c	Sat Feb 14 19:51:08 2026
+++ b/dlib/dlib.c	Thu Feb 19 13:51:55 2026
@@ -949,6 +949,99 @@ char *dGethomedir (void)
 }
 
 /**
+ * Return the save directory in a static string
+ */
+char *dGetsavedir (void)
+{
+   static char *dillorc = NULL;
+   dillorc = dStrconcat(dGethomedir(), "/", ".dillo/dillorc", NULL);
+   FILE *In;
+   int len;
+   char *rcline = NULL, *value = NULL, *p;
+   if ((In = fopen(dillorc, "r")) == NULL) {
+      DLIB_MSG("dGetsavedir: unable to open dillorc.\n");
+      return (NULL);
+   }
+   while ((rcline = dGetline(In)) != NULL) {
+      if (strncmp(rcline, "save_dir", 8) == 0)
+         break;
+      dFree(rcline);
+   }
+   fclose(In);
+   if (!rcline) {
+      value = NULL;
+      DLIB_MSG("dGetsavedir: no 'save_dir' in dillorc..\n");
+   } else {
+      len = (int) strlen(rcline);
+      if (len && rcline[len - 1] == '\n')
+         rcline[len - 1] = 0;
+      if ((p = strchr(rcline, '='))) {
+         while (*++p == ' ');
+         value = dStrdup(p);
+      } else {
+         value = NULL;
+	 DLIB_MSG("dGetsavedir: error parsing value in dillorc.\n");
+      }
+   }
+   dFree(rcline);
+   return (value);
+}
+
+/**
+ * Return the enable_unveil value in a static string
+ */
+char *dGetenableunveil (void)
+{
+   static char *dillorc = NULL;
+   dillorc = dStrconcat(dGethomedir(), "/", ".dillo/dillorc", NULL);
+   FILE *In;
+   int len;
+   char *rcline = NULL, *value = NULL, *p;
+   if ((In = fopen(dillorc, "r")) == NULL) {
+      DLIB_MSG("dGetenableunveil: unable to open dillorc.\n");
+      return (NULL);
+   }
+   while ((rcline = dGetline(In)) != NULL) {
+      if (strncmp(rcline, "enable_unveil", 13) == 0)
+         break;
+      dFree(rcline);
+   }
+   fclose(In);
+   if (!rcline) {
+      value = NULL;
+      DLIB_MSG("dGetenableunveil: no 'enable_unveil' in dillorc.\n");
+   } else {
+      len = (int) strlen(rcline);
+      if (len && rcline[len - 1] == '\n')
+         rcline[len - 1] = 0;
+      if ((p = strchr(rcline, '='))) {
+         while (*++p == ' ');
+         value = dStrdup(p);
+      } else {
+         value = NULL;
+	 DLIB_MSG("dGetenableunveil: error parsing value in dillorc.\n");
+      }
+   }
+   dFree(rcline);
+   return (value);
+}
+
+/**
+ * Use unveil on OpenBSD
+ */
+void *dUnveil(const char *path, const char *perm)
+{
+    #ifdef ENABLE_UNVEIL
+    #ifdef __OpenBSD__
+    if (unveil(path, perm) == -1) {
+       DLIB_MSG("unveil(%s, %s) failed: %s\n", path, perm, strerror(errno));
+       exit(1);
+    }
+    #endif
+    #endif
+}
+
+/**
  * Get a line from a FILE stream.
  * Return value: read line on success, NULL on EOF.
  */
diff -upr a/dlib/dlib.h b/dlib/dlib.h
--- a/dlib/dlib.h	Sat Feb 14 19:51:08 2026
+++ b/dlib/dlib.h	Thu Feb 19 13:51:55 2026
@@ -205,6 +205,9 @@ void dLib_show_messages(bool_t show);
  */
 char *dGetcwd(void);
 char *dGethomedir(void);
+char *dGetsavedir(void);
+char *dGetenableunveil(void);
+void *dUnveil(const char *path, const char *perm);
 char *dGetline(FILE *stream);
 int dClose(int fd);
 int dUsleep(unsigned long us);
diff -upr a/src/dillo.cc b/src/dillo.cc
--- a/src/dillo.cc	Sat Feb 14 19:51:08 2026
+++ b/src/dillo.cc	Thu Feb 19 13:51:55 2026
@@ -494,7 +494,48 @@ int main(int argc, char **argv)
       fclose(fp);
    }
    dLib_show_messages(prefs.show_msg);
-
+   
+   // Use unveil
+   if (dGetenableunveil() != NULL) {
+      if (strncmp(dGetenableunveil(), "YES", 3) == 0) {
+         #ifdef ENABLE_UNVEIL
+	  const char *home = dGethomedir();
+         const char *save = prefs.save_dir;
+         int nsave = strlen(save);
+         int nhome = strlen(home);
+         if (nsave <= nhome) {
+            /* Prevent save_dir="/home" and save_dir=$HOME */
+            if (strncmp(save, home, nsave) == 0) {
+            MSG("save_dir cannot contain home\n");
+            exit(1);
+            }
+         }
+	  dUnveil("/bin/sh", "x");
+         dUnveil("/usr/local/share/fonts", "r");
+         dUnveil("/usr/local/share/icons", "r");
+         dUnveil("/usr/X11R6/share/X11/locale", "r");
+         dUnveil("/usr/X11R6/lib/X11/fonts", "r");
+         dUnveil("/usr/local/etc/dillo", "r");
+         dUnveil("/tmp", "rwc");
+         dUnveil("/usr/local/bin/dpid", "x");
+         dUnveil("/etc/fonts", "r");
+         dUnveil("/etc/resolv.conf", "r");
+         dUnveil("/etc/ssl/cert.pem", "r");
+         dUnveil(prefs.save_dir, "rwc");
+         char *dil_loc = dStrconcat(dGethomedir(), "/.dillo", NULL);
+         dUnveil(dil_loc, "rwc");
+         dFree(dil_loc);
+         char *icons_loc = dStrconcat(dGethomedir(), "/.icons", NULL);
+         dUnveil(icons_loc, "r");
+         dFree(icons_loc);
+         char *xauth_loc = dStrconcat(dGethomedir(), "/.Xauthority", NULL);
+         dUnveil(xauth_loc, "r");
+         dFree(xauth_loc);
+         dUnveil(NULL, NULL);
+         #endif
+      } 
+   }
+    
    // initialize internal modules
    a_Dpi_init();
    a_Dns_init();
diff -upr a/src/prefs.c b/src/prefs.c
--- a/src/prefs.c	Sat Feb 14 19:51:08 2026
+++ b/src/prefs.c	Thu Feb 19 13:57:14 2026
@@ -72,6 +72,7 @@ void a_Prefs_init(void)
    prefs.http_strict_transport_security = TRUE;
    prefs.http_force_https = FALSE;
    prefs.http_user_agent = dStrdup(PREFS_HTTP_USER_AGENT);
+   prefs.enable_unveil = FALSE;
    prefs.limit_text_width = FALSE;
    prefs.adjust_min_width = TRUE;
    prefs.adjust_table_min_width = TRUE;
diff -upr a/src/prefs.h b/src/prefs.h
--- a/src/prefs.h	Sat Feb 14 19:51:08 2026
+++ b/src/prefs.h	Thu Feb 19 13:55:03 2026
@@ -105,6 +105,7 @@ typedef struct {
    bool_t http_persistent_conns;
    bool_t http_strict_transport_security;
    bool_t http_force_https;
+   bool_t enable_unveil;
    int32_t buffered_drawing;
    char *font_serif;
    char *font_sans_serif;
diff -upr a/src/prefsparser.cc b/src/prefsparser.cc
--- a/src/prefsparser.cc	Sat Feb 14 19:51:08 2026
+++ b/src/prefsparser.cc	Thu Feb 19 13:59:07 2026
@@ -181,6 +181,7 @@ void PrefsParser::parse(FILE *fp)
         PREFS_BOOL, 0 },
       { "http_force_https", &prefs.http_force_https, PREFS_BOOL, 0 },
       { "http_user_agent", &prefs.http_user_agent, PREFS_STRING, 0 },
+      { "enable_unveil", &prefs.enable_unveil, PREFS_BOOL, 0 },
       { "limit_text_width", &prefs.limit_text_width, PREFS_BOOL, 0 },
       { "adjust_min_width", &prefs.adjust_min_width, PREFS_BOOL, 0 },
       { "adjust_table_min_width", &prefs.adjust_table_min_width, PREFS_BOOL, 0 },
diff -upr a/src/version.cc b/src/version.cc
--- a/src/version.cc	Sat Feb 14 19:51:08 2026
+++ b/src/version.cc	Thu Feb 19 13:51:55 2026
@@ -151,6 +151,11 @@ static void print_features()
 #else
          " -CTL"
 #endif
+#ifdef ENABLE_UNVEIL
+         " +UNVEIL"
+#else
+         " -UNVEIL"
+#endif
          "\n");
 }
 
