关于bash quote的认识
问题的背景:参数注入
在shell中,我们希望将参数传递给子命令,如下面的例子:
假设我们有一个http服务,它接受一个cmd
参数,并将其传递给bash -c
执行:
// curl 'localhost:8080/demo?cmd=echo hello'
handler(req,res){const cmd = req.query.cmd;const process = child_process.exec(`bash -c "${cmd}"`);// ...
}
显然,因为cmd
将被拼接在字符串中,所以上面的处理方式有很明显的问题:如果cmd
中含有双引号,或者其他特殊字符,甚至cmd=':";rm -rf /
, 那么执行的命令就变成了bash -c ":";rm -rf /
,是极其危险的。
其实,这在编程领域是非常常见的注入问题,和SQL注入是同样的道理:参数将被拼接到命令中执行,因此不能信任参数。
解决方法
解决方法就是对要拼接的参数进行转义,防止其中的任何特殊字符造成期望之外的结果。
比如,bash -c "${cmd}"
的含义是: cmd
将作为一个完整的字符串被双引号包围。所以,需要对cmd
进行转义:
function quoteShell(cmd){return cmd.replaceAll("\\", "\\\\").replaceAll("$", "\\$").replaceAll("`", "\\`").replaceAll("\"", "\\\"").replaceAll("\n", "\\n")
}
上面的例子一种常见的情况,即参数只会被命令行解析一次,因此需要保证命令行解析的结果就是原始的参数字符串。所以,本质上quote
函数可以视为bash
解析参数的逆过程。
还有另外一种情况,参数通过printf
进行传递:
printf "${cmd}" | bash
在这种情况下,参数不仅要被bash
解析,还要被printf
解析,如何保证经过这两个解析过程之后,得到原始的参数字符串?
我们分析解析的过程:首先是bash解析,然后printf解析bash解析的参数,即实际参数 -> bash -> printf -> 原始参数
,所以,我们将这条链反转过来就是如何从原始参数到实际参数的过程: 原始参数->printf->bash->实际参数
。因此,我们需要定义quotePrintf
:
function quotePrintf(cmd){cmd = cmd.replaceAll("\\","\\\\").replaceAll("%","%%")return quoteShell(cmd)
}
- 先将printf中的特殊字符\和%转义
- 再将转义后的字符串进行
quoteShell
注意:对printf来说,"
不是特殊字符,那只是bash的特殊字符。
例子:
quoteShell:'\n' -> '\\n'$A -> "\$A""\n -> \"\\n"quotePrintf:'\n' -> '\\\\n'$A -> \$A"\n -> \"\\\\n%s -> %%s
关于bash quote的认识相关推荐
- linux命令帮助 man bash
BASH(1) BASH(1)NAMEbash - GNU Bourne-Again SHell (GNU 命令解释程序 "Bourne二世")概述(SYNOPSIS)bash [ ...
- shell变量加单引号sql_关于shell:在Bash中的命令中扩展变量的单引号
我想从bash shell脚本中运行一个命令,该脚本在单引号和变量中包含单引号和一些其他命令. 如repo forall -c '....$variable'. 在这种格式中,对$进行转义,不展开变量 ...
- Bash For Loop Examples for Your Linux Shell Scripting--ref
There are two types of bash for loops available. One using the "in" keyword with list of v ...
- Bash 中的特殊字符大全
Linux下无论如何都是要用到shell命令的,在Shell的实际使用中,有编程经验的很容易上手,但稍微有难度的是shell里面的那些个符号,各种特殊的符号在我们编写Shell脚本的时候如果能够用的好 ...
- Bash+R: howto pass parameters from bash script to R(转)
From original post @ http://analyticsblog.mecglobal.it/analytics-tools/bashr/ In the world of data a ...
- gitlab bash_如何编写Bash一线式以克隆和管理GitHub和GitLab存储库
gitlab bash Few things are more satisfying to me than one elegant line of Bash that automates hours ...
- Bash字符串处理(与Java对照) - 18.格式化字符串
From: http://codingstandards.iteye.com/blog/1198098 In Java class Formatter 参见:http://download.oracl ...
- Bash中单引号和双引号之间的区别
本文翻译自:Difference between single and double quotes in Bash 在bash,什么是单引号(之间的差异'' )和双引号( "" ) ...
- 认识 BASH Shell
认识 BASH Shell 切换解析度为 800x600 最近更新日期:2005/08/30 文字模式 (command line) 这种指令下达的方式,在 Linux 里面,其实就相当于是 bash ...
最新文章
- 动态规划算法-01爬楼梯问题
- js优化工具:ECMAScript Cruncher
- 利用wojilu框架仿一个网站的全过程(Step by Step利用wojilu框架开发网站系列二 附源码)...
- Linux shell 脚本入门教程+实例
- error code ELIFECYCLE
- 阿里P8架构师分享:如何从0到1设计一个类Dubbo的RPC框架
- 第十章第二节 阿基米德原理
- 强网杯2019线上赛-misc
- java项目 分模块管理_java 工程项目模块划分及各模块功能梳理
- WPS Linux 2019领先的背后
- 20210525电力通信网
- 腾讯不缺少梦想,但是缺算法与数据管理
- Netlogo仿真初步学习总结
- 单身职场人士怎么利用晚上时间提高自己?
- 记一次触发器定义者不同导致的sql异常TRIGGER command denied to user 'XXX' @'%' for table '...
- 学UI设计需要会手绘吗
- 同是数据分析产品, 为什么200万App企业都选择友盟+
- 51nod-2534 最小旅行路线
- 【Linux开发环境搭建】之Nginx安装
- Xilinx FPGA 配置之ICAP
热门文章
- linux cs go鼠标灵敏度,CSGO鼠标调试方法 选择适合自己的鼠标速度
- 记一次打包源码的过程
- 说说Android桌面(Launcher应用)背后的故事(八)——让桌面的精灵穿越起来
- 【附源码】计算机毕业设计SSM社区居家养老服务管理系统
- python keys模块_python自动化常用模块
- datadashboard下载_Data Dashboard for LabVIEW
- Android闪动的文字效果
- 解决Chrome浏览器想要弹出警告框时会卡死的问题
- apachebench_使用ApacheBench对PHP应用进行压力测试
- MAC系统安装Wireshark网络抓包工具