Skip to content

Commit

Permalink
SARIF support and integration with Github Alerts (#29)
Browse files Browse the repository at this point in the history
* Feat/add makefile (#21)

* develop

* release/0.0.6

* feat: add Dockerized build and run support

- Added Makefile for Dockerized application
- Defined Docker image and version variables
- Included Docker commands for build, run, exec, stop, clean, and rebuild

Why: Facilitate easy development, testing, and deployment using Docker.

* test perl critic

* test perl critic

* fix

* syntax

* identation

* add path

* identation

* test

* test of rule

* fix

* remove examples

* remove rules

* fix code

* new policies

* fix linter errors

* update version to 0.0.6

* Support SARIF output format #11  (#27)

* feat!: support of SARIF output format when "--sarif" option is passed as a parameter

BREAKING CHANGES:

recieves "--sarif" as a parameter 

stores the subset of information present on ZARN to generate SARIF output

function to generate SARIF output

* feat!: support "--sarif" option for outputs of this type

* fix: variables declaration, SARIF generation

* update workflows

* Support SARIF output format (#28)

* Bump actions/checkout from 2 to 4 (#26)

Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v2...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* initializing sarif output format and some refactor on ast file

* update the command description

* commiting code changes to make checkpoint - most part of the implementation are correct now but still with some problems

* support sarif output format

* perlcritic update

* solve merge problems

* remove unused method

* some changes

now we maintain the actual output of the tool but in case the user pass --sarif with a string for filename we will create the corresponding file with the output at this file in sarif

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* added JSON as a dependencie

* update version

* starting refactoring

* added example of sarif command

* adjusts on style code

* return to privsec version

* fix linter warnings

* rename

* update version

* fix syntax

* rename SARIF to Sarif

* fix

* fixes to be a valid sarif file

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Anderson Bosa <andersonbosa0@gmail.com>
Co-authored-by: Heitor Gouvêa <htrgouvea@Heitors-MacBook-Pro.local>
Co-authored-by: priv <140729444+scriptprivate@users.noreply.github.com>
Co-authored-by: Giovanni Martins <giovannimartins2000@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
6 people authored Nov 20, 2023
1 parent d1acedc commit 9c9c22a
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 56 deletions.
1 change: 1 addition & 0 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
pull_request:
branches:
- main
- develop

jobs:
critic:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
name: Testing on Ubuntu
on: [push]

on:
pull_request:
branches:
- main
- develop

jobs:
build:
Expand All @@ -13,4 +18,7 @@ jobs:
sudo cpanm --installdeps .
- name: Verify the basic usage
run: |
perl zarn.pl --source . --ignore examples
perl zarn.pl --source . --sarif zarn.sarif
- uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: zarn.sarif
4 changes: 1 addition & 3 deletions .github/workflows/security-gate.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
name: Security Gate - Instriq

on:
push:
branches:
- main
pull_request:
branches:
- main
- develop

jobs:
build:
Expand Down
6 changes: 6 additions & 0 deletions .perltidyrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
--maximum-line-length=120
--indent-columns=4
--continuation-indentation=4
--square-bracket-tightness=2
--tight-secret-operators
--maximum-consecutive-blank-lines=1
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<img src="https://img.shields.io/badge/license-MIT-blue.svg">
</a>
<a href="https://github.com/htrgouvea/zarn/releases">
<img src="https://img.shields.io/badge/version-0.0.5-blue.svg">
<img src="https://img.shields.io/badge/version-0.0.8-blue.svg">
</a>
</p>
</p>
Expand Down Expand Up @@ -37,7 +37,7 @@ $ sudo cpanm --installdeps .
### Example of use

```bash
$ perl zarn.pl --rules rules/quick-wins.yml --source ../nozaki
$ perl zarn.pl --rules rules/quick-wins.yml --source ../nozaki --sarif report.sarif

[warn] - FILE:../nozaki/lib/Functions/Helper.pm Potential: Timing Attack.
[vuln] - FILE:../nozaki/lib/Engine/Orchestrator.pm Potential: Path Traversal.
Expand Down
3 changes: 2 additions & 1 deletion cpanfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
requires "File::Find::Rule", "0.34";
requires "Getopt::Long", "2.54";
requires "YAML::Tiny", "1.73";
requires "PPI::Document", "1.276";
requires "PPI::Document", "1.276";
requires "JSON";
69 changes: 30 additions & 39 deletions lib/Zarn/AST.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package Zarn::AST {

sub new {
my ($self, $parameters) = @_;
my ($file, $rules);
my ($file, $rules, @results);

Getopt::Long::GetOptionsFromArray (
$parameters,
Expand All @@ -27,50 +27,41 @@ package Zarn::AST {
my $category = $rule -> {category};
my $title = $rule -> {name};

if ($self -> matches_sample($token -> content(), \@sample)) {
$self -> process_sample_match($document, $category, $file, $title, $token);
if (grep {my $content = $_; scalar(grep {$content =~ m/$_/} @sample)} $token -> content()) {
my $next_element = $token -> snext_sibling;

# this is a draft source-to-sink function
if (defined $next_element && ref $next_element && $next_element -> content() =~ /[\$\@\%](\w+)/) {
# perform taint analyis
my $var_token = $document -> find_first (
sub { $_[1] -> isa("PPI::Token::Symbol") and $_[1] -> content eq "\$$1" }
);

if ($var_token && $var_token -> can("parent")) {
if ((
$var_token -> parent -> isa("PPI::Token::Operator") ||
$var_token -> parent -> isa("PPI::Statement::Expression")
)) {
my ($line, $rowchar) = @{$var_token -> location};

push @results, {
category => $category,
file => $file,
title => $title,
line => $line,
rowchar => $rowchar
};
}
}
}
}
}
}
}

return 1;
}

sub matches_sample {
my ($self, $content, $sample) = @_;

return grep {
my $sample_content = $_;
scalar(grep {$content =~ m/$_/} @$sample)
} @$sample;
}

sub process_sample_match {
my ($self, $document, $category, $file, $title, $token) = @_;

my $next_element = $token -> snext_sibling;

# this is a draft source-to-sink function
if (defined $next_element && ref $next_element && $next_element -> content() =~ /[\$\@\%](\w+)/) {
# perform taint analysis
$self -> perform_taint_analysis($document, $category, $file, $title, $next_element);
return @results;
}
}

sub perform_taint_analysis {
my ($self, $document, $category, $file, $title, $next_element) = @_;

my $var_token = $document -> find_first(
sub { $_[1 ] -> isa("PPI::Token::Symbol") and $_[1] -> content eq "\$$1" }
);

if ($var_token && $var_token -> can("parent")) {
if (($var_token -> parent -> isa("PPI::Token::Operator") || $var_token -> parent -> isa("PPI::Statement::Expression"))) {
my ($line, $rowchar) = @{ $var_token -> location };
print "[$category] - FILE:$file \t Potential: $title. \t Line: $line:$rowchar.\n";
}
}
return 0;
}
}

Expand Down
49 changes: 49 additions & 0 deletions lib/Zarn/Sarif.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package Zarn::Sarif {
use strict;
use warnings;

sub new {
my ($self, @vulnerabilities) = @_;

my $sarif_data = {
"\$schema" => "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
version => "2.1.0",
runs => [{
tool => {
driver => {
name => "ZARN",
informationUri => "https://github.com/htrgouvea/zarn",
version => "0.0.8"
}
},
results => []
}]
};

foreach my $info (@vulnerabilities) {
my $result = {
ruleId => $info -> {title},
message => {
text => $info -> {title}
},
locations => [{
physicalLocation => {
artifactLocation => {
uri => $info -> {file}
},
region => {
startLine => $info -> {line},
startColumn => $info -> {rowchar}
}
}
}]
};

push @{$sarif_data -> {runs}[0]{results}}, $result;
}

return $sarif_data;
}
}

1;
46 changes: 37 additions & 9 deletions zarn.pl
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,37 @@
use strict;
use warnings;
use lib "./lib/";
use Getopt::Long;
use Zarn::AST;
use Zarn::Files;
use Zarn::Rules;
use Getopt::Long;
use Zarn::Sarif;
use JSON;

sub main {
my $rules = "rules/default.yml";

my ($source, $ignore);
my ($source, $ignore, $sarif, @results);

Getopt::Long::GetOptions (
"r|rules=s" => \$rules,
"s|source=s" => \$source,
"i|ignore=s" => \$ignore
"r|rules=s" => \$rules,
"s|source=s" => \$source,
"i|ignore=s" => \$ignore,
"srf|sarif=s" => \$sarif
);

if (!$source) {
print "
\rZarn v0.0.5
\rZarn v0.0.8
\rCore Commands
\r==============
\r\tCommand Description
\r\t------- -----------
\r\t-s, --source Configure a source directory to do static analysis
\r\t-r, --rules Define YAML file with rules
\r\t-i, --ignore Define a file or directory to ignore
\r\t-srf, --sarif Define the SARIF output file
\r\t-h, --help To see help menu of a module\n
";
\r";

exit 1;
}
Expand All @@ -41,9 +44,34 @@ sub main {

foreach my $file (@files) {
if (@rules) {
my $analysis = Zarn::AST -> new (["--file" => $file, "--rules" => @rules]);
my @analysis = Zarn::AST -> new ([
"--file" => $file,
"--rules" => @rules
]);

push @results, @analysis;
}
}

foreach my $result (@results) {
my $category = $result -> {category};
my $file = $result -> {file};
my $title = $result -> {title};
my $line = $result -> {line};
my $rowchar = $result -> {rowchar};

print "[$category] - FILE:$file \t Potential: $title. \t Line: $line:$rowchar\n";
}

if ($sarif) {
my $sarif_data = Zarn::Sarif -> new (@results);

open(my $output, '>', $sarif) or die "Cannot open file '$sarif': $!";
print $output encode_json($sarif_data);
close($output);
}

return 0;
}

exit main();

0 comments on commit 9c9c22a

Please sign in to comment.