Joining user input to a base directory is not enough, because the joined path is cleaned and can climb out. Check the result against the base, or better use os.OpenRoot, which also stops symlinks that point outside.