出于安全目的,在 bash 中清理用户输入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4273074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sanitize user input in bash for security purposes
提问by johnf
How do I sanitise user input in a bash script so that I can then pass it as an argument to another shell program? I want to prevent the following:
如何清理 bash 脚本中的用户输入,以便我可以将其作为参数传递给另一个 shell 程序?我想防止以下情况:
INPUT="filename;rm -rf /"
ls $INPUT
I was thinking it should be enough to surround the user input in double quotes like so:
我认为将用户输入用双引号括起来就足够了,如下所示:
ls "$INPUT"
but what if there is a double quote in $INPUT?
但是如果 中有双引号$INPUT怎么办?
Or does bash already deal with this problem?
还是 bash 已经解决了这个问题?
回答by John Kugelman
The Short
短篇
Bash already deals with that. Quoting it is sufficient.
Bash 已经解决了这个问题。引用它就足够了。
ls "$INPUT"
The Long
长的
A rough guide to how the shell parses this line is:
shell 如何解析这一行的粗略指南是:
"ls \"$INPUT\"" # Raw command line.
["ls", "\"$INPUT\""] # Break into words.
["ls", "\"filename; rm -rf /\""] # Perform variable expansion.
["ls", "\"filename; rm -rf /\""] # Perform word splitting (no change).
["ls", "filename; rm -rf /"] # Remove quotes.
Because of the quotes the $INPUTvariable does not undergo word splitting. The lswill look for a file named filename; rm -rf /.
由于引号,$INPUT变量不会进行分词。该ls会寻找一个名为文件filename; rm -rf /。
If you didn't quote it then the expansion would proceed differently:
如果您没有引用它,那么扩展的进行方式会有所不同:
"ls $INPUT" # Raw command line.
["ls", "$INPUT"] # Break into words.
["ls", "filename; rm -rf /"] # Perform variable expansion.
["ls", "filename;", "rm", "-rf", "/"] # Perform word splitting.
You can at least have consolation that this won't actually execute rm -rf /. Rather, it'll pass each of those strings as a file name to ls. You'll lssome files you didn't intend but at least it won't accidentally execute unwanted commands.
您至少可以感到安慰的是,这实际上不会执行rm -rf /。相反,它会将这些字符串中的每一个作为文件名传递给ls. 你会得到ls一些你不想要的文件,但至少它不会意外地执行不需要的命令。
jkugelman$ VAR='.; echo hi'
jkugelman$ ls $VAR
ls: .;: No such file or directory
ls: echo: No such file or directory
ls: hi: No such file or directory
Excerpts from "man bash":
摘自“man bash”:
QUOTING
Quoting is used to remove the special meaning of certain characters or words to the shell. Quoting can be used to disable special treatment for special characters, to prevent reserved words from being recognized as such, and to prevent parameter expansion.
EXPANSION
Expansion is performed on the command line after it has been split into words. There are seven kinds of expansion performed: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion.
Only brace expansion, word splitting, and pathname expansion can change the number of words of the expansion; other expansions expand a single word to a single word. The only exceptions to this are the expansions of
"$@"and"${name[@]}"as explained above (see PARAMETERS).Word Splitting
The shell scans the results of parameter expansion, command substitution, and arithmetic expansion that did not occur within double quotes for word splitting.
Quote Removal
After the preceding expansions, all unquoted occurrences of the characters
\,', and"that did not result from one of the above expansions are removed.
引用
引用用于删除某些字符或单词对 shell 的特殊含义。引用可用于禁用对特殊字符的特殊处理,防止保留字被识别为此类,并防止参数扩展。
扩张
拆分成单词后在命令行上进行扩展。执行的扩展有七种:大括号扩展、波浪号扩展、参数和变量扩展、命令替换、算术扩展、分词和路径名扩展。
只有花括号展开、分词、路径名展开才能改变展开的字数;其他扩展将单个单词扩展为单个单词。唯一的例外是的膨胀
"$@"和"${name[@]}"上面所解释的(见参数)。分词
shell 扫描没有出现在双引号内的参数扩展、命令替换和算术扩展的结果以进行分词。
报价删除
在前面的扩展之后,所有未加引号的字符
\,'和"不是由上述扩展之一产生的都将被删除。

