root area/directories/files
Typically there are no files in the root area. If there are this file is called a ‘tarbomb’. The problem with a tarbomb is that during extraction the files in the root area burst into your current directory and cause a mess. It can be tough to tell which files in your current directory were there before extraction and which are there courtesy of the tarbomb. This is a real pain and usually requires tedious removing or moving of each invidivual file.
Not fun!
Needless to say I’m not a big fan of tarbombs. I lost a good amount of sleep but I finally finished writing a script that robustly prevents any harm from tarbombs.
I’m happy now. :)
Here are some cool points of the script:
- Completely protects against tarbombs! :D
- It has 3 options which it can receive in any order before or after the tar file name and specific extract path.
- Allows the specific extract path to come after the tar file name if the tar file name contains “.tar”
- It has robust error messaging.
- It has a nice help menu.
- Has a lot of good comments and easy program structure for anyone looking to follow the code.
To demonstrate this script let’s look at the bad ‘tarbomb.tar’. Peering into it’s structure we can see this is an insidious tarbomb.
readme.txt <--- residing in the tar root space!
/super/readme.txt
/super/cool/man.txt
Normally if you try to extract this tar file the script will warn you the file is a tarbomb and exit. But for this example let’s force the extraction into the path “iam/” by using this code:
| ~/test> ./utar.sh tarbomb.tar iam/ --force Warning! A tarbomb was detected! Forcing the extraction... Found a duplicate file: 'readme.txt': renaming it to 'readme.txt-1' ~/test> |
What happens when this script is run is:
- Determines tarbomb.tar is in fact a tarbomb but because of option “–force” it will continue the extraction.
- Create the “iam/” directory if needed and extract all the files not in the root space into the “iam/” directory.
- Lastly it will move the files in the root space into “iam/”
The folder structure will look like this:
../iam/readme.txt-1
../iam/readme.txt
../iam/cool/man.txt
You might notice the file originally in the tar root space now has a “-1″ appended to it’s file name. The issue here is that the tarbomb had a file in it’s root area and a file in it’s first directory with the same name. So when files in the root area are placed into the main directory a number has to be appended to it’s file name to ensure no files are overwritten.
I hope someone can get some use out of this script. I removed the “.sh” and put it into my /usr/bin directory so I definitely use it. The code should easily copy and paste but I’ve only tested it in Firefox.
Use it. Rip it up. Learn from it. Play with it. :)
I’d like to hear some feedback!
If you want to study the source code or use this script I suggest downloading it. Different browsers have a tendency to mess up the formatting of the code.
Click to directly download utar.sh
|
#!/bin/bash # file name 'utar.sh' # coded by: Louis Casillas, e-mail: oxaric@gmail.com # version 1.1 # How to use: # This script will protect against tarbombs and allow you TRUE=0 OFF=0 NO=0 SUCCEEDED=0 file_name="" num_of_dirs_passed=0 # the initial temporary directory name function display_help_and_exit exit $SUCCEEDED # receives the exit code of the last system command called exit $FAILED function did_the_system_command_work delete_the_temp_directory function has_ending_forward_slash function contains_a_forward_slash # determines if the string is a proper option function evaluate_parameter "--help") "--keep-root-dir") exit $FAILED # determine if the passed parameter is a directory path optional_extraction_path="$1" file_name="$1" optional_extraction_path="$1""/" # too many files or dirs passed exit $FAILED # sorts out the 6 parameters passed and makes sure they are proper exit $FAILED if [[ "$2" != "" ]]; then if [[ "$3" != "" ]]; then if [[ "$4" != "" ]]; then if [[ "$5" != "" ]]; then # test if there are more options than is possible echo "utar: invalid command: $6" exit $FAILED if [ $help_option -eq $ON ]; then ### function create_the_temp_directory # grab a random number between 0 and 9 temp_dir+="$temp_num" temp_dir+="/" # make the temporary directory did_the_system_command_work $? function delete_the_temp_directory # $? gives us the return result of the system command function remove_dirs_from_the_temp_directory # test if there any directories in the temp directory # if there are directories in the mpt directory then # output list of dirs to file temp.txt exec<"$temp_dir""temp.txt" # delete all directories inside the temp directory # this does not exactly need to be removed at this point because function test_for_being_a_tar_bomb remove_dirs_from_the_temp_directory temp="$(ls $temp_dir)" # test for any leftover files in the temp directory echo "Warning! A tarbomb was detected!" is_a_tar_bomb=$YES # remove all leftover files in the temp directory if [ $force_option -eq $ON ]; then exit $FAILED # check if the tar file exists exit $FAILED function create_specified_extract_path_if_needed # if the specified extract path does not exist then create it mkdir -p "$optional_extraction_path" function try_normal_extraction tar -xf "$file_name" exit $SUCCEEDED function try_maintaining_the_root_directory_extraction tar -xf "$file_name" -C "$optional_extraction_path" exit $SUCCEEDED function extract_the_tar_bomb # now take care of any files from a tarbomb # grab a list of the files and directories in the temp directory # output list of left over files to file temp.txt echo "$ls_results" > "$temp_dir""temp.txt" exec<"$temp_dir""temp.txt" # go through the list of leftover files and # test to see if the file exists while [ -f "$optional_extraction_path""$line""-""$i" ] echo "Found a duplicate file: ""'$line':"" renaming it to ""'$line""-""$i'" # move the files back to the specified directory # move the files back to the specified directory delete_the_temp_directory exit $SUCCEEDED function extract_to_the_specified_path delete_the_temp_directory exit $SUCCEEDED ### HERE STARTS THE CODE EXECUTION # makes sure the specified tar file exists # tests the tar for being a tarbomb # runs and exits if no specified extract path was given # if the extract path does not exist then create it # runs and exits if a specified extract path was given if [ $is_a_tar_bomb -eq $YES ]; then # runs and exits after extracting the tarbomb to the path given # runs and exits after extracting to the path given |