Skip to content

Commit

Permalink
Merge pull request #11 from instriq/develop
Browse files Browse the repository at this point in the history
refactor Code and Dependencies modules, fix severity counting, and update README
  • Loading branch information
htrgouvea authored Sep 11, 2024
2 parents 8d4bf0d + 230c9c9 commit d35a39a
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 89 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Core Commands
Command Description
------- -----------
-t, --token GitHub token
-r, --repo GitHub repository, organization/repository-name
-r, --repo GitHub repository, organization/repository-name
-c, --critical Critical severity limit
-h, --high High severity limit
-m, --medium Medium severity limit
Expand Down Expand Up @@ -122,4 +122,4 @@ Your contributions and suggestions are heartily ♥ welcome. [See here the contr

### License

This work is licensed under [MIT License.](/LICENSE.md)
This work is licensed under [MIT License.](/LICENSE.md)
86 changes: 43 additions & 43 deletions lib/SecurityGate/Engine/Code.pm
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,55 @@ package SecurityGate::Engine::Code {
use Mojo::JSON;

sub new {
my ($class, $token, $repository, $severity_limits) = @_;
my $alerts_endpoint = "https://api.github.com/repos/$repository/code-scanning/alerts";

my $userAgent = Mojo::UserAgent -> new();
my $alerts_request = $userAgent -> get($alerts_endpoint, {Authorization => "Bearer $token"}) -> result();

if ($alerts_request -> code() == 200) {
my $alerts_data = $alerts_request -> json();
my $open_alerts = 0;
my %severity_counts = map {$_ => 0} keys %$severity_limits;

foreach my $alert (@$alerts_data) {
if ($alert -> {state} eq "open") {
$open_alerts++;

my $severity = $alert -> {rule} -> {severity};
$severity_counts{$severity}++ if exists $severity_counts{$severity};
}
}
my ($class, $token, $repository, $severity_limits) = @_;
my $alerts_endpoint = "https://api.github.com/repos/$repository/code-scanning/alerts";

print "[!] Total of open code scanning alerts: $open_alerts\n";

foreach my $severity (keys %severity_counts) {
print "[-] $severity: $severity_counts{$severity}\n";
}
my $userAgent = Mojo::UserAgent->new();
my $alerts_request = $userAgent->get($alerts_endpoint, {Authorization => "Bearer $token"})->result();

my $threshold_exceeded = 0;

foreach my $severity (keys %severity_counts) {
if ($severity_counts{$severity} > $severity_limits -> {$severity}) {
print "[+] More than $severity_limits->{$severity} $severity code scanning alerts found.\n";

$threshold_exceeded = 1;
}
}
if ($alerts_request->code() == 200) {
my $alerts_data = $alerts_request->json();
my $open_alerts = 0;
my %severity_counts = map {$_ => 0} keys %$severity_limits;

foreach my $alert (@$alerts_data) {
if ($alert->{state} eq "open") {
$open_alerts++;

my $severity = $alert->{rule}->{security_severity_level} // 'unknown';
$severity_counts{$severity}++ if exists $severity_counts{$severity};
}
}

print "\n[!] Total of open code scanning alerts: $open_alerts\n\n";

if ($threshold_exceeded) {
return 1;
foreach my $severity (keys %severity_counts) {
print "[-] $severity: $severity_counts{$severity}\n";
}

print "\n";

my $threshold_exceeded = 0;

foreach my $severity (keys %severity_counts) {
if ($severity_counts{$severity} > $severity_limits->{$severity}) {
print "[+] More than $severity_limits->{$severity} $severity code scanning alerts found.\n";
$threshold_exceeded = 1;
}
}

if ($threshold_exceeded) {
return 1;
}
}
}

else {
print "Error: Unable to fetch code scanning alerts. HTTP status code: " . $alerts_request -> code() . "\n";

return 1;
}
else {
print "Error: Unable to fetch code scanning alerts. HTTP status code: " . $alerts_request->code() . "\n";
return 1;
}

return 0;
return 0;
}
}

1;
1;
26 changes: 13 additions & 13 deletions lib/SecurityGate/Engine/Dependencies.pm
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ package SecurityGate::Engine::Dependencies {
my ($class, $token, $repository, $severity_limits) = @_;

my %severity_counts = map { $_ => 0 } @SEVERITIES;

my $endpoint = "https://api.github.com/repos/$repository/dependabot/alerts";
my $userAgent = Mojo::UserAgent -> new();
my $request = $userAgent -> get($endpoint, {Authorization => "Bearer $token"}) -> result();
my $userAgent = Mojo::UserAgent->new();
my $request = $userAgent->get($endpoint, {Authorization => "Bearer $token"})->result();

if ($request->code() == 200) {
my $data = $request->json();

if ($request -> code() == 200) {
my $data = $request -> json();

foreach my $alert (@$data) {
if ($alert -> {state} eq "open") {
my $severity = $alert -> {security_vulnerability} -> {severity};
if ($alert->{state} eq "open") {
my $severity = $alert->{security_vulnerability}->{severity};
$severity_counts{$severity}++;
}
}

print "[!] Total of security alerts:\n\n";
print "\n[!] Total of dependency alerts:\n\n";

foreach my $severity (@SEVERITIES) {
print "[-] $severity: $severity_counts{$severity}\n";
Expand All @@ -38,20 +38,20 @@ package SecurityGate::Engine::Dependencies {
my $threshold_exceeded = 0;

foreach my $severity (@SEVERITIES) {
if ($severity_counts{$severity} > $severity_limits -> {$severity}) {
if ($severity_counts{$severity} > $severity_limits->{$severity}) {
print "[+] More than $severity_limits->{$severity} $severity security alerts found.\n";
$threshold_exceeded = 1;
}
}

return $threshold_exceeded;
}

else {
print "Error: Unable to fetch alerts. HTTP status code: " . $request -> code() . "\n";
print "Error: Unable to fetch alerts. HTTP status code: " . $request->code() . "\n";
return 1;
}
}
}

1;
1;
37 changes: 21 additions & 16 deletions lib/SecurityGate/Engine/Secrets.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8,43 +8,48 @@ package SecurityGate::Engine::Secrets {
my ($class, $token, $repository, $severity_limits) = @_;

my $endpoint = "https://api.github.com/repos/$repository/secret-scanning/alerts";
my $userAgent = Mojo::UserAgent -> new();
my $request = $userAgent -> get($endpoint, {Authorization => "Bearer $token"}) -> result();
my $userAgent = Mojo::UserAgent->new();
my $request = $userAgent->get($endpoint, {Authorization => "Bearer $token"})->result();

if ($request -> code() == 200) {
my $data = $request -> json();
if ($request->code() == 200) {
my $data = $request->json();
my $open_alerts = 0;
my @alert_details;

foreach my $alert (@$data) {
if ($alert -> {state} eq "open") {
if ($alert->{state} eq "open") {
$open_alerts++;

my $locations_endpoint = "https://api.github.com/repos/$repository/secret-scanning/alerts/$alert -> {number}/locations";
my $locations_request = $userAgent -> get($locations_endpoint, {Authorization => "Bearer $token"}) -> result();
my $locations_endpoint = "https://api.github.com/repos/$repository/secret-scanning/alerts/" . $alert->{number} . "/locations";
my $locations_request = $userAgent->get($locations_endpoint, {Authorization => "Bearer $token"})->result();

if ($locations_request -> code() == 200) {
my $locations = $locations_request -> json();
if ($locations_request->code() == 200) {
my $locations = $locations_request->json();

push @alert_details, {
alert_number => $alert -> {number},
alert_number => $alert->{number},
locations => $locations,
};
}
}
}

print "[!] Total of open secret scanning alerts: $open_alerts\n";
print "\n[!] Total of open secret scanning alerts: $open_alerts\n\n";

foreach my $detail (@alert_details) {
print "[-] Alert " . $detail -> {alert_number} . " found in the following locations:\n";
print "[-] Alert " . $detail->{alert_number} . " found in the following locations:\n";

foreach my $location (@{$detail -> {locations}}) {
print " File: " . $location -> {path} . ", Start line: " . $location -> {start_line} . "\n";
foreach my $location (@{$detail->{locations}}) {
my $file_path = $location->{details}->{path} // 'Unknown file';
my $start_line = $location->{details}->{start_line} // 'Unknown line';

print " File: $file_path, Start line: $start_line\n";
}
}

my $threshold = $severity_limits -> {high};
print "\n";

my $threshold = $severity_limits->{high};
if ($open_alerts > $threshold) {
print "[+] More than $threshold secret scanning alerts found. Blocking pipeline.\n";
return 1;
Expand All @@ -57,7 +62,7 @@ package SecurityGate::Engine::Secrets {
}

else {
print "Error: Unable to fetch secret scanning alerts. HTTP status code: " . $request -> code() . "\n";
print "Error: Unable to fetch secret scanning alerts. HTTP status code: " . $request->code() . "\n";
return 1;
}
}
Expand Down
20 changes: 5 additions & 15 deletions security-gate.pl
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,13 @@ sub main {
my $result = 0;

my %alert_checks = (
'dependency-alerts' => sub { SecurityGate::Engine::Dependencies -> new($token, $repository, \%severity_limits) },
'secret-alerts' => sub { SecurityGate::Engine::Secrets -> new($token, $repository, \%severity_limits) },
'code-alerts' => sub { SecurityGate::Engine::Code -> new($token, $repository, \%severity_limits) }
'dependency-alerts' => $dependency_alerts ? sub { SecurityGate::Engine::Dependencies->new($token, $repository, \%severity_limits) } : undef,
'secret-alerts' => $secret_alerts ? sub { SecurityGate::Engine::Secrets->new($token, $repository, \%severity_limits) } : undef,
'code-alerts' => $code_alerts ? sub { SecurityGate::Engine::Code->new($token, $repository, \%severity_limits) } : undef
);

for my $alert_type (keys %alert_checks) {
if ($alert_type eq 'dependency-alerts' && $dependency_alerts) {
$result += $alert_checks{$alert_type}->();
}

elsif ($alert_type eq 'secret-alerts' && $secret_alerts) {
$result += $alert_checks{$alert_type}->();
}

elsif ($alert_type eq 'code-alerts' && $code_alerts) {
$result += $alert_checks{$alert_type}->();
}
for my $check (grep { defined } values %alert_checks) {
$result += $check->();
}

return $result;
Expand Down

0 comments on commit d35a39a

Please sign in to comment.