Skip to content

Commit

Permalink
Added support to filter findings based on created_at and `updated_a…
Browse files Browse the repository at this point in the history
…t` column value provided in query parameter in the table aws_securityhub_finding Closes #2295 (#2298)
  • Loading branch information
ParthaI authored Nov 25, 2024
1 parent 816d316 commit c695110
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 26 deletions.
54 changes: 54 additions & 0 deletions aws/table_aws_securityhub_finding.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package aws
import (
"context"
"strings"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/securityhub"
Expand Down Expand Up @@ -45,6 +46,8 @@ func tableAwsSecurityHubFinding(_ context.Context) *plugin.Table {
{Name: "verification_state", Require: plugin.Optional, Operators: []string{"=", "<>"}},
{Name: "workflow_status", Require: plugin.Optional, Operators: []string{"=", "<>"}},
{Name: "source_account_id", Require: plugin.Optional, Operators: []string{"=", "<>"}},
{Name: "created_at", Require: plugin.Optional, Operators: []string{"=", ">=", ">", "<=", "<"}},
{Name: "updated_at", Require: plugin.Optional, Operators: []string{"=", ">=", ">", "<=", "<"}},
},
IgnoreConfig: &plugin.IgnoreConfig{
ShouldIgnoreErrorFunc: shouldIgnoreErrors([]string{"InvalidAccessException"}),
Expand Down Expand Up @@ -406,9 +409,60 @@ func getSecurityHubFinding(ctx context.Context, d *plugin.QueryData, _ *plugin.H
func buildListFindingsParam(quals plugin.KeyColumnQualMap) *types.AwsSecurityFindingFilters {
securityFindingsFilter := &types.AwsSecurityFindingFilters{}
strFilter := types.StringFilter{}
dateFilter := types.DateFilter{}
timeFormat := "2006-01-02T15:04:05Z"

strColumns := []string{"company_name", "compliance_status", "generator_id", "product_arn", "product_name", "record_state", "title", "verification_state", "workflow_state", "workflow_status", "source_account_id"}

timeColumns := []string{"created_at", "updated_at"}

for _, t := range timeColumns {
if quals[t] == nil {
continue
}
for _, q := range quals[t].Quals {
value := q.Value.GetTimestampValue().AsTime().Format(timeFormat)
if value == "" {
continue
}

switch q.Operator {
case "=", ">=", ">":
dateFilter.Start = &value
dateFilter.End = aws.String(time.Now().Format(timeFormat))
case "<", "<=":
dateFilter.End = &value
st, err := time.Parse(timeFormat, value)
if err != nil {
panic("failed to parsing provided value " + value + " for " + t)
}
if t == "updated_at" {
// Default to past 90 days.
// https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-findings.html
dateFilter.Start = aws.String(st.AddDate(0, 0, -90).Format(timeFormat))
} else {
// For the query "select * from aws_securityhub_finding where created_at <= current_timestamp - interval '31d'", we are setting the end time based on the query parameter.
// The query doesn't explicitly mention a start date for the creation time.
// AWS retains Security Hub findings updated within the last 90 days, regardless of when they were created.
// There is no strict limit for the creation start time, but we have set it to the date when AWS introduced SecurityHub. The API will return an error if we will not set the Start anf End time all together.
findingIntroduceTime := "2018-11-27T00:00:00Z"
t, err := time.Parse(timeFormat, findingIntroduceTime)
if err != nil {
panic("failed to parse the introduced securityhub findings time")
}
dateFilter.Start = aws.String(t.Format(timeFormat))
}

}
}
switch t {
case "created_at":
securityFindingsFilter.CreatedAt = []types.DateFilter{dateFilter}
case "updated_at":
securityFindingsFilter.UpdatedAt = []types.DateFilter{dateFilter}
}
}

for _, s := range strColumns {
if quals[s] == nil {
continue
Expand Down
116 changes: 90 additions & 26 deletions docs/tables/aws_securityhub_finding.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ from
aws_securityhub_finding
where
severity ->> 'Original' = 'CRITICAL'
and
and
created_at >= now() - interval '10' day;
```

Expand All @@ -177,7 +177,7 @@ from
aws_securityhub_finding
where
json_extract(severity, '$.Original') = 'CRITICAL'
and
and
created_at >= datetime('now', '-10 day');
```

Expand All @@ -192,7 +192,7 @@ select
criticality
from
aws_securityhub_finding
order by
order by
criticality desc nulls last;
```

Expand All @@ -204,7 +204,7 @@ select
criticality
from
aws_securityhub_finding
order by
order by
case when criticality is null then 1 else 0 end, criticality desc;
```

Expand All @@ -220,7 +220,7 @@ select
company_name
from
aws_securityhub_finding
where
where
company_name = 'Turbot';
```

Expand All @@ -233,7 +233,7 @@ select
company_name
from
aws_securityhub_finding
where
where
company_name = 'Turbot';
```

Expand Down Expand Up @@ -276,7 +276,7 @@ select
workflow_status
from
aws_securityhub_finding
where
where
workflow_status = 'NOTIFIED';
```

Expand All @@ -289,7 +289,7 @@ select
workflow_status
from
aws_securityhub_finding
where
where
workflow_status = 'NOTIFIED';
```

Expand All @@ -310,7 +310,7 @@ select
network ->> 'SourcePort' as network_source_port
from
aws_securityhub_finding
where
where
title = 'EC2 instance involved in SSH brute force attacks.';
```

Expand All @@ -328,7 +328,7 @@ select
json_extract(network, '$.SourcePort') as network_source_port
from
aws_securityhub_finding
where
where
title = 'EC2 instance involved in SSH brute force attacks.';
```

Expand All @@ -352,7 +352,7 @@ select
patch_summary ->> 'RebootOption' as reboot_option
from
aws_securityhub_finding
where
where
title = 'EC2 instance involved in SSH brute force attacks.';
```

Expand All @@ -373,7 +373,7 @@ select
json_extract(patch_summary, '$.RebootOption') as reboot_option
from
aws_securityhub_finding
where
where
title = 'EC2 instance involved in SSH brute force attacks.';
```

Expand All @@ -396,7 +396,7 @@ select
from
aws_securityhub_finding,
jsonb_array_elements(vulnerabilities) as v
where
where
title = 'EC2 instance involved in SSH brute force attacks.';
```

Expand All @@ -416,7 +416,7 @@ select
from
aws_securityhub_finding,
json_each(vulnerabilities) as v
where
where
title = 'EC2 instance involved in SSH brute force attacks.';
```

Expand Down Expand Up @@ -496,65 +496,65 @@ order by
Explore which findings are associated with the CIS AWS foundations benchmark in your AWS Security Hub. This can assist in identifying potential security risks or non-compliance issues for your company.

```sql+postgres
select
select
title,
id,
company_name,
created_at,
criticality,
confidence
from
from
aws_securityhub_finding
where
where
standards_control_arn like '%cis-aws-foundations-benchmark%';
```

```sql+sqlite
select
select
title,
id,
company_name,
created_at,
criticality,
confidence
from
from
aws_securityhub_finding
where
where
standards_control_arn like '%cis-aws-foundations-benchmark%';
```

### List findings for a particular standard control (Config.1)
Identify instances where specific security findings are associated with a particular standard control. This is beneficial in understanding the security posture of your organization by analyzing the criticality and confidence of the findings.

```sql+postgres
select
select
f.title,
f.id,
f.company_name,
f.created_at,
f.criticality,
f.confidence
from
from
aws_securityhub_finding as f,
aws_securityhub_standards_control as c
where
where
c.arn = f.standards_control_arn
and
c.control_id = 'Config.1';
```

```sql+sqlite
select
select
f.title,
f.id,
f.company_name,
f.created_at,
f.criticality,
f.confidence
from
from
aws_securityhub_finding as f,
aws_securityhub_standards_control as c
where
where
c.arn = f.standards_control_arn
and
c.control_id = 'Config.1';
Expand Down Expand Up @@ -709,4 +709,68 @@ group by
source_account_id
order by
source_account_id;
```

### Retrieve findings updated within a specific time range
This query retrieves AWS Security Hub findings that were updated within a specified time interval. It provides details such as the ID, company name, the first time the finding was observed, the last update time, criticality, and verification state.

```sql+postgres
select
id,
company_name,
first_observed_at,
updated_at,
criticality,
verification_state
from
aws_securityhub_finding
where
updated_at between '2023-06-26T13:00:21+05:30' and '2024-07-04T14:45:00+05:30';
```

```sql+sqlite
select
id,
company_name,
first_observed_at,
updated_at,
criticality,
verification_state
from
aws_securityhub_finding
where
updated_at between '2023-06-26T13:00:21+05:30' and '2024-07-04T14:45:00+05:30';
```

### List findings that are created in the last month
This query is useful for retrieving security findings from AWS Security Hub that were created within the last 30 days. It allows you to filter and monitor findings based on their creation date, helping identify recent security issues, assess compliance status, and track product-specific incidents. This can be particularly valuable for auditing, incident response, or compliance reporting, ensuring you're working with the most recent data.

```sql+postgres
select
id,
company_name,
created_at,
confidence,
compliance_status,
product_name,
product_arn
from
aws_securityhub_finding
where
created_at >= now() - interval '30d';
```

```sql+sqlite
select
id,
company_name,
created_at,
confidence,
compliance_status,
product_name,
product_arn
from
aws_securityhub_finding
where
created_at >= datetime('now', '-30 days');
```

0 comments on commit c695110

Please sign in to comment.