Skip to content

Commit

Permalink
Merge pull request #2 from Orange-Cyberdefense/sca-develop
Browse files Browse the repository at this point in the history
SCA (Software Composition Analysis) capabilities
  • Loading branch information
fxbru authored Feb 10, 2023
2 parents 06b52be + ae4ce18 commit dcfe737
Show file tree
Hide file tree
Showing 17 changed files with 1,314 additions and 352 deletions.
14 changes: 13 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,32 @@ WORKDIR /opt/grepmarx

ENV FLASK_APP run.py

RUN apt-get update && apt-get install -y supervisor && rm -rf /var/lib/apt/lists/*
RUN apt-get update

# Supervisord install & configuration
RUN apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor
COPY supervisord-docker.conf /etc/supervisor/conf.d/supervisord.conf

# Copy required files into the container
COPY entrypoint.sh run.py gunicorn-cfg.py requirements.txt requirements-pgsql.txt ./
COPY .env-docker .env
COPY nginx nginx
COPY app app
COPY migrations migrations
RUN mkdir data

# Install dependencies
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements-pgsql.txt

# Dependency scan (cdxgen / depscan) requirements
RUN apt-get install -y npm openjdk-17-jdk maven gradle golang composer
RUN npm install -g @cyclonedx/cdxgen

# Downloaded packages cleaning
RUN rm -rf /var/lib/apt/lists/*

EXPOSE 5000
#EXPOSE 443

Expand Down
38 changes: 24 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
![Grepmarx](media/grepmarx-logo.png)

# Grepmarx - source code static analysis platform for security auditors
# Grepmarx - Application Security Platform

Grepmarx is a web application providing a single platform to quickly understand, analyze and identify vulnerabilities in possibly large and unknown code bases.

## Features

Code scanning capabilities
- Security code analysis (SAST - Static Analysis Security Testing)
SAST (Static Analysis Security Testing) capabilities:
- Multiple languages support: C/C++, C#, Go, HTML, Java, Kotlin, JavaScript, TypeScript, OCaml, PHP, Python, Ruby, Bash, Rust, Scala, Solidity, Terraform, Swift
- Multiple frameworks support: Spring, Django, Flask, jQuery, Express, Angular...
- Inspector: automatic application features discovery

Analysis rules
- Multiple frameworks support: Spring, Laravel, Symfony, Django, Flask, Node.js, jQuery, Express, Angular...
- 1600+ existing analysis rules
- Easily extend analysis rules using Semgrep syntax: https://semgrep.dev/editor
- Manage rules in rule packs to tailor code scanning

SCA (Software Composition Analysis) capabilities:
- Multiple package-dependency formats support: NPM, Maven, Gradle, Composer, pip, Gopkg, Gem, Cargo, NuPkg, CSProj, PubSpec, Cabal, Mix, Conan, Clojure, Docker, GitHub Actions, Jenkins HPI, Kubernetes
- SBOM (Software Bill-of-Materials) generation (CycloneDX compliant)

Extra
- Analysis workbench designed to efficiently browse scan results
- Scan code that doesn't compile
- Comprehensive LOC (Lines of Code) counter
- Inspector: automatic application features discovery
- ... and a Dark Mode

## Screenshots
Expand Down Expand Up @@ -79,12 +80,6 @@ Visit `http://localhost:8001` in your browser. The app should be up & running.

## Build from sources

> A Redis server is required to queue security scans. Install the `redis` package with your favorite distro package manager, then:
```bash
$ redis-server
```

> Get the code
```bash
Expand All @@ -105,6 +100,20 @@ $ # OR with PostgreSQL connector (Production)
$ # pip install -r requirements-pgsql.txt
```

> Install additionnal requirements
```bash
# Dependency scan (cdxgen / depscan) requirements
$ sudo apt install npm openjdk-17-jdk maven gradle golang composer
$ sudo npm install -g @cyclonedx/cdxgen
$ pip install appthreat-depscan
```

> A Redis server is required to queue security scans. Install the `redis` package with your favorite distro package manager, then:
```bash
$ redis-server
```

> Set the FLASK_APP environment variable
```bash
$ export FLASK_APP=run.py
Expand Down Expand Up @@ -132,7 +141,8 @@ $ flask run --host=0.0.0.0 --port=5000
## Credits & Links

- The web application dashboard is based on [AdminLTE Flask](https://github.com/app-generator/flask-dashboard-adminlte)
- Code scanning is powered by the [semgrep](https://semgrep.dev/) engine
- SAST code scanning is powered by the [semgrep](https://semgrep.dev/) engine
- SBOM generation is done with the great [CycloneDX cdxgen](https://github.com/CycloneDX/cdxgen), and SCA is performed using the awesome [AppThreat dep-scan](https://github.com/AppThreat/dep-scan)
- LOC counting is handled by [scc](https://github.com/boyter/scc)
- Features discovery is done using A[pplication Inspector](https://github.com/microsoft/ApplicationInspector)

Expand Down
14 changes: 5 additions & 9 deletions app/administration/templates/repos_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,6 @@ <h1>Rule repositories</h1>
</ol>
</div>
</div>
<div class="row mb-2">
<div class="btn-group float-sm-right">
<button class="btn btn-default"
data-toggle="modal" data-target="#confirm-sync">
<span class="fas fa-sync-alt"></span>
Sync rules
</button>
</div>
</div>
<div class="row mb-2 ">
<div class="col-sm-8">
<p class="mb-3">
Expand All @@ -40,6 +31,11 @@ <h1>Rule repositories</h1>

<div class="col-sm-4">
<div class="btn-group float-sm-right">
<button class="btn btn-default"
data-toggle="modal" data-target="#confirm-sync">
<span class="fas fa-sync-alt"></span>
Sync rules
</button>
<a class="btn btn-default" href="/repos/add">
<span class="fas fa-plus-circle"></span>
Add repository
Expand Down
66 changes: 53 additions & 13 deletions app/analysis/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Copyright (c) 2021 - present Orange Cyberdefense
"""

from sqlalchemy import Column, Integer, String
from sqlalchemy import Boolean, Column, Integer, String

from app import db
from app.rules.models import analysis_to_rule_pack_association_table
Expand Down Expand Up @@ -51,9 +51,7 @@ class Occurence(db.Model):
__tablename__ = "Occurence"

id = Column(Integer, primary_key=True)
vulnerability_id = db.Column(
db.Integer, db.ForeignKey("Vulnerability.id"), nullable=False
)
vulnerability_id = db.Column(db.Integer, db.ForeignKey("Vulnerability.id"), nullable=False)
vulnerability = db.relationship(
"Vulnerability",
backref=db.backref("occurences", lazy=True, cascade="all, delete-orphan"),
Expand All @@ -76,6 +74,53 @@ class Position(db.Model):
column_end = Column(Integer)


class VulnerableDependency(db.Model):
__tablename__ = "VulnerableDependency"

id = Column(Integer, primary_key=True)
analysis_id = db.Column(db.Integer, db.ForeignKey("Analysis.id"), nullable=False)
analysis = db.relationship(
"Analysis",
backref=db.backref(
"vulnerable_dependencies", lazy=True, cascade="all, delete-orphan"
),
)
common_id = Column(String, nullable=False)
bom_ref = Column(String, nullable=False)
pkg_type = Column(String, nullable=False)
pkg_ref = Column(String, nullable=False)
pkg_name = Column(String, nullable=False)
source = Column(String, nullable=False)
severity = Column(String, nullable=False)
cvss_score = Column(String)
cvss_version = Column(String)
cwes = Column(String)
description = Column(String)
recommendation = Column(String)
version = Column(String, nullable=False)
fix_version = Column(String)
prioritized = Column(Boolean)
vendor_confirmed = Column(Boolean)
has_poc = Column(Boolean)
has_exploit = Column(Boolean)
direct = Column(Boolean)
indirect = Column(Boolean)

class VulnerableDependencyReference(db.Model):
__tablename__ = "VulnerableDependencyReference"

id = Column(Integer, primary_key=True)
title = Column(String)
url = Column(String)
vulnerable_dependency_id = db.Column(
db.Integer, db.ForeignKey("VulnerableDependency.id"), nullable=True
)
vulnerable_dependency = db.relationship(
"VulnerableDependency",
backref=db.backref("advisories", lazy=True, cascade="all, delete-orphan"),
)


class AppInspector(db.Model):

__tablename__ = "AppInspector"
Expand All @@ -85,12 +130,13 @@ class AppInspector(db.Model):
project = db.relationship("Project", back_populates="appinspector")



class Match(db.Model):

__tablename__ = "Match"
id = Column(Integer, primary_key=True)
app_inspector_id = db.Column(db.Integer, db.ForeignKey("AppInspector.id"), nullable=False)
app_inspector_id = db.Column(
db.Integer, db.ForeignKey("AppInspector.id"), nullable=False
)
appinspector = db.relationship(
"AppInspector",
backref=db.backref("match", lazy=True, cascade="all, delete-orphan"),
Expand All @@ -108,9 +154,7 @@ class InspectorTag(db.Model):
__tablename__ = "InspectorTag"

id = Column(Integer, primary_key=True)
match_id = db.Column(
db.Integer, db.ForeignKey("Match.id"), nullable=False
)
match_id = db.Column(db.Integer, db.ForeignKey("Match.id"), nullable=False)
match = db.relationship(
"Match",
backref=db.backref("tag", lazy=True, cascade="all, delete-orphan"),
Expand All @@ -122,7 +166,3 @@ class InspectorTag(db.Model):
start_line = Column(Integer)
end_column = Column(Integer)
end_line = Column(Integer)




Loading

0 comments on commit dcfe737

Please sign in to comment.