Code Monkey home page Code Monkey logo

huskyci's Introduction

This article can also be read in Brazilian Portuguese.

Introduction

huskyCI is an open source tool that orchestrates security tests and centralizes all results into a database for further analysis and metrics. It can perform static security analysis in Python (Bandit and Safety), Ruby (Brakeman), JavaScript (Npm Audit and Yarn Audit), Golang (Gosec), Java (SpotBugs plus Find Sec Bugs), and HCL (TFSec). It can also audit repositories for secrets like AWS Secret Keys, Private SSH Keys, and many others using GitLeaks.

How does it work?

Developers can set up a new stage into their CI pipelines to check for vulnerabilities:

If security issues are found in the code, the severity, the confidence, the file, the line, and many more useful information can be shown, as exemplified:

[HUSKYCI][*] poc-python-bandit -> https://github.com/globocom/huskyCI.git
[HUSKYCI][*] huskyCI analysis started! yDS9tb9mdt4QnnyvOBp3eVAXE1nWpTRQ

[HUSKYCI][!] Title: Use of exec detected.
[HUSKYCI][!] Language: Python
[HUSKYCI][!] Tool: Bandit
[HUSKYCI][!] Severity: MEDIUM
[HUSKYCI][!] Confidence: HIGH
[HUSKYCI][!] Details: Use of exec detected.
[HUSKYCI][!] File: ./main.py
[HUSKYCI][!] Line: 7
[HUSKYCI][!] Code:
6
7 exec(command)
8

[HUSKYCI][!] Title: Possible hardcoded password: 'password123!'
[HUSKYCI][!] Language: Python
[HUSKYCI][!] Tool: Bandit
[HUSKYCI][!] Severity: LOW
[HUSKYCI][!] Confidence: MEDIUM
[HUSKYCI][!] Details: Possible hardcoded password: 'password123!'
[HUSKYCI][!] File: ./main.py
[HUSKYCI][!] Line: 1
[HUSKYCI][!] Code:
1 secret = 'password123!'
2
3 password = 'thisisnotapassword' #nohusky
4

[HUSKYCI][SUMMARY] Python -> huskyci/bandit:1.6.2
[HUSKYCI][SUMMARY] High: 0
[HUSKYCI][SUMMARY] Medium: 1
[HUSKYCI][SUMMARY] Low: 1
[HUSKYCI][SUMMARY] NoSecHusky: 1

[HUSKYCI][SUMMARY] Total
[HUSKYCI][SUMMARY] High: 0
[HUSKYCI][SUMMARY] Medium: 1
[HUSKYCI][SUMMARY] Low: 1
[HUSKYCI][SUMMARY] NoSecHusky: 1

[HUSKYCI][*] The following securityTests were executed and no blocking vulnerabilities were found:
[HUSKYCI][*] [huskyci/gitleaks:2.1.0]
[HUSKYCI][*] Some HIGH/MEDIUM issues were found in these securityTests:
[HUSKYCI][*] [huskyci/bandit:1.6.2]
ERROR: Job failed: exit code 190

Getting Started

You can try huskyCI by setting up a local environment using Docker Compose following this guide.

Documentation

All guides and the full documentation can be found in the official documentation page.

Contributing

Read our contributing guide to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to huskyCI.

Communication

We have a few channels for contact, feel free to reach out to us at:

Contributors


rafaveira3

Krlier

spimpaov

joserenatosilva

gabriel-cantergiani

marcelomagina

nettoclaudio

edersonbrilhante

GabhenDM

mdjunior

fguisso

vitoriario

rodrigo-brito

gustavocovas

abzcoding

lzakharov

itepifanio

victorpalmeira

meltedblocks

localleon

jimmy1134

henriquebonadio-zz

vfiebig

gitter-badger

renatoaquino

RayTdC

rafaelrubbioli

rafaelsq

ragoso

aranhams

This project exists thanks to all the contributors. You rock! โค๏ธ๐Ÿš€

License

huskyCI is licensed under the BSD 3-Clause "New" or "Revised" License.

huskyci's People

Contributors

abzcoding avatar actions-user avatar edersonbrilhante avatar fguisso avatar gabhendm avatar gabriel-cantergiani avatar gitter-badger avatar gustavocovas avatar henriquebonadio-zz avatar itepifanio avatar jimmy1134 avatar joserenatosilva avatar krlier avatar localleon avatar lzakharov avatar marcelomagina avatar mdjunior avatar meltedblocks avatar nettoclaudio avatar rafaelrubbioli avatar rafaelsq avatar rafaveira3 avatar ragoso avatar raytdc avatar renatoaquino avatar rodrigo-brito avatar spimpaov avatar vfiebig avatar victorpalmeira avatar vitoriario avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

huskyci's Issues

Verify if image exists and get image if it doesn't exist

The images used in Docker to start the containers with security tests is downloaded once from Vagrant script. However, image management must be done on the API. If the images are removed from Docker, the security tests will fail.

The HuskyCI API needs to know if images that deal with security tests exist and, if not, get from the correspondent registry. After that, the logic follows the current procedure.

Add a return statement into analysis.go

enrySecurityTestQuery := map[string]interface{}{"name": "enry"}
		enrySecurityTestResult, err := FindOneDBSecurityTest(enrySecurityTestQuery)
		if err != nil {
			fmt.Println("Error finding enry securityTest:", err)
                 }

Change limitEnryScan to 0 to force Husky always start enry

Although it would be nice avoiding a new Enry scan every time Husky starts an analysis, this might be necessary to guarantee that any vulnerability is not detected if a new language is inserted.

Example:

A new config.sh is added into the repository that contains hardcoded passwords. Enry may not detect this file for the futures 9 scans in the worst case scenario.

analysis.go: 302 response missing Location header

When building Husky client, the following error is being received when trying to GET an analysis:

Error during GET to Husky API: Get http://localhost:9999/husky/g3i2Yqrwv1hQfejdQehSMIOtcmOZsJCJ: 302 response missing Location header

The problem might be at return c.JSON(http.StatusFound, analysisResult) from analysis.go. A different status code like StatusOK would solve this problem.

ReadOutput() from api.go could return STDERR as well

func (d Docker) ReadOutput() (string, error) {
	dockerHost := os.Getenv("DOCKER_HOST")
	URL := "http://" + dockerHost + "/v1.24/containers/" + d.CID + "/logs?stdout=1"
	resp, err := http.Get(URL)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return string(body), err
}

URL := "http://" + dockerHost + "/v1.24/containers/" + d.CID + "/logs?stdout=1"
is being used but it would be nice to check if

URL := "http://" + dockerHost + "/v1.24/containers/" + d.CID + "/logs?stderr=1"
is also returns something!

Gathering metrics (Brainstorm)

For statistics purposes, it would be a good idea to implement the field numAnalysis into Repository.

An increment function is also needed when updating it into MongoDB.

type Repository struct {
	ID               bson.ObjectId  `bson:"_id,omitempty"`
	URL              string         `bson:"URL" json:"repositoryURL"`
	SecurityTests    []SecurityTest `bson:"securityTests" json:"securityTests"`
	SecurityTestName []string       `bson:"securityTestName,omitempty" json:"securityTestName"`
	VM               string         `bson:"VM" json:"vm"`
	CreatedAt        time.Time      `bson:"createdAt" json:"createdAt"`
	DeletedAt        time.Time      `bson:"deletedAt" json:"deletedAt"`
	Languages        []Language     `bson:"languages" json:"languages"`
}

Refactor DockerHostsConfig struct

Change DockerHostsConfig struct so that it stores:

  • Addresses
  • Protocol
  • DockerAPIVersion

@mdjunior : "The DockerAPI port that will be the same on all hosts?
Maybe it was better if the data structure allowed a list of hosts, where each host would be a structure with Address and Port (and eventually other things, such as certificates and keys)."

// DockerHostsConfig represents Docker Hosts configuration.
type DockerHostsConfig struct {
	Addresses     []string
	DockerAPIPort int

@mdjunior : "The http protocol and docker version is hardcoded. Maybe it was better if this information was entered in the DockerHosts data structure in context/config.go."

// HealthCheckAPI returns true if a 200 status code is received or false otherwise.
func HealthCheckAPI(dockerHost string) error {
	URL := fmt.Sprintf("http://%s/v1.24/version", dockerHost)

Cannot find package "github.com/globocom/glbgelf"

After installing the environment via make install, the following error is being found:

$ docker logs huskyCIAPI
server.go:10:2: cannot find package "github.com/globocom/glbgelf" in any of:
	/go/src/github.com/globocom/huskyci/vendor/github.com/globocom/glbgelf (vendor tree)
	/usr/local/go/src/github.com/globocom/glbgelf (from $GOROOT)
	/go/src/github.com/globocom/glbgelf (from $GOPATH)

Container's logs are coming with different outputs after refactor

Example:

Cloning into 'code'...
remote: Counting objects: 1620, done.
remote: Compressing objects: 100% (1141/1141), done.
remote: Total 1620 (delta 420), reused 1594 (delta 398), pack-reused 0
Receiving objects: 100% (1620/1620), 3.69 MiB | 2.15 MiB/s, done.
Resolving deltas: 100% (420/420), done.
{"Dockerfile":["Dockerfile"],"Go":["api/health.go","api/health_test.go","api/mock.go","api/scan.go","api/scan_test.go","api/server.go","cmd/root.go","cmd/server/server.go","cmd/server/server_test.go","cmd/worker/worker.go","cmd/worker/worker_test.go","db/mock.go","db/mongodb/mongo.go","db/mongodb/mongo_test.go","db/storage.go","main.go","queue/mock.go","queue/queue.go","scan/clair.go","scan/mock.go","scan/scan.go","scan/scheduler/default.go","scan/scheduler/default_test.go","scan/scheduler/mock.go","scan/scheduler/scheduler.go","scan/worker/default.go","scan/worker/default_test.go"],"Makefile":["Makefile"]}

Expected:

{"Dockerfile":["Dockerfile"],"Go":["api/health.go","api/health_test.go","api/mock.go","api/scan.go","api/scan_test.go","api/server.go","cmd/root.go","cmd/server/server.go","cmd/server/server_test.go","cmd/worker/worker.go","cmd/worker/worker_test.go","db/mock.go","db/mongodb/mongo.go","db/mongodb/mongo_test.go","db/storage.go","main.go","queue/mock.go","queue/queue.go","scan/clair.go","scan/mock.go","scan/scan.go","scan/scheduler/default.go","scan/scheduler/default_test.go","scan/scheduler/mock.go","scan/scheduler/scheduler.go","scan/worker/default.go","scan/worker/default_test.go"],"Makefile":["Makefile"]}

It could be optional git cloning repositories via SSH inside containers (security Tests)

Security tests configs could have cmds to git clone inside container with or without using SSH keys:

For example cmdSSHAuth and cmdNonAuth:

enry:
  name: enry
  image: huskyci/enry
  cmdSSHAuth: |+
    mkdir -p ~/.ssh &&
    echo 'GIT_PRIVATE_SSH_KEY' > ~/.ssh/huskyci_id_rsa &&
    chmod 600 ~/.ssh/huskyci_id_rsa &&
    echo "IdentityFile ~/.ssh/huskyci_id_rsa" >> /etc/ssh/ssh_config &&
    echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config &&
    git clone -b %GIT_BRANCH% --single-branch %GIT_REPO% code --quiet 2> /tmp/errorGitCloneEnry
    if [ $? -eq 0 ]; then
      cd code
      enry --json | tr -d '\r\n'
    else
      echo "ERROR_CLONING"
      cat /tmp/errorGitCloneEnry
    fi
  cmdNonAuth: |+
    git clone -b %GIT_BRANCH% --single-branch %GIT_REPO% code --quiet 2> /tmp/errorGitCloneEnry
    if [ $? -eq 0 ]; then
      cd code
      enry --json | tr -d '\r\n'
    else
      echo "ERROR_CLONING"
      cat /tmp/errorGitCloneEnry
    fi
  language: Generic
  default: true
  timeOutInSeconds: 60

Standardize how error messages are sent to the user

Create a new standard for all error messages to be used by Husky as suggested by @nettoclaudio:

I would returned the echo.NewHTTPError(http.StatusNotFound, "analysis not found") instead that. I think that's the standardized by Echo web framework.

Ref.: https://echo.labstack.com/guide/error-handling

Include into dockers' cmd an auth command to git clone private repositories

The following commands may need to use git private and pub ssh keys to clone private repositories:

git clone %GIT_REPO% code --quiet && cd code && enry --json | tr -d '\r\n'
cd src; git clone %GIT_REPO% code --quiet && cd code && /go/bin/gas -quiet -fmt=json -log=log.txt -out=results.json ./... 2> /dev/null ; jq -j -M -c . results.json

Create husky client to be downloaded and executed during a CI

Husky must have a client with the following features:

  • Send request to Husky API.
  • From time to time, check if the scan has already finished.
  • Receive eventual parameters (name of the scan, ignore files, how paranoid the scan should be, etc.)
  • Fail/Pass the pipeline.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.