CVE-2018-6198 (published 2018-01-25T03:29Z)

w3m through 0.5.3 does not properly handle temporary files when the ~/.w3m directory is unwritable, which allows a local attacker to craft a symlink attack to overwrite arbitrary files.

Severity: LOW
CVSS v2 base score: 3.3 (AV:L/AC:M/Au:N/C:N/I:P/A:P)
CVSS v3 base score: 4.7, MEDIUM (CVSS:3.0/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:N)

Weakness information:
cwe_id: CWE-59
cwe_name: Improper Link Resolution Before File Access ('Link Following')
description: The product attempts to access a file based on the filename, but it does not properly prevent that filename from identifying a link or shortcut that resolves to an unintended resource.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/tats/w3m
commit_details: repo_url: https://github.com/tats/w3m
author: Tatsuya Kinoshita
author_date: 2018-01-21 01:29:10+09:00
msg: Make temporary directory safely when ~/.w3m is unwritable
repository: repo_url: https://github.com/tats/w3m
repo_name: tats/w3m
description: Debian's w3m: WWW browsable pager
repo_language: C
owner: tats
file_changes: filename: config.h.dist
change_type: ModificationType.MODIFY
diff: @@ -210,6 +210,7 @@ typedef long clen_t;
 #define HAVE_SRANDOM
 #undef HAVE_GETPASSPHRASE
 #define HAVE_CHDIR
+#define HAVE_MKDTEMP
 
 
 #define SETJMP(env) sigsetjmp(env,1)

programming_language: Shell
filename: config.h.in
change_type: ModificationType.MODIFY
diff: @@ -143,6 +143,7 @@ typedef long clen_t;
 #undef HAVE_SRANDOM
 #undef HAVE_GETPASSPHRASE
 #undef HAVE_CHDIR
+#undef HAVE_MKDTEMP
 #undef HAVE_SETPGRP
 #undef HAVE_SETLOCALE
 #undef HAVE_LANGINFO_CODESET

programming_language: Ruby
filename: configure
change_type: ModificationType.MODIFY
diff: @@ -8767,7 +8767,7 @@ _ACEOF
 
 
 
-for ac_func in strcasecmp strcasestr strchr memcpy strerror bcopy setpgrp chdir getcwd getwd readlink setenv putenv strtoll stroq atoll atoq symlink readlink lstat srand48 srandom getpassphrase waitpid setlocale
+for ac_func in strcasecmp strcasestr strchr memcpy strerror bcopy setpgrp chdir mkdtemp getcwd getwd readlink setenv putenv strtoll stroq atoll atoq symlink readlink lstat srand48 srandom getpassphrase waitpid setlocale
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"

programming_language: Shell
filename: configure.ac
change_type: ModificationType.MODIFY
diff: @@ -150,7 +150,7 @@ dnl AC_FUNC_MEMCMP
 dnl AC_FUNC_MMAP
 dnl AC_FUNC_SETVBUF_REVERSED
 dnl AC_FUNC_VPRINTF
-AC_CHECK_FUNCS(strcasecmp strcasestr strchr memcpy strerror bcopy setpgrp chdir getcwd getwd readlink setenv putenv strtoll stroq atoll atoq symlink readlink lstat srand48 srandom getpassphrase waitpid setlocale)
+AC_CHECK_FUNCS(strcasecmp strcasestr strchr memcpy strerror bcopy setpgrp chdir mkdtemp getcwd getwd readlink setenv putenv strtoll stroq atoll atoq symlink readlink lstat srand48 srandom getpassphrase waitpid setlocale)
 AC_FUNC_STRFTIME
 AC_FUNC_WAIT3
 AC_FUNC_SETPGRP

programming_language: Shell
filename: main.c
change_type: ModificationType.MODIFY
diff: @@ -5971,6 +5971,13 @@ w3m_exit(int i)
 #endif
 #ifdef __MINGW32_VERSION
     WSACleanup();
+#endif
+#ifdef HAVE_MKDTEMP
+    if (no_rc_dir && tmp_dir != rc_dir)
+	if (rmdir(tmp_dir) != 0) {
+	    fprintf(stderr, "Can't remove temporary directory (%s)!\n", tmp_dir);
+	    exit(1);
+	}
 #endif
     exit(i);
 }

programming_language: C
filename: rc.c
change_type: ModificationType.MODIFY
diff: @@ -1330,6 +1330,11 @@ init_rc(void)
 	((tmp_dir = getenv("TMP")) == NULL || *tmp_dir == '\0') &&
 	((tmp_dir = getenv("TEMP")) == NULL || *tmp_dir == '\0'))
 	tmp_dir = "/tmp";
+#ifdef HAVE_MKDTEMP
+    tmp_dir = mkdtemp(Strnew_m_charp(tmp_dir, "/w3m-XXXXXX", NULL)->ptr);
+    if (tmp_dir == NULL)
+	tmp_dir = rc_dir;
+#endif
     create_option_search_table();
     goto open_rc;
 }

programming_language: C++