shell语言编程规范安全篇是针对bash语言编程中的数据校验、加密与解密、脚本执行、目录&文件操作等方面,描述可能导致安全漏洞或风险的常见编码错误。该规范基于业界最佳实践,并总结了公司内部的编程实践。该规范旨在减少SQL注入、敏感信息泄露、环境变量攻击、临时文件攻击、社会工程学等方面的安全问题发生。

使用对象

本规范的读者及使用对象主要为使用bash脚本的研发人员和测试人员等

适用范围

该规范适用于基于bash脚本的产品开发

术语定义

规则:编程时必须遵守的约定

建议:编程时加以考虑的约定

说明:某个规则的具体解释

错误示例:对此规则/建议从反面给出例子

推荐做法:对此规则/建议从正面给出例子或建议

例外情况:相应规则不使用的场景

信任边界:位于信任边界之内的所有组件都是被系统本身直接控制的,所有来自不受控的外部系统的连接与数据,包括客户端与第三方系统,都应该被认为是不可信的,要先在边界处对其校验,才能允许进一步与本系统交互。

非信任代码:非产品包中的代码,如通过网络下载到本地虚拟机中加载并执行的代码。


通用原则

规则1:校验跨信任边界传递的不可信数据

说明:软件最为普遍的缺陷就是没有对来自外部环境(系统/程序信任域之外)的数据进行合法性校验,校验缺失可导致系统的各种缺陷,比如DOS、SQL注入等,所以对于来自外部环境的输入,默认为不可信,需要执行合法性校验,校验必须在信任边界以内进行(比如对于web应用,需要服务端做校验)。不可信数据可能来自(包括但不局限与):用户输入、外部接口输入、配置文件、网络数据、环境变量。

数据校验可以参考如下几种策略(包括但不限于):

1).接受已知好的数据:该策略被称为白名单或者正向校验,重点检查数据是否属于一个可接受的数据集合。如下代码用于确保name参数只包含字母、数字以及下划线且必须以字母开头:

check

2).拒绝已知坏的数据:该策略被称为黑名单或者负向校验,相对于正向校验,是一种较弱的校验方式,这种策略存在缺陷,因为潜在的坏数据可能是一个无限集合,采用这种策略意味着必须维护一个系统不可接受的列表(如字符或模式),否则列表中的信息会很快过时,系统安全性会降低。

3).白名单方式净化:删除、编码或者替换系统不能接受的字符/数据,就是系统只接受某个确定的数据列表,比如期望接收一个电话号码,则可以剔除输入数据中所有非数字字符。

4).黑名单方式净化:为确保输入数据安全,剔除某些字符或转换某些字符,跟黑名单校验类似,该策略需要持续维护,且黑名单通常也不全面,因为大部分输入域有其特殊的业务或格式要求,对比对应于当前和未来所有攻击方式而使用的一个复杂、迟钝的校验程序,针对正确输入的正向校验显得更为简单、高效。

错误示例1:环境变量容易被篡改,如果脚本中使用系统环境变量,建议优先使用系统命令取值,如下代码中,直接使用环境变量USER判断当前用户是否为root用户,如果该环境变量USER被人篡改,会得到非预期的结果。

check

推荐做法:使用id -un命令可以准确安全地判断当前用户,如下:

check


规则2 禁止直接使用不可信数据来拼接SQL语句

说明:SQL注入是指原始SQL操作被动态更改成一个与程序预期完全不同的操作,执行更改后SQL可能导致信息泄露或者数据被篡改。防止SQL注入主要需对不可信数据进行校验,推荐对不可信数据做如下校验以防SQL注入:

对于字符型字段,需要对数据做转义

1).将单引号替换为两个单引号

2).如果字符类型输入数据作为SQL语句中like部分,需要参考后面的附录A做转义。

3).系统根据具体业务场景,确定需要校验的特殊字符,特殊字符可以参考附录A和附录B

对于整型字段,需要对输入数据进行类型校验,拒绝传入不合法数字。

错误示例1:该例子中直接使用输入数据拼接SQL语句,没有对输入数据做校验,存在SQL注入风险。当username输入值为tom'OR '1' = '1'的时候,SQL语句变成了"SELECT * FROM db_user WHERE username = 'tom OR '1' = '1' AND password = '${pvalue}'" ,这样就绕开了对口令的验证。

get

推荐做法:

get


规则3 禁止在界面或日志中输出敏感信息

说明:敏感数据的范围应该基于系统场景以及威胁分析的结果来确定,典型的铭感数据包括口令、银行账号、个人信息、通讯记录、秘钥等,如果shell脚本中往界面或日志中输出敏感信息,都可能会有助于攻击者尝试发起进一步的攻击,因此shell脚本中禁止往界面或日志中输出敏感信息,避免被攻击者所获取并利用。敏感信息举例(包括但不限于):

1).口令与秘钥:口令包括口令明文和口令密文。

2).环境变量:命令set、env、declear、export以及typeset会把操作系统的环境变量显示出来,其中可能会存在关键信息。

3).产品相关信息:产品License、日志中如password、passwd等关键字信息。

对敏感信息建议采取以下措施:

1).不输出到界面或日志中

2).若特殊原因必须要输出到界面或日志,则使用*号代替,并且不显示敏感信息的长度。

错误示例1:该例子中,功能实现时为方便定位问题,在日志和界面上输出了详细信息,其中包括了数据库密码,存在被利用的风险。

db

推荐做法:不将敏感信息输出到界面以及日志中,避免被利用。

db

错误示例2:如下示例中,如果环境变量plvaule为关键信息,如下

env

而脚本如下,会将环境变量输出至日志及界面,存在信息泄露风险。

env

推荐做法:禁止在shell脚本中把set、env、declare、export及typeset命令的回显打印到日志及界面上。

例外情况:可以将命令执行结果赋值给一个变量,但需要保证该变量不输出到日志和界面,如下所示:

env


规则4 禁止在shell脚本中保留敏感信息

说明:敏感数据的范围应该基于应用场景以及产品威胁分析的结果来确定,shell脚本在产品发布版本中以文本方式存在,如果脚本中包含敏感信息,可能会被恶意利用造成安全隐患,比如脚本中注释中包含员工的个人信息,虽然不违反安全红线,但是带有员工个人信息的注释可能会泄露具体的开发人员信息,从而引入社会工程学方面的风险,因此要从脚本注释中删除员工个人信息。

脚本中敏感信息包括(但不限于):

1).用户名、密钥、密码明文和密文:如果脚本中存在这类信息,一旦泄露,与其相关的数据的机密性将受到严重的影响,因此不能在脚本中体现出来。

2).公司内部信息:如代码作者的工号、姓名、联系方式等

错误示例1:如下代码中,硬编码了默认的用户名和密码,在执行时会导致用户名和密码这类敏感信息很容易泄露出来。

input

推荐做法:shell脚本里面禁止硬编码密码等敏感信息,需要密码时通过手工输入,如下:

input

例外情况:在系统初始化安装的shell脚本中可以使用默认的用户名和密码密文,但是需要在调测及管理员操作指南中提醒用户及时修改缺省密码。

错误示例2:该例子中,发布版本中的shell脚本中包含了公司内部信息,可能导致社会工程学方面的风险。

info

推荐做法:把脚本中的开发人员个人信息清除掉。


规则5 禁止在PATH环境变量中使用相对路径

说明:环境变量攻击是用来操控脚本行为的最常见的方式,通过修改环境变量攻击者可以改变一个依赖环境变量值的脚本的执行过程或执行结果。其中最常被修改的环境变量是PATH,该变量值的路径集决定了用户在执行不包含完整路径的单独命令时,查找该命令的路径及路径查找先后顺序。

假设PATH变量的内容是:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin,

正常情况下命令会顺序在/usr/local/sbin、/usr/local/bin、/usr/sbin、/usr/bin中查找并执行,如果PATH环境变量内容设置不当,存在如"."这样的相对路径,攻击者可以在当前目录下创建与系统命令同名的恶意程序或者脚本,当用户执行该命令是,就会触发执行恶意程序,导致恶意攻击。

防护措施:PATH环境变量中必须使用绝对路径,或者直接使用绝对路径命令进行操作。


  • May you share freely, never taking more than you give.

  • 愿你宽心与人分享,所取不多于你所施与。

转自

https://www.toutiao.com/i6498345706607084046/

linux shell语言编程规范安全篇之通用原则【转】的更多相关文章

  1. 华为C语言编程规范

    DKBA华为技术有限公司内部技术规范DKBA 2826-2011.5C语言编程规范2011年5月9日发布 2011年5月9日实施华为技术有限公司Huawei Technologies Co., Ltd ...

  2. Linux shell脚本编程(一)

    Linux shell脚本编程: 守护进程,服务进程:启动?开机时自动启动: 交互式进程:shell应用程序 广义:GUI,CLI GUI: CLI: 词法分析:命令,选项,参数 内建命令: 外部命令 ...

  3. Linux C语言编程基本原理与实践

    Linux C语言编程基本原理与实践(2018-06-16 19:12:15) Linux C语言编程基本原理与实践 高效的学习带着目的性: 是什么 -> 干什么 -> 怎么用 重识C语言 ...

  4. Uber Go 语言编程规范

    目录 Uber Go 语言编程规范 1. 介绍 2. 编程指南 3. 性能相关 4. 编程风格 5. 编程模式(Patterns) 6. 总结 Uber Go 语言编程规范 相信很多人前两天都看到 U ...

  5. Linux shell脚本编程(三)

    Linux shell脚本编程 流程控制: 循环语句:for,while,until while循环: while CONDITION; do 循环体 done 进入条件:当CONDITION为“真” ...

  6. Linux shell脚本编程(二)

    Linux shell脚本编程(二) 练习:求100以内所有偶数之和; 使用至少三种方法实现; 示例1: #!/bin/bash # declare -i sum=0 #声明一个变量求和,初始值为0 ...

  7. Linux Shell脚本编程--Linux特殊符号大全

    Linux Shell脚本编程--Linux特殊符号大全 linux_shell 特殊符号的介绍 2011

  8. C语言编程规范

    C语言编程规范 6 函数与过程 6.1 函数的功能与规模设计 函数应当短而精美,而且只做一件事.不要设计多用途面面俱到的函数,多功能集于一身的函数,很可能使函数的理解.测试.维护等变得困难. 6.2 ...

  9. C语言编程规范试题(标准答案)

    C语言编程规范试题(标准答案) 一.单选题(每小题3分,共20小题60分) 1.1-1.5    B D A C B                1.6-1.10    C A D B C 1.11 ...

随机推荐

  1. Java参数引用传递之例外:null

    今天写链表的时候写了一个函数,实参是一个空链表,应该是按引用传参,但是在函数内修改了链表,外部的链表没有变化. 原来是null作为参数传递的时候,就不是引用传参了. 引自:http://blog.cs ...

  2. 【比赛】NOIP2017 总结

    一.比赛过程 Day1: 拿到题目后,立即把所有题目都看了一遍,发现没有很虚的期望DP和概率DP,感到很庆幸.然后发现今年的题目顺序好像有点不对,T1是数论,T2像是模拟,这难道是把两天的基础题放到一 ...

  3. 【HDU4336】Card Collector(Min-Max容斥)

    [HDU4336]Card Collector(Min-Max容斥) 题面 Vjudge 题解 原来似乎写过一种状压的做法,然后空间复杂度很不优秀. 今天来补一种神奇的方法. 给定集合\(S\),设\ ...

  4. 【51Nod1847】奇怪的数学题

    ​ 记\(f(x)=\)\(x\)的次大因数,那么\(sgcd(i,j)=f(gcd(i,j))\). 下面来推式子: \[ \begin{aligned} \sum_{i=1}^n\sum_{j=1 ...

  5. android studio 怎么做屏幕适配?

    一.关于布局适配建议1.不要使用绝对布局2.尽量使用match_parent 而不是fill_parent .3.能够使用权重的地方尽量使用权重(android:layout_weight)4.如果是 ...

  6. D. Monitor Educational Codeforces Round 28

    http://codeforces.com/contest/846/problem/D 二分答案 适合于: 判断在t时候第一次成立 哪个状态是最小代价 #include <cstdio> ...

  7. Java 从业一年的心得体会

    在你打开此文时,你或许在犹豫这个职业,但是我觉得干就好了,没有适合不适合,趁年轻折腾吧! 以下是我一年来从事Java的经验积累,知识有很多,经验就九条 1.设计的数据库表尽量添加一个状态位,可以在删除 ...

  8. linux命令总结之route命令

    route命令用于显示和操作IP路由表.要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或者同时位于两个网络的网关来实现.在Linux系统中,设置路由通常是 为了解决以下问题:该Linu ...

  9. Python【异常处理】

    def f(): first = input('请输入除数:') second = input('请输入被除数:') try: first = int(first) second = int(seco ...

  10. P2657 [SCOI2009]windy数

    P2657 [SCOI2009]windy数 题目描述 windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之间,包括A和B ...