Skip to main content

Security Group Allows Ingress from Internet to MongoDB Ports

Overview

This check verifies that your EC2 security groups do not allow unrestricted inbound access from the internet (0.0.0.0/0 or ::/0) to MongoDB database ports 27017 and 27018.

MongoDB is a popular NoSQL database. If its ports are exposed to the entire internet, anyone can attempt to connect to your database. This is a critical security misconfiguration that should be fixed immediately.

Risk

Exposing MongoDB ports to the internet creates serious security risks:

  • Data theft: Attackers can access, copy, or exfiltrate your entire database
  • Ransomware: Attackers commonly encrypt exposed MongoDB databases and demand payment
  • Data destruction: Malicious actors may delete your data entirely
  • Unauthorized access: Without network-level protection, only database authentication stands between attackers and your data
  • Denial of Service: Attackers can overwhelm your database with connection attempts
  • Compliance violations: Most compliance frameworks (PCI-DSS, HIPAA, SOC 2) require databases to be isolated from direct internet access

MongoDB databases exposed to the internet have been frequently targeted in mass scanning attacks. This is considered a high severity finding.

Remediation Steps

Prerequisites

You need:

  • AWS Console access with permissions to modify security groups
  • Knowledge of which IP addresses or security groups legitimately need MongoDB access
Required IAM permissions

Your IAM user or role needs these permissions:

  • ec2:DescribeSecurityGroups
  • ec2:DescribeSecurityGroupRules
  • ec2:RevokeSecurityGroupIngress
  • ec2:AuthorizeSecurityGroupIngress

AWS Console Method

Step 1: Identify the Problematic Security Group

  1. Go to EC2 Console in us-east-1
  2. Click Security Groups in the left sidebar under "Network & Security"
  3. Look for security groups with inbound rules that have:
    • Port range: 27017, 27018, or a range including these ports
    • Source: 0.0.0.0/0 or ::/0 (meaning "anywhere")

Step 2: Remove the Dangerous Rule

  1. Select the security group with the problematic rule
  2. Click the Inbound rules tab
  3. Click Edit inbound rules
  4. Find the rule allowing 27017 or 27018 from 0.0.0.0/0 or ::/0
  5. Click Delete (the X button) next to that rule
  6. Click Save rules

Step 3: Add a Restricted Rule (if access is still needed)

If legitimate applications need MongoDB access, add a properly scoped rule:

  1. Click Edit inbound rules again
  2. Click Add rule
  3. Configure the rule:
    • Type: Custom TCP
    • Port range: 27017 (or 27017-27018 if both ports are needed)
    • Source: Choose one of these secure options:
      • A specific IP address (e.g., 10.0.1.50/32)
      • A CIDR block for your internal network (e.g., 10.0.0.0/16)
      • Another security group (select "Custom" and enter the security group ID)
  4. Click Save rules
AWS CLI (optional)

Find Security Groups with Exposed MongoDB Ports

List security groups that allow MongoDB access from anywhere:

aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=27017" "Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query 'SecurityGroups[*].[GroupId,GroupName]' \
--output table

Also check for IPv6:

aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=27017" "Name=ip-permission.ipv6-cidr,Values=::/0" \
--query 'SecurityGroups[*].[GroupId,GroupName]' \
--output table

Remove the Dangerous Rule

Revoke the rule allowing port 27017 from anywhere (replace <security-group-id> with your actual security group ID):

# Revoke IPv4 rule for port 27017
aws ec2 revoke-security-group-ingress \
--group-id <security-group-id> \
--protocol tcp \
--port 27017 \
--cidr 0.0.0.0/0 \
--region us-east-1

# Revoke IPv6 rule for port 27017
aws ec2 revoke-security-group-ingress \
--group-id <security-group-id> \
--protocol tcp \
--port 27017 \
--cidr ::/0 \
--region us-east-1

# Repeat for port 27018 if applicable
aws ec2 revoke-security-group-ingress \
--group-id <security-group-id> \
--protocol tcp \
--port 27018 \
--cidr 0.0.0.0/0 \
--region us-east-1

Add a Restricted Rule (if needed)

Add a rule allowing access only from a specific CIDR block:

aws ec2 authorize-security-group-ingress \
--group-id <security-group-id> \
--protocol tcp \
--port 27017 \
--cidr 10.0.0.0/16 \
--region us-east-1

Or allow access from another security group:

aws ec2 authorize-security-group-ingress \
--group-id <security-group-id> \
--protocol tcp \
--port 27017 \
--source-group <source-security-group-id> \
--region us-east-1
CloudFormation (optional)

This template creates a secure security group for MongoDB that only allows access from a specified CIDR block or security group:

AWSTemplateFormatVersion: '2010-09-09'
Description: Secure security group for MongoDB access (no internet exposure)

Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC where the security group will be created

AllowedCidr:
Type: String
Description: CIDR block allowed to access MongoDB (e.g., 10.0.0.0/16)
AllowedPattern: ^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$
ConstraintDescription: Must be a valid CIDR block (e.g., 10.0.0.0/16)
Default: 10.0.0.0/16

Resources:
MongoDBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: mongodb-secure-sg
GroupDescription: Security group for MongoDB - restricted access only
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 27017
ToPort: 27017
CidrIp: !Ref AllowedCidr
Description: MongoDB access from internal network only
- IpProtocol: tcp
FromPort: 27018
ToPort: 27018
CidrIp: !Ref AllowedCidr
Description: MongoDB shard access from internal network only
Tags:
- Key: Name
Value: mongodb-secure-sg
- Key: Purpose
Value: MongoDB database access

Outputs:
SecurityGroupId:
Description: ID of the MongoDB security group
Value: !Ref MongoDBSecurityGroup
Export:
Name: MongoDBSecurityGroupId

Deploy with:

aws cloudformation deploy \
--template-file mongodb-secure-sg.yaml \
--stack-name mongodb-security-group \
--parameter-overrides \
VpcId=vpc-xxxxxxxxx \
AllowedCidr=10.0.0.0/16 \
--region us-east-1

Important: After deploying this secure security group, update your MongoDB instances to use it and remove the old insecure security group.

Terraform (optional)
variable "vpc_id" {
description = "VPC ID where the security group will be created"
type = string
}

variable "allowed_cidr_blocks" {
description = "CIDR blocks allowed to access MongoDB"
type = list(string)
default = ["10.0.0.0/16"]
}

variable "allowed_security_group_ids" {
description = "Security group IDs allowed to access MongoDB"
type = list(string)
default = []
}

# Secure MongoDB security group - no internet access
resource "aws_security_group" "mongodb" {
name = "mongodb-secure-sg"
description = "Security group for MongoDB - restricted access only"
vpc_id = var.vpc_id

tags = {
Name = "mongodb-secure-sg"
Purpose = "MongoDB database access"
}
}

# Allow MongoDB access from specified CIDR blocks
resource "aws_security_group_rule" "mongodb_cidr" {
count = length(var.allowed_cidr_blocks) > 0 ? 1 : 0
type = "ingress"
from_port = 27017
to_port = 27018
protocol = "tcp"
cidr_blocks = var.allowed_cidr_blocks
security_group_id = aws_security_group.mongodb.id
description = "MongoDB access from allowed CIDR blocks"
}

# Allow MongoDB access from specified security groups
resource "aws_security_group_rule" "mongodb_sg" {
count = length(var.allowed_security_group_ids)
type = "ingress"
from_port = 27017
to_port = 27018
protocol = "tcp"
source_security_group_id = var.allowed_security_group_ids[count.index]
security_group_id = aws_security_group.mongodb.id
description = "MongoDB access from allowed security group"
}

output "security_group_id" {
description = "ID of the MongoDB security group"
value = aws_security_group.mongodb.id
}

output "security_group_arn" {
description = "ARN of the MongoDB security group"
value = aws_security_group.mongodb.arn
}

Deploy with:

terraform init
terraform plan -var="vpc_id=vpc-xxxxxxxxx"
terraform apply -var="vpc_id=vpc-xxxxxxxxx"

Important: After applying this configuration, update your MongoDB instances to use the new secure security group.

Verification

After making changes, verify the security group no longer allows internet access to MongoDB ports:

  1. Go to EC2 Console > Security Groups
  2. Select the security group you modified
  3. Click the Inbound rules tab
  4. Confirm there are no rules with:
    • Port 27017 or 27018 with source 0.0.0.0/0 or ::/0
CLI verification commands

Check if any security groups still have MongoDB ports open to the internet:

# Check for IPv4 exposure on port 27017
aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=27017" "Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query 'SecurityGroups[*].[GroupId,GroupName]' \
--output table

# Check for IPv4 exposure on port 27018
aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=27018" "Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query 'SecurityGroups[*].[GroupId,GroupName]' \
--output table

If the output is empty, no security groups have MongoDB ports exposed to the internet.

You can also re-run the Prowler check to confirm remediation:

prowler aws -c ec2_securitygroup_allow_ingress_from_internet_to_mongodb_ports -r us-east-1

Additional Resources

Notes

  • MongoDB default ports:

    • Port 27017: Standard MongoDB database connections
    • Port 27018: MongoDB shard server (shardsvr) connections
  • Check for active connections first: Before removing security group rules, verify what resources are using this security group and whether legitimate applications will be affected. You can see associated resources in the security group's "Associated resources" section.

  • Consider using AWS PrivateLink: For production MongoDB deployments, consider using AWS PrivateLink or VPC endpoints to ensure traffic never traverses the public internet.

  • Database authentication is not enough: Even if your MongoDB instance requires authentication, exposing it to the internet allows attackers to:

    • Attempt brute force attacks against credentials
    • Exploit any MongoDB vulnerabilities before patches are applied
    • Conduct denial of service attacks
  • Automated scanning is constant: Exposed MongoDB ports are discovered within hours by automated scanners. The 2017 MongoDB ransomware attacks affected over 27,000 databases that were exposed to the internet.

  • Use security groups as an allowlist: Always specify the minimum necessary source IP ranges or security groups. Start restrictive and expand access only when needed.

  • Monitor for changes: Consider setting up CloudWatch alarms to detect when security group rules are modified. See the cloudwatch_log_metric_filter_security_group_changes check for guidance.