Ensure No EC2 Instances Allow Ingress from the Internet to TCP Port 1433 or 1434 (SQL Server)
Overview
This check identifies EC2 instances whose security groups allow unrestricted inbound traffic on TCP ports 1433 or 1434 from the internet (0.0.0.0/0 or ::/0). Port 1433 is the default port for SQL Server database connections, while port 1434 is used by the SQL Server Browser service. Exposing these ports publicly is a critical security risk.
Risk
Exposing SQL Server ports to the internet creates serious attack vectors:
- Brute force attacks: Attackers can attempt thousands of password combinations against database logins
- SQL injection exploitation: Publicly exposed databases become targets for SQL injection attacks
- Data exfiltration: Unauthorized access can lead to theft of sensitive data stored in the database
- Ransomware deployment: Attackers can encrypt database contents and demand ransom
- Remote code execution: SQL Server vulnerabilities can be exploited to run malicious code on the host
- Lateral movement: Once inside, attackers can use the database server to pivot to other resources
This is rated as a critical severity finding because internet-exposed databases are prime targets for threat actors seeking sensitive data.
Remediation Steps
Prerequisites
You need permission to modify EC2 security groups in your AWS account. If you plan to restrict SQL Server access to specific IP addresses, have those IP ranges ready (e.g., your application servers or corporate network).
Setting up AWS CLI (optional)
If you prefer using the command line, ensure you have the AWS CLI installed and configured:
# Verify AWS CLI is installed
aws --version
# Configure credentials if needed
aws configure
# Verify access
aws sts get-caller-identity
AWS Console Method
- Open the EC2 Console in us-east-1
- In the left navigation, click Instances
- Select the affected EC2 instance
- Click the Security tab at the bottom of the page
- Click the security group link under Security groups
- Click Edit inbound rules
- Find any rule with:
- Type: MSSQL (or Custom TCP with port 1433 or 1434)
- Source: 0.0.0.0/0 or ::/0
- Either:
- Delete the rule by clicking the X button (if external access is not needed), or
- Restrict the source to a specific IP or CIDR block (e.g., your application server's security group or private subnet CIDR)
- Click Save rules
Important: Databases should never be directly accessible from the internet. Place SQL Server instances in private subnets and use a bastion host, VPN, or AWS Systems Manager Session Manager for administrative access.
AWS CLI (optional)
Step 1: Identify the security group with the exposed rule
# Find security groups allowing SQL Server port 1433 from anywhere
aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=1433" \
"Name=ip-permission.to-port,Values=1433" \
"Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query 'SecurityGroups[*].[GroupId,GroupName]' \
--output table
# Also check port 1434 (SQL Server Browser)
aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=1434" \
"Name=ip-permission.to-port,Values=1434" \
"Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query 'SecurityGroups[*].[GroupId,GroupName]' \
--output table
Step 2: Remove the overly permissive rules
# Remove the rule allowing SQL Server port 1433 from anywhere (IPv4)
aws ec2 revoke-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 1433 \
--cidr 0.0.0.0/0
# Remove IPv6 rule for port 1433 if present
aws ec2 revoke-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 1433 \
--cidr ::/0
# Remove the rule allowing SQL Server Browser port 1434 from anywhere (IPv4)
aws ec2 revoke-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 1434 \
--cidr 0.0.0.0/0
# Remove IPv6 rule for port 1434 if present
aws ec2 revoke-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 1434 \
--cidr ::/0
Step 3 (optional): Add a restricted rule if SQL Server access is still needed
# Add SQL Server access from a specific security group (recommended)
aws ec2 authorize-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 1433 \
--source-group <APP_SERVER_SECURITY_GROUP_ID>
# Or add access from a specific trusted CIDR (private subnet)
aws ec2 authorize-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 1433 \
--cidr <YOUR_PRIVATE_SUBNET_CIDR>
Replace <SECURITY_GROUP_ID> with your security group ID (e.g., sg-0123456789abcdef0), <APP_SERVER_SECURITY_GROUP_ID> with your application server's security group, and <YOUR_PRIVATE_SUBNET_CIDR> with your private subnet CIDR (e.g., 10.0.1.0/24).
CloudFormation (optional)
Use this template to create a security group with properly restricted SQL Server access:
AWSTemplateFormatVersion: '2010-09-09'
Description: Security group with restricted SQL Server access
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC ID where the security group will be created
AppServerSecurityGroupId:
Type: AWS::EC2::SecurityGroup::Id
Description: Security group ID of the application servers that need database access
Resources:
RestrictedSQLServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group with restricted SQL Server access
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 1433
ToPort: 1433
SourceSecurityGroupId: !Ref AppServerSecurityGroupId
Description: SQL Server access from application servers only
Tags:
- Key: Name
Value: restricted-sqlserver-sg
Outputs:
SecurityGroupId:
Description: ID of the security group
Value: !Ref RestrictedSQLServerSecurityGroup
Deploy the stack:
aws cloudformation deploy \
--region us-east-1 \
--stack-name restricted-sqlserver-sg \
--template-file template.yaml \
--parameter-overrides VpcId=<YOUR_VPC_ID> AppServerSecurityGroupId=<APP_SERVER_SG_ID>
Terraform (optional)
variable "vpc_id" {
description = "VPC ID where the security group will be created"
type = string
}
variable "app_server_security_group_id" {
description = "Security group ID of the application servers that need database access"
type = string
}
resource "aws_security_group" "restricted_sqlserver" {
name = "restricted-sqlserver-sg"
description = "Security group with restricted SQL Server access"
vpc_id = var.vpc_id
ingress {
description = "SQL Server access from application servers only"
from_port = 1433
to_port = 1433
protocol = "tcp"
security_groups = [var.app_server_security_group_id]
}
tags = {
Name = "restricted-sqlserver-sg"
}
}
output "security_group_id" {
description = "ID of the security group"
value = aws_security_group.restricted_sqlserver.id
}
Apply the configuration:
terraform init
terraform apply -var="vpc_id=<YOUR_VPC_ID>" -var="app_server_security_group_id=<APP_SERVER_SG_ID>"
Verification
After making changes, verify the fix in the AWS Console:
- Go to EC2 > Security Groups
- Select your security group
- Check the Inbound rules tab
- Confirm there are no rules allowing port 1433 or 1434 from 0.0.0.0/0 or ::/0
CLI verification commands
# Verify no security groups allow SQL Server port 1433 from anywhere
aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=1433" \
"Name=ip-permission.to-port,Values=1433" \
"Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query 'SecurityGroups[*].GroupId' \
--output text
# Verify no security groups allow SQL Server Browser port 1434 from anywhere
aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.from-port,Values=1434" \
"Name=ip-permission.to-port,Values=1434" \
"Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query 'SecurityGroups[*].GroupId' \
--output text
# Both should return empty if properly remediated
You can also re-run the Prowler check to confirm:
prowler aws --check ec2_instance_port_sqlserver_exposed_to_internet --region us-east-1
Additional Resources
- AWS Security Groups Documentation
- AWS Well-Architected Security Pillar
- AWS Database Migration Service - For migrating to AWS-managed databases
- Amazon RDS for SQL Server - Consider using managed database service
- Microsoft SQL Server Security Best Practices
Notes
- Service interruption: Removing SQL Server access rules will immediately disconnect any active database connections from affected sources. Coordinate with application teams before making changes.
- Private subnets: SQL Server instances should be placed in private subnets with no direct internet access. Use NAT gateways if outbound internet access is required.
- Consider managed services: AWS RDS for SQL Server or Azure SQL Database provide built-in security features and eliminate the need to manage infrastructure security.
- Encryption in transit: Enable TLS/SSL encryption for SQL Server connections to protect data in transit.
- Authentication: Use Windows Authentication or strong SQL Server authentication with complex passwords. Consider integrating with AWS Directory Service.
- Monitoring: Enable VPC Flow Logs, CloudTrail, and SQL Server audit logging to monitor for unauthorized access attempts.
- Port 1434 (SQL Server Browser): This port is used for dynamic port discovery. If not needed, disable the SQL Server Browser service entirely.