Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions docs/security/accepted-findings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# AWS Security Hub Accepted Findings

This document tracks AWS Security Hub findings that have been evaluated and accepted as false positives or intentional design decisions for this project.

## Accepted Findings

### CloudFront.1: CloudFront distributions should have a default root object configured

**Severity:** HIGH
**Status:** Accepted (False Positive)
**Date Evaluated:** 2025-11-25

#### Description
AWS Security Hub recommends that CloudFront distributions have a default root object configured to prevent exposing S3 bucket contents when users access the root URL.

#### Why This Is Accepted
This control **does not apply** to our CloudFront distribution because:

1. **Not an S3 Origin**: Our CloudFront distribution uses an Application Load Balancer (ALB) custom origin, not an S3 origin. The security risk this control addresses—exposing S3 bucket directory listings—is not present in our architecture.

2. **Dynamic Application**: We serve a Next.js application that handles routing dynamically. Setting a `default_root_object` interferes with the application's client-side routing for subdirectories (e.g., `/search`, `/opportunities`).

3. **No Content Exposure Risk**: When users access the root URL, requests are forwarded to our ALB and handled by the Next.js application. There is no risk of exposing backend file structures or bucket contents.

#### Configuration
```terraform
# infra/modules/service/cdn.tf
resource "aws_cloudfront_distribution" "cdn" {
# No default_root_object configured - intentional for ALB origin
enabled = true

dynamic "origin" {
for_each = var.enable_alb_cdn ? [1] : []
content {
domain_name = local.origin_domain_name
origin_id = local.default_origin_id
custom_origin_config { # ALB custom origin, not S3
origin_protocol_policy = "http-only"
# ...
}
}
}
}
```

#### References
- [AWS Security Hub CloudFront Controls](https://docs.aws.amazon.com/securityhub/latest/userguide/cloudfront-controls.html)
- This control specifically targets S3 origins and does not apply to custom origins

---

### ECS.5: ECS containers should be limited to read-only access to root filesystems

**Severity:** HIGH
**Status:** Accepted (Operational Requirement)
**Date Evaluated:** 2025-11-24

#### Description
AWS Security Hub recommends that ECS containers use read-only root filesystems to limit attack surface.

#### Why This Is Accepted
Fluent Bit containers require write access to the filesystem for:
- Writing log buffer files during log aggregation
- Managing temporary state for log forwarding
- Handling log rotation and buffering

This is a documented operational requirement for log aggregation sidecars.

#### Affected Resources
- Fluent Bit log aggregation containers in ECS task definitions

#### Mitigation
- Fluent Bit containers run with minimal privileges
- Write access is limited to specific directories needed for log processing
- Container isolation prevents impact to application containers

---

## Review Process

All Security Hub findings should be:
1. Investigated to determine if remediation is possible
2. Fixed if the security concern is valid and applicable
3. Documented here if accepted as false positive or operational requirement
4. Reviewed periodically (at least quarterly) to ensure the justification remains valid
65 changes: 65 additions & 0 deletions infra/accounts/guardduty.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#===================================
# GuardDuty
#===================================

# Import existing GuardDuty detector
# To import: terraform import aws_guardduty_detector.main 94c62cc0d4fe7b2eb627a33e8273238c
resource "aws_guardduty_detector" "main" {
#checkov:skip=CKV2_AWS_3:Member account in AWS Organization - org-level GuardDuty managed by administrator account 215331682793
enable = true
finding_publishing_frequency = "SIX_HOURS"

datasources {
s3_logs {
enable = true
}
kubernetes {
audit_logs {
enable = true
}
}
malware_protection {
scan_ec2_instance_with_findings {
ebs_volumes {
enable = true
}
}
}
}
}

# GuardDuty.7: Enable EKS Runtime Monitoring
# This enables GuardDuty to monitor EKS runtime activity
resource "aws_guardduty_detector_feature" "eks_runtime_monitoring" {
detector_id = aws_guardduty_detector.main.id
name = "EKS_RUNTIME_MONITORING"
status = "ENABLED"

additional_configuration {
name = "EKS_ADDON_MANAGEMENT"
status = "ENABLED"
}
}

# GuardDuty.11: Enable Runtime Monitoring
# This enables GuardDuty to monitor ECS Fargate, EKS, and EC2 runtime activity
resource "aws_guardduty_detector_feature" "runtime_monitoring" {
detector_id = aws_guardduty_detector.main.id
name = "RUNTIME_MONITORING"
status = "ENABLED"

additional_configuration {
name = "ECS_FARGATE_AGENT_MANAGEMENT"
status = "ENABLED"
}

additional_configuration {
name = "EKS_ADDON_MANAGEMENT"
status = "ENABLED"
}

additional_configuration {
name = "EC2_AGENT_MANAGEMENT"
status = "ENABLED"
}
}
15 changes: 15 additions & 0 deletions infra/accounts/inspector.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#===================================
# Amazon Inspector
#===================================

# Enable Amazon Inspector for EC2, ECR, Lambda Code, and Lambda Standard scanning
# This addresses Inspector.1, Inspector.2, Inspector.3, and Inspector.4 findings
resource "aws_inspector2_enabler" "main" {
account_ids = [data.aws_caller_identity.current.account_id]
resource_types = ["EC2", "ECR", "LAMBDA", "LAMBDA_CODE"]
}

# Note: Inspector findings may show as FAILED in multi-account environments
# if the organization's delegated administrator has not enabled Inspector
# for all member accounts. This resource ensures Inspector is enabled for
# this specific account.
10 changes: 10 additions & 0 deletions infra/accounts/ssm.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#===================================
# AWS Systems Manager (SSM)
#===================================

# SSM.7: Block public sharing of SSM documents
# This prevents SSM documents from being shared publicly
resource "aws_ssm_service_setting" "block_public_sharing" {
setting_id = "arn:aws:ssm:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:servicesetting/ssm/documents/console/public-sharing-permission"
setting_value = "Disable"
}