Players are able to use the help file system to read any file by doing something like:
> help ../players/Kiasyn.yml
To fix this, change help.rb to look like this (note usages of File.basename):
# # RocketMUD was written by Jon Lambert, 2006. # It is based on SocketMUD™ written by Brian Graversen. # This code is released to the public domain. # # # This file contains the dynamic help system. # If you wish to update a help file, simply edit # the entry in ../help/ and the mud will load the # new version next time someone tries to access # that help file. #
# # Check_help() # # This function first sees if there is a valid # help file in the help_list, should there be # no helpfile in the help_list, it will check # the ../help/ directory for a suitable helpfile # entry. Even if it finds the helpfile in the # help_list, it will still check the ../help/ # directory, and should the file be newer than # the currently loaded helpfile, it will reload # the helpfile. def check_help dMob, helpfile pHelp = nil entry = nil hFile = helpfile.upcase
$help_list.each do |p| if is_prefix hFile, p.keyword pHelp = p break end end
# If there is an updated version we load it if pHelp if last_modified(sprintf("help/%s", File.basename(hFile))) > pHelp.load_time pHelp.text = read_help_entry "help/#{File.basename(hFile)}" end else # is there a version at all ?? entry = read_help_entry "help/#{File.basename(hFile)}" if entry == nil return false else pHelp = Help.new hFile, entry $help_list << pHelp end end
# # Loads all the helpfiles found in ../help/ # def load_helps log_string "Load_helps: getting all help files."
Dir.entries("help").each do |entry| next if File.stat("help/#{File.basename(entry)}").directory? s = read_help_entry "help/#{File.basename(entry)}"
if s.nil? bug "load_helps: Helpfile %s does not exist.", entry next end
new_help = Help.new entry, s $help_list << new_help
if "GREETING".casecmp(new_help.keyword) == 0 $greeting = new_help.text elsif "MOTD".casecmp(new_help.keyword) == 0 $motd = new_help.text end end end
if __FILE__ == $0 load_helps puts $motd puts $greeting pp $help_list end
14 Nov, 2009, David Haley wrote in the 2nd comment:
Votes: 0
Hmm, classic case of giving user input straight to the file system. Unfortunately it's easy to forget to write safe code in this context. (My quest management system at one point let you access any global variable in the Lua scripting space if you entered the right argument to a command. Oops :redface:) I wonder if this kind of problem can also be more generally managed by having a resource manager of sorts that ties resource name to file system location. Then, you associate the "help file" resource manager, and people query for files by logical name, not by file name. This gives you a protection layer in between the user input and the actual filesystem.
Using basename works too in this instance, but there are probably cases where one would like to have directories in the file names; in those cases, basename would not be sufficient.
To fix this, change help.rb to look like this (note usages of File.basename):