14 Nov, 2009, kiasyn wrote in the 1st comment:
Votes: 0
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

# 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)}"
else # is there a version at all ??
entry = read_help_entry "help/#{File.basename(hFile)}"
if entry == nil
return false
pHelp = Help.new hFile, entry
$help_list << pHelp

dMob.text_to_mobile sprintf("=== %s ===\r\n%s", pHelp.keyword, pHelp.text)

return true

# 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

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

if __FILE__ == $0
puts $motd
puts $greeting
pp $help_list
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.
14 Nov, 2009, Tyche wrote in the 3rd comment:
Votes: 0
Patch applied.
14 Nov, 2009, kiasyn wrote in the 4th comment:
Votes: 0
Tyche said:
Patch applied.

great :)