OpenSearch Service (formerly Elasticsearch Service) provides managed search and analytics. Often contains logs, application data, and business intelligence. Public dashboards are a common finding.
Clusters of instances storing indexed data. Access controlled by domain access policies, fine-grained access control (FGAC), or VPC placement. Contains searchable application data.
Attack note: Many domains have public access policies or weak FGAC. Check for Principal: * in access policies.
Web UI for visualizing and querying data. Often publicly accessible with weak or no auth. Provides Dev Tools console for direct query execution.
Attack note: Public Kibana with anonymous access is extremely common. Dev Tools allows arbitrary queries.
OpenSearch domains often contain sensitive logs, PII, financial data, and application secrets. Public dashboards and overly permissive access policies are extremely common misconfigurations.
aws opensearch list-domain-namesaws opensearch describe-domain \
--domain-name my-domainaws opensearch describe-domain \
--domain-name my-domain \
--query 'DomainStatus.AccessPolicies'aws opensearch describe-domain \
--domain-name my-domain \
--query 'DomainStatus.VPCOptions'curl -X GET 'https://domain.region.es.amazonaws.com/_cat/indices?v'Quick wins: Search for "password", "api_key", "secret", "token" across all indices.
curl -s 'https://DOMAIN/_cat/indices?v&s=index'curl -s 'https://DOMAIN/INDEX/_mapping' | jqcurl -s -X POST 'https://DOMAIN/_search' \
-H 'Content-Type: application/json' \
-d '{"query":{"query_string":{"query":"password OR secret OR api_key"}}}'curl -s -X POST 'https://DOMAIN/INDEX/_search?scroll=1m' \
-H 'Content-Type: application/json' \
-d '{"size":10000,"query":{"match_all":{}}}'curl -X DELETE 'https://DOMAIN/INDEX'curl -X PUT 'https://DOMAIN/_snapshot/my-repo/backup-1' \
-H 'Content-Type: application/json' \
-d '{"indices":"*","include_global_state":true}'{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": "*",
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:123456789012:domain/my-domain/*"
}]
}Anyone on the internet can access and modify the domain
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:role/AppRole"},
"Action": ["es:ESHttpGet", "es:ESHttpPost"],
"Resource": "arn:aws:es:us-east-1:123456789012:domain/my-domain/*"
}]
}
// Combined with VPC deploymentOnly specific IAM role can access, limited to read/search operations
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": "*",
"Action": "es:*",
"Resource": "*",
"Condition": {
"IpAddress": {"aws:SourceIp": "203.0.113.0/24"}
}
}]
}IP restriction but no authentication - anyone from that IP range has full access
Fine-Grained Access Control (FGAC):
- Internal database enabled
- Master user with strong password
- Index-level permissions
- Document-level security
- Field-level security
- Audit logging enabledFGAC provides granular, user-based access control
Place OpenSearch domain in private subnets, use VPC endpoints for access.
aws opensearch update-domain-config \
--domain-name my-domain \
--vpc-options SubnetIds=subnet-xxx,SecurityGroupIds=sg-xxxEnable FGAC with strong master user and role-based access.
AdvancedSecurityOptions:
Enabled: true
InternalUserDatabaseEnabled: true
MasterUserOptions:
MasterUserName: adminSend audit logs to CloudWatch for monitoring and alerting.
aws opensearch update-domain-config \
--log-publishing-options "AUDIT_LOGS={CloudWatchLogsLogGroupArn=arn,Enabled=true}"Require IAM credentials for all API requests.
Never allow anonymous access to OpenSearch Dashboards.
Enable encryption at rest (KMS) and in transit (TLS).
EncryptionAtRestOptions:
Enabled: true
KmsKeyId: arn:aws:kms:...:key/xxx
NodeToNodeEncryptionOptions:
Enabled: trueAWS OpenSearch Security Card • Toc Consulting
Always obtain proper authorization before testing