mirror of
https://github.com/koalaman/shellcheck.git
synced 2025-10-03 11:19:45 +08:00
Created SC2089 (markdown)
44
SC2089.md
Normal file
44
SC2089.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Quotes/backslashes will be treated literally. Use an array.
|
||||
|
||||
### Problematic code:
|
||||
|
||||
args="-lh "My File.txt"'
|
||||
ls $args
|
||||
|
||||
### Correct code:
|
||||
|
||||
args=(-lh "My File.txt")
|
||||
ls "${args[@]}"
|
||||
|
||||
### Rationale:
|
||||
|
||||
Bash does not interpret data as code. Consider almost any other languages, such as Python:
|
||||
|
||||
print 1+1 # prints 2
|
||||
a="1+1"
|
||||
print a # prints 1+1, not 2
|
||||
|
||||
Here, `1+1` is Python syntax for adding numbers. However, passing a literal string containing this expression does not cause Python to interpret it, see the `+` and produce the calculated result.
|
||||
|
||||
Similarly, `"My File.txt"` is Bash syntax for a single word with a space in it. However, passing a literal string containing this expression does not cause Bash to interpret it, see the quotes and produce the tokenized result.
|
||||
|
||||
The solution is to use an array instead, whenever possible.
|
||||
|
||||
If you due to `sh` compatibility can't use arrays, you can use `eval` instead. However, this is very insecure and easy to get wrong, leading to various forms of security vulnerabilities and breakage:
|
||||
|
||||
quote() { local q=${1//\'/\'\\\'\'}; echo "'$q'"; }
|
||||
args="-lh $(quote "My File.txt")"
|
||||
eval ls "$args" # Do not use unless you understand implications
|
||||
|
||||
If you ever accidentally forget to use proper quotes, such as with:
|
||||
|
||||
for f in *.txt; do
|
||||
args="-lh '$1'" # Example security exploit
|
||||
eval ls "$args" # Do not copy and use
|
||||
done
|
||||
|
||||
Then you can use `touch "'; rm -rf \$'\x2F'; '.txt"` (or someone can trick you into downloading a file with this name, or create a zip file or git repo containing it, or changing their nick and have your chat client create the file for a chat log, or...), and running the script to list your files will run the command `rm -rf /`.
|
||||
|
||||
### Contraindications
|
||||
|
||||
Few and far between.
|
Reference in New Issue
Block a user