Sonar-自动化代码审查

2,314 阅读6分钟

Sonar是一个自动code review工具,检测代码的bugs,漏洞和坏味道。它可以和现有的工具流(jekins、github等)集成从而能够对代码分支(project branchs)和拉取请求(pull requests)持续的代码检测。

试用SonarQube

安装 SonarQube

  1. 下载并安装Java11
  2. 下载SonarQube 社区版 zip 文件
  3. 解压文件,启动服务
cd /var/srvbot/sonarqube-5.6.7/bin/linux-x86-64
./sonar.sh start

其他命令(启动,重启,停止)

./sonar.sh start   启动服务 
./sonar.sh stop    停止服务 
./sonar.sh restart 重启服务

打开浏览器,通过http://localhost:9000/ 访问web页面。 账号: admin 密码: admin

安装Sonar Scanner

实用工具SonarQube Scanner扫描代码。

  1. 下载sonar-scanner-2.6.1.zip解压
  2. 配置环境变量 命令行执行:vim ~/.bash_profile,编辑:
# sonar环境
export SONAR_HOME=/usr/local/sonarqube-7.6
export SONAR_SCANNER_HOME=/usr/local/sonar-scanner-3.2
export PATH=$M2:$PATH:$SONAR_SCANNER_HOME/bin:$JAVA_HOME/bin

保存后,终端执行source ~/.bash_profile使环境变量生效 最后,终端执行sonar-scanner --version,显示如下即配置成功:

INFO: Scanner configuration file: /usr/local/Cellar/sonar-scanner/4.2.0.1873/libexec/conf/sonar-scanner.properties
INFO: Project root configuration file: NONE
INFO: SonarQube Scanner 4.2.0.1873
INFO: Java 1.8.0_191 Oracle Corporation (64-bit)
INFO: Mac OS X 10.14.5 x86_64

使用

  1. 打开项目跟路径 创建sonar-project.properties文件
  2. 编写sonar-project.properties
# must be unique in a given SonarQube instance
sonar.projectKey=itil:change
# this is the name displayed in the SonarQube UI
sonar.projectName=change
sonar.projectVersion=1.0

# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# Since SonarQube 4.2, this property is optional if sonar.modules is set. 
# If not set, SonarQube starts looking for source code from the directory containing 
# the sonar-project.properties file.
sonar.sources=src

# Encoding of the source code. Default is default system encoding
#sonar.sourceEncoding=UTF-8

3. 登录本地的SonarQube,让我们分析一个项目: (1)单击创建新项目按钮。 (2)给您的项目一个项目键和一个显示名称,然后单击设置按钮。 (3)在提供令牌下,选择生成令牌。为您的令牌命名,单击Generate按钮,然后单击Continue。 4. 在项目根目录下运行scanner

sonar-scanner \
  -Dsonar.projectKey=Test \
  -Dsonar.sources=. \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.login=2d20ae700cd025515440c87b8f25f62e43409

5. 进入SonarQube WEB界面,看分析情况。

Sonar整体设计

sonar

sonar有3部分组成

  1. SonarScanner scanner分析代码,分析结果以报告的形式发送给服务端SonarQube处理。
  2. SonarQube (1) web服务器,为 SonarQube 用户界面提供服务。 (2) 搜索服务器,基于 Elasticsearch的搜索。 (3) 计算引擎,责处理代码分析报告并将其保存在 SonarQube 数据库中。
  3. 数据库存储 (1) 存储代码扫描期间生成的代码质量和安全性指标和问题。 (2) 存储SonarQube 实例配置。

SonarQube界面功能

1 在web界面的tab中,包含6个tab,即6个功能模块。

  • Projects
  • Issues
  • Rules
  • Quality Profiles
  • Quality Gates
  • Administration

Rules

164702243-84cd31d8-8bbc-45fb-bfc0-a971868b7e13.png

代码应该遵循的标准,Rules分为4类。

  1. Bug,代码错误,和代码的可靠性有关。
  2. 坏味道,和代码的可维护性有关。
  3. 漏洞,给攻击者留后门,和安全有关。
  4. 安全热点,需要手动检查的安全敏感代码段,是否需要修改开发人员决定,和安全相关。

定义Rules实例

下面我扪看一下定义的规则的几个实例。

bug

"delete" should be used only with object properties delete操作符只能用于删除对象的属性。 不符合规则的代码:

var x  = 1;
delete x;       // Noncompliant

function foo(){
..
}

delete foo;  // Noncompliant

对不符合规则的代码修改,使其符合规则:

var obj = {
  x:1,
  foo: function(){
  ...
  }
};
delete obj.x;
delete obj.foo;

坏味道

"===" and "!==" should be used instead of "==" and "!=" ==和!=操作符在比较值之前进行类型强制转换。这样是不好的,因为它会忽略类型错误。例如,' \t\r\n' == 0为true。 不符合规则的代码:

if (var == 'howdy') {...} // Noncompliant

对不符合规则的代码修改,使其符合规则:

if (var === 'howdy') {...}

漏洞

Origins should be verified during cross-origin communications 浏览器允许不同来源的Window对象之间交换消息。 因为任何窗口都可以从另一个窗口发送或接收消息,所以验证发送方/接收方的身份很重要:

  • 当使用postMessage方法发送消息时,应该指定接收者(不应该使用通配符关键字(*))。
  • 当接收带有消息事件的消息时,应使用源属性(可能还有源属性)验证发送方的身份。 不符合规则的代码:
/** 发送消息时 **/
var iframe = document.getElementById("testiframe");
iframe.contentWindow.postMessage("secret", "*"); // Noncompliant: * is used
/** 接收消息时 **/
window.addEventListener("message", function(event) { // Noncompliant: no checks are done on the origin property.
      console.log(event.data);
 });

对不符合规则的代码修改,使其符合规则:

/** 发送消息时 **/
var iframe = document.getElementById("testsecureiframe");
iframe.contentWindow.postMessage("hello", "https://secure.example.com"); // Compliant
/** 接收消息时 **/
window.addEventListener("message", function(event) {

  if (event.origin !== "http://example.org") // Compliant
    return;

  console.log(event.data)
});

安全热点

Creating cookies without the "HttpOnly" flag is security-sensitive cookie的HttpOnly属性表示脚本能否获取到cookie值。大多数情况下,HttpOnly默认为false。当cookie存储的是sesson-cookie时,用于身份认证信息,如果HttpOnly设置为true,能够避免潜在的XSS攻击。HttpOnly的值的设置取决于当前的使用场景,需要手动审查。

Quality Profiles

Quality profiles是rules的集合,是分析代码的依据,分析代码时根据一个profile对代码做分析。 profile 如上图所示一个名为Sonar way的profile,总共包含191个规则,其中Bugs54个,漏洞11个,坏味道91个,安全热点35个。在执行代码分析时,按照这些规则集(即一个 profile)分析,最终分析结果展示在web界面中。

Quality Gates

代码是否能够发布的总体标准,这个标准是可以在自己设置的。 图片1

集成

overview

一个典型的开发过程:

  1. 开发人员用一个IDE开发和合并代码(建议使用SonarLint在编辑器中得到检查的实时反馈),然后把代码放入开发运维平台。
  2. 一套持续的集成工具检查、构建和执行单元测试,并且集成SonarQube scanner用于分析代码。
  3. SonarQube scanner把分析结果提交给SonarQube server。SonarQube server通过web,email,in-IDE通知(通过SonarLint)。

SonarLint集成

SonarLint是一个IDE的免费插件,在写代码时在IDE中检测出bugs和漏洞。SonarLint是你的代码的质量和安全审查工具,SonarQube是你的团队的代码的质量和安全审查工具。 SonarLint使用如下:

user-images.githubusercontent.com/9429326/164…

SonarLint和SonarQube可以建立连接,你的SonarQube配置和设置被扩展到SonarLint,从你开始编写代码的那一刻起就给你提供一致、可靠的分析结果。

Gitlab/Github集成

push代码和提交pull request自动触发sonar分析。 SonarQube支持对最新更新的代码部分分析,这样把关注放在最新更新的部分代码的质量和安全。 Pull Request分析显示了你的一个Pull Request的更新代码的quality gate和SonarQube界面的分析。这个分析显示了Pull Request在合并目标分支之前引入的新问题: pr

Jekins集成

把SonarQube scanner集成到Jekins, Jekins构建时自动触发SonarQube scanner扫描。