Semgrep结合GitLab实现代码审计实践-服务端

简介: 为了能让开发者时时刻刻关注安全问题,我在gitlab服务端放了一个钩子,这个钩子主要是将本次提交的代码文件进行了检测,遇到可能存在安全风险的问题将其输出出来,这样开发者能够对培训的内容有更深的感受,更注重编码时候的安全问题。

一、背景


前段时间在做代码审计,发现很多项目都存在安全隐患,大多数是来自于参数未过滤所造成的;为了解决这个问题,我将Web安全开发规范手册V1.0进行了培训,但是效果并不是太理想,原因是培训后开发者的关注点主要在功能完成度上,安全编码对于他们来说并不是核心指标;


为了能让开发者时时刻刻关注安全问题,我在gitlab服务端放了一个钩子,这个钩子主要是将本次提交的代码文件进行了检测,遇到可能存在安全风险的问题将其输出出来,这样开发者能够对培训的内容有更深的感受,更注重编码时候的安全问题。


二、操作步骤


  1. 搭建环境
  2. 创建项目
  3. 创建钩子
  4. 钩子实验


三、搭建环境


3.1 安装gitlab


在正式部署到服务器之前,我需要在本地搭建一个gitlab服务,用于钩子的开发和测试,这里我用docker搭建速度比较快,执行的命令如下


docker run --detach  --publish 443:443 --publish 80:80  --name gitlab --restart always  gitlab/gitlab-ce


命令执行之后,返回的信息如下所示


1.png


在上图中可以看到容器已经运行成功,使用浏览器访问gitlab的地址


http://127.0.0.1


访问之后需要设置一个管理员的密码,如下图所示


2.png


填写密码之后,确认修改密码,会跳转到gitlab的主页,如下图所示


3.png


这gitlab中创建一个项目用于钩子测试,如下图所示


4.png


创建项目成功之后,注意留意页面中的Project ID:2,把这个2记录一下,后续会使用到;接下来需要开始钩子的开发和部署,钩子可以使用各种语言开发,这里我比较熟悉php,因此采用php开发。


3.2 安装依赖


gitlab的容器默认不支持php语言,需要先安装php,安装命令如下所示


apt update -y && apt install php -y


命令执行之后,返回的信息如下所示


5.png


在上图中可以看到php已经安装成功,为了验证php命令是否可以运行,这里我使用如下命令进行验证


php -v


命令执行之后,返回的信息如下所示


6.png


在上图中可以看到php的版本是7.4.3 ,说明php已经安装成功。


3.3 安装semgrep


钩子程序中需要调用semgrep,这个程序gitlab中也没有安装,需要安装一下,这里采用pip安装,不过需要先升级pip的版本才行,升级的命令如下所示


pip3 install --upgrade pip


命令执行之后,返回的信息如下所示


7.png


在上图中可以看到pip的版本已经升级到21.1.2,说明升级成功了


semgrep还依赖setuptools模块,需要用pip先升级一下,升级的命令如下所示


pip3 install --upgrade setuptools


命令执行之后,返回的信息如下所示


8.png


在上图中可以看到setuptools模块已经升级成功


接下来就可以正式安装semgrep了,安装的命令如下所示


cd /usr/local/bin/ && python3 -m pip install semgrep


命令执行之后,返回的信息如下所示


9.png


在上图中可以看到semgrep已经安装完成,这里我需要再次使用semgrep命令来验证一下,执行的命令如下所示


semgrep --version


命令执行之后,返回的信息如下所示


10.png


在上图中可以看到semgrep的版本信息为0.52.0,确认安装成功了。


3.4 查看hash


现在我们需要在刚才创建的项目中添加钩子,这里需要找到项目的存放路径,在项目页中


echo -n 2 | sha256sum


命令执行之后,返回的信息如下所示


11.png


find / -iname d4


命令执行之后,返回的信息如下所示


12.png


在上图中可以看到项目存放的位置,返回了两个路径,这两个路径其中有一个是软连接,通过cd命令进入进入项目的存放位置


cd /var/opt/gitlab/git-data/repositories/@hashed/d4


命令执行之后,再次执行ls命令,得到的信息如下所示


13.png


在上图中可以看到有一个73的文件夹,这是gitlab的命名规则,进入此文件夹,命令如下所示


cd 73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git/


命令执行之后,返回的信息如下所示


14.png


在上图中可以看到此项目的所有文件,我需要在这个位置开发钩子文件


五、创建钩子


自定义钩子需要存放在custom_hooks目录下,默认没有此文件夹所以需要创建此文件夹,执行命令如下所示


mkdir custom_hooks  && cd custom_hooks


5.1 新建钩子


创建custom_hooks文件夹并进入之后,使用vim创建一个钩子文件,命令如下所示


vim  pre-receive


进入vim编辑器界面之后,将如下钩子代码添加进去,代码如下所示


#!/usr/bin/php
<?php
fwrite(STDOUT, 'please input:');
list($oldVer, $newVer, $ref_name) = explode(" ", fgets(STDIN));
//ob_start();
$cmd = "git diff --name-only  {$oldVer}..{$newVer}";
echo $cmd . PHP_EOL;
exec($cmd, $result);
$rand = date("Y-m-d-H-i-s");
$baseDir = "/tmp/11/$rand/";
$ruleFile = "/semgrep-rule.yaml";
foreach ($result as $value) {
    if (strstr($value, ".php") !== false) {
        $randName = $baseDir . $value;
        if (!is_dir(dirname($randName))) {
#        if (file_exists($randName) == false) {
            mkdir(dirname($randName), 0777, true);
        }
        $cmd = "git show {$newVer}:$value > $randName";
#        echo $cmd . PHP_EOL;
        exec($cmd, $result);
    }
}
$cmd = "/opt/gitlab/embedded/bin/semgrep  -f '$ruleFile' $baseDir  -o /tmp/11.txt";
exec($cmd, $result);
//ob_clean();
$notice = file_get_contents("/tmp/11.txt");
echo $notice . PHP_EOL;
file_put_contents("/tmp/11.txt", "");
exec("rm -rf $baseDir");
echo 0;


保存并推出此钩子文件,接着需要给自定义钩子目录设置权限,这里我简单粗暴的把权限设置为777,命令如下所示


chmod -R 777 ../


权限设置好之后,我还需要创建一个semgrep的扫描规则文件,用于判断代码是否正确。


执行的命令如下所示


vim /semgrep-rule.yaml


进入vim编辑器之后,需要将如下规则内容复制进去


rules:
  - id: assert-use
    patterns:
      - pattern: assert($ASSERT, ...);
      # - pattern-not: assert(<... $ASSERT ...>, ...); - https://github.com/returntocorp/semgrep/issues/2035
      - pattern-not: assert("...", ...);
    message: |
      使用用户输入调用assert等价于eval'。
    metadata:
      references:
        - https://www.php.net/manual/en/function.assert
        - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/AssertsSniff.php
    languages: [ php ]
    severity: ERROR
  - id: backticks-use
    pattern: '`...`;'
    message: |
      使用反勾号可能导致命令注入漏洞。
    metadata:
      references:
        - https://www.php.net/manual/en/language.operators.execution.php
        - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/BackticksSniff.php
    languages: [ php ]
    severity: ERROR


保存并推出规则文件后,需要修改此规则文件的权限,这里我以777权限距离,命令如下所示


chmod 777 /semgrep-rule.yaml


设置完规则文件权限之后,还有两个缓存地方需要设置权限,否则会在运行过程当中报错,首先是semgrep的缓存文件,设置权限命令如下


mkdir -p /var/opt/gitlab/.cache  && chmod -R 777 /var/opt/gitlab/.cache


另外一处是钩子本身的缓存文件,同样需要设置权限,执行的命令如下所示


echo '' > /tmp/11.txt  && chmod 777 /tmp/11.txt


5.2 测试钩子


现在可以正式测试钩子的可用性,首先需要拉取刚才创建的项目代码,命令如下所示


git clone http://127.0.0.1/root/test.git


执行命令之后,返回的信息如下所示


15.png


在上图中可以看到项目已经拉取下来,接下来我需要编辑一个php文件,命令如下所示


vim index.php


命令执行完毕之后,将测试的代码存放进去


<?php
phpinfo();
$cmd = "ls {$_GET['x']}";
exec($cmd);


保存并退出之后,将代码提交到gitlab中去,命令如下所示


echo ' ' >> index.php && git add . && git commit . -m 'init' && git push


但git往gitlab服务器推送之后,gitlab就会调用钩子,并将钩子返回的信息输出出来,如下图所示


16.png


在上图中可以看到钩子提示了 index.php文件第8行不安全,此致整个部署完毕。


目录
相关文章
|
安全 Shell API
蜻蜓:GitLab结合fortify实现自动化代码扫描实践
在甲方做安全的同学可能会有一项代码审计的工作,通常需要从gitlab把代码拉取下来,然后使用代码审计工具进行扫描,然后对结果进行人工确认; 在这个流程中需要做的事情比较繁琐,比如说gitlab如何配置token、如何自动化把代码拉取到本地、如何调用fortify实现批量扫描等诸多繁琐问题。 本篇文章以甲方安全代码安全建设为主线,分享如何让代码审计工具自动化扫描gitlab仓库里的代码。并且提供了一个便捷的实验环境供大家测试。
496 0
蜻蜓:GitLab结合fortify实现自动化代码扫描实践
|
运维 测试技术 持续交付
微服务项目部署实践:使用Gitlab Runner实现微服务项目的持续集成,持续交付和持续部署
本文通过详细的步骤一步一步说明在微服务架构的项目中如何进行项目部署的操作实践,通过Gitlab实现项目的持续集成,持续部署和持续交付。详解介绍的Gitlab中实现项目持续部署的工具GitLab Runner的具体使用步骤。通过这篇文章,可以熟悉微服务项目持续集成,持续交付和持续部署,学会使用GitLab Runner的具体使用方式,极大简化微服务项目的部署。
750 0
微服务项目部署实践:使用Gitlab Runner实现微服务项目的持续集成,持续交付和持续部署
|
缓存 前端开发 测试技术
Gitlab的落地与应用(二)测试代码接入Gitlab实践
Git&SVN对比、优缺点分析;Git目录、核心概念讲解;Git环境搭建、配置免密访问;测试代码接入gitlab、代码管理;
Gitlab的落地与应用(二)测试代码接入Gitlab实践
|
Kubernetes Java API
实践分享!GitLab CI/CD 快速入门
本文给大家讲述如何使用 GitLab CI/CD 构建、测试、部署 Spring Boot 应用,将产物运行在 Rainbond 上。
|
存储 Shell 应用服务中间件
基于docker-compose的Gitlab CI/CD实践&排坑指南
经过长时间实操验证,终于完成基于Gitlab的CI/CD实践,本次实践的坑位很多, 实操过程尽量接近最佳实践(不做hack, 不做骚操作),记录下来加深理解。
基于docker-compose的Gitlab CI/CD实践&排坑指南
|
Shell
搭建自己的gitlab服务端
搭建自己的gitlab服务端
288 0
搭建自己的gitlab服务端
|
缓存 负载均衡 前端开发
极狐GitLab实践影响地图的最佳方式
影响地图 (Impact Mapping )是一种战略规划方面的技术。它通过清晰的假设、可视化的形式,建立产品功能与商业目标之间的关系,并最终做出更合理的里程碑规划。从而使得开发人员在构建产品和交付过程中避免迷失方向。 本文将结合极狐GitLab来实践影响地图的最佳方式
307 1
极狐GitLab实践影响地图的最佳方式
|
持续交付 开发工具 Android开发
Android项目持续集成实践之Gitlab CI
简介 持续集成(Continuous integration)是一种软件开发实践,即团队开发成员经常集成它们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。 入门 下面我们来简单介绍
8331 0
|
缓存 Kubernetes Java
GitLab CI/CD 自动化构建与发布实践
GitLab CI/CD 自动化构建与发布实践
3408 0
GitLab CI/CD 自动化构建与发布实践
|
Kubernetes 负载均衡 jenkins
Kubernetes上基于GitLab+Jenkins的GitOps应用发布实践
## 1. 在 [容器服务控制台](https://cs.console.aliyun.com) 创建kubernetes集群 #### 1.1 新建Kubernetes集群: ![image](https://yqfile.alicdn.com/17bba07bc905b8049507005a9a65be1139709d61.png) #### 1.2 新建命名空间gito
2560 0
Kubernetes上基于GitLab+Jenkins的GitOps应用发布实践

相关实验场景

更多