AWS RDS does not force clients to connect using a secure transport layer
The AWS RDS service, by default, does not enable secure transport layer security, allowing clients to connect insecurely if they want to. This is a blogpost to look at its discovery, why this is a problem and what you can possibly do to mitigate it.
AWS RDS is a managed relational database service that allows users to rapidly set up fully operational instances on the cloud and use them as data sources within applications. The AWS RDS is one of the more popular services that AWS provides and has been a favourite amongst customers for having a wider range of Engine types to pick from.
Apart from the obvious benefits that AWS RDS has over conventional on premise databases, you don’t need to manage the underlying infrastructure. RDS can easily be set up to perform backups and can be configured to remain private or become available over the Internet.
AWS RDS Engine configurations are applied via a resource called Parameter group. These parameter groups are engine specific and contain settings that are pre-configured by AWS.
During a review of a MySQL RDS Engine, it was noticed that the security setting that forces RDS to only accept encrypted connections from clients was set to null while being unmodifiable. This blogpost takes a closer look at the setting and what you can do about it.
AWS RDS and Transport Layer Security
When you create a RDS instance in AWS, a parameter group is also created, if one hasn’t already been created for the specific Engine type.
Different Engine types have different settings that define how the database is set up, what character set the DB will use, where the log file will be, whether unsecured clients can connect or not, where the DB binary data is stored etc. Depending on the database engine type, some of these settings may not be available or may have a different variable name.
However, since AWS RDS is a managed service, some of these settings may not be modifiable, especially the ones that change filesystem access or location of resources on the underlying AWS managed machine.
One of the more security focused configurations is the setting that enforces transport layer security, essentially the setting that prevents clients from connecting unless the connection uses transport layer security.
Based on the kind of database engine, this setting is implemented via different variable names. For example, require_secure_transport in the case of MySQL, MariaDB and Aurora MySQL. However, the default value for this setting for ALL engine types within AWS RDS is either set to null or 0 which essentially disables this setting. What’s even worse is that, for the more commonly used MySQL and MariaDB RDS engine types, this setting cannot be enabled to ensure only secure clients connect.
Here’s a complete summary of all RDS Engine types in AWS.
What does this mean to attackers?
From an attacker point of view, this means that RDS does not enforce transport layer security allowing any client that can either disable transport layer security or does not support it all will be able to establish a successful connection.
We tried this with the mysql client with the following command, disabling transport layer security, and were able to connect successfully
mysql -u user -h aws-rds-host -p --ss-mode=DISABLED
While the connection was being established, we ran a Wireshark trace to see what we could see over the network. Wireshark shows us the packets that the MySQL client sent including the credentials, all handshake, data and commands being exchanged between client and server - showing that the connection did indeed occur over an unencrypted channel.
An attacker on a local network or an intermediary server, like an ISP, would be able to perform Man in the middle attacks and capture data, modify content or simply patch the request and response to invoke other functions. This also brings the requirement of “encryption of data in motion” to a grey area since the RDS can no longer enforce connection security with the client and it is upto the client to connect securely.
What does AWS say about this?
When we contacted AWS about this, they acknowledged that they are aware of this and this setting is disabled by default as there are various RDS configurations for customers including those that allow creation of database instances inside customers' VPCs so that they are not publicly accessible.
The AWS Security team added that at present, enabling encryption may cause customers to adjust the configuration of their existing applications; thus, setting ‘require_secure_transport=ON’ as a service default may adversely impact some customers. Also, allowing customers to modify the ‘require_secure_transport’ parameter is on RDS's roadmap but AWS could not say when this would be available for the general public.
How do you mitigate this and stay safe?
For most engine types, it is possible to enable this setting using the Parameter Groups resource type and by editing the values. For example, the following image shows the setting for rds.force_ssl being updated for the sqlserver-se-15 DB type.
As there is no way to currently modify the require_secure_transport option for the MySQL and MariaDB engine types, it is recommended that all clients connecting to these database instances must use secure connections. This is the default in all clients, however, this can easily be changed via command line or in code.
It is also a good security practice to keep the RDS inside a VPC away from the public Internet and to practice basic security hygiene like having strong passwords, keeping snapshots private and enabling encryption at rest for snapshots and the database itself.
When an AWS RDS instance is created, an appropriate parameter group is applied to the DB instance. These parameter groups contain settings for the database at the engine layer. During our research we discovered that the setting that enforces transport layer security is disabled on all database engine types with the ability to modify it also being absent for certain types of databases.
As AWS RDS cannot enforce clients to connect using a secure connection, it is possible for insecure clients to make a connection which could be attacked and data could be stolen or modified in transit. Although AWS RDS allows for the setting to be enabled on some engine types, in the case of MySQL and MariaDB there is no way to change the option at all. This makes enforcing client side security an even more important security measure.
ABOUT THE AUTHOR
Riyaz is a security evangelist, offensive security expert and researcher with over a decade of experience in the cyber security industry. His passion to break into some of the most well defended networks and systems in his career spanning 15 years has earned him a lot respect within the security industry. He has led Security Assessment and Penetration Testing teams at Pricewaterhouse Coopers (PwC) and Appsecco, and the Product Security Team at Citrix before co-founding Kloudle. Riyaz now specializes in cloud native, container and cloud security in general, helping build an easy to use security management platform to help companies enhance their visibility in the cloud, identify security misconfigurations and automate remediation for security gaps enabling compliance and operational security in multi-cloud environments. He is also an avid speaker and trainer and presents his research and findings at security conferences and community meetups around the world including BlackHat USA, BH Europe, BH Asia, nullcon and OWASP AppsecUSA.Specialties: Cloud (AWS, GCP, Azure, IBM, Others) Security, Cloud-Native Security, Kubernetes, Container Security, Web Application Security, Network and System Penetration Testing, Wireless Network Security, Malware Analysis and Reverse Engineering, Threat Modelling, Windows Forensics, Security Code Review, Vulnerability Research, Exploit Development and Reverse Engineering. Certifications: CKA, CKAD, OSCP
Enjoyed this read?
Subscribe to our newsletter and stay ahead with more great insights and resources on cloud security!
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.