Use `directory?` not `exists?` when checking if a directory exists

Author: bwatters-r7Created Aug 26, 2026Updated Sep 7, 2026
Labelsbug

I noticed that a PR used exists? to validate writable_dir That is a bad thing, since exists? is a file check, so will return true if there is a file or directory there. Instead, we should be using directory? This is also a great time to use the new Windows writable? method that got added a few days ago.

tmoose@bw-dev-2026:~/git/metasploit-framework (upstream-master)$ git grep -i writ | grep -i dir | grep 'exists?'
modules/exploits/example_linux_persistence.rb:    return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)
modules/exploits/linux/persistence/apt_package_manager.rb:    return CheckCode::Safe("#{writable_dir} not found") unless exists?(writable_dir)
modules/exploits/linux/persistence/docker_image.rb:    return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)
modules/exploits/linux/persistence/init_openrc.rb:    return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)
modules/exploits/linux/persistence/init_systemd.rb:    return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)
modules/exploits/linux/persistence/init_systemd_override.rb:      return CheckCode::Safe("No write access to #{service_dir}") if !exists?(override_conf) && !writable?(service_dir)
modules/exploits/linux/persistence/udev.rb:    return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)
modules/exploits/linux/persistence/yum_package_manager.rb:    return CheckCode::Safe("#{datastore['WritableDir']} does not exist") unless exists? datastore['WritableDir']
modules/exploits/multi/persistence/at.rb:    return CheckCode::Safe("#{datastore['WritableDir']} does not exist") unless exists? datastore['WritableDir']
modules/exploits/windows/persistence/accessibility_features_debugger.rb:    return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)
modules/exploits/windows/persistence/assistive_technology.rb:    return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)
modules/exploits/windows/persistence/bits.rb:    return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)
modules/exploits/windows/persistence/image_exec_options.rb:    return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)
modules/exploits/windows/persistence/registry_userinit.rb:    return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)
modules/exploits/windows/persistence/service.rb:    return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)
modules/exploits/windows/persistence/service_for_user/event.rb:    return CheckCode::Safe("#{writable_dir} doesn't exist") unless exists?(writable_dir)
modules/exploits/windows/persistence/service_for_user/lock_unlock.rb:    return CheckCode::Safe("#{writable_dir} doesn't exist") unless exists?(writable_dir)
modules/exploits/windows/persistence/service_for_user/logon.rb:    return CheckCode::Safe("#{writable_dir} doesn't exist") unless exists?(writable_dir)
modules/exploits/windows/persistence/service_for_user/schedule.rb:    return CheckCode::Safe("#{writable_dir} doesn't exist") unlessexists?(writable_dir)
modules/exploits/windows/persistence/task_scheduler.rb:    return CheckCode::Safe("#{writable_dir} doesn't exist") unless exists?(writable_dir)
modules/exploits/windows/persistence/userinit_mpr_logon_script.rb:    return CheckCode::Safe("#{writable_dir} does not exist") unless exists?(writable_dir)

I also noticed it is in our example module
@jheysel-r7, I'm tagging you since you were the one that first noticed and you might want to stay in the loop.

Source: rapid7/metasploit-framework