As machine learning and artificial intelligence use continue to grow in conversation-based applications, it’s important to note trends emerging. I have noticed something that has been popping up in greater frequency the more I dive deeper into integrations with Software as a Service (SaaS) offerings, but it is amplified more so with Communication Platforms as a Service (CPaaS) projects. What is this trend I speak of? It’s the trend of pushing more business logic or rules into the client side for applications. This phenomenon or application style is also commonly referred to as Thick Clients.
Thick clients are making a comeback, which is a stark departure from older design patterns like Model-View-Controller (MVC) or the modern version of that, being Microservice architectures. There are (too) many reasons why these design patterns dominated implementations for decades and why Thin Clients, or clients focused on display artifacts only, became the predominant standard for applications.
With this current rise in the use of thick clients, I thought it might be an excellent opportunity to review the security implications of thick clients and maybe even look through the lens of penetration testing and things to watch out for.
# Improper Access Control: Locking Down Your App
Improper Access Control is one of the most common vulnerabilities that can be exploited in thick client applications. This vulnerability occurs when an application doesn’t properly limit access to sensitive data or functions. Hackers can take advantage of this by accessing data or performing actions they shouldn’t be able to access. Since, by definition, thick clients have more of the business logic available client side, these exploits become increasingly more common because the details of how your application functions are available for all to see.
Developers should ensure that access to sensitive data or functions is properly restricted based on user roles and permissions. This can be achieved by implementing role-based access control, where users are assigned roles determining what data and functions they can access. Developers should also ensure that any user input that controls access is appropriately validated to prevent tampering.
# Insecure Storage: Protect Your Data
Insecure storage is another vulnerability that can be exploited in thick client applications. This vulnerability occurs when an application doesn’t properly encrypt or secure the data that is being stored. Hackers can take advantage of this by accessing sensitive data, such as user credentials, held on the client side.
To mitigate this risk, developers should ensure that data is properly encrypted and stored in secure locations. This can be achieved by using strong encryption algorithms and secure storage mechanisms. Developers should also ensure that sensitive data is never stored in plain text and that encryption keys are properly managed.
This might even need to include encrypting sensitive information while being held in memory when the application is running! If you need to hold credentials or access tokens in memory to be used repeatedly throughout the lifecycle of your application, especially if this is a long-running process like a microservice, encrypt the information and decrypt when needed. There are many ways to scan your applications memory space in order to retrieve this information. Also, make sure the decrypted credentials or tokens are only used in stack memory if possible! It reduces your security footprint and helps to ensure the memory is released quicker.
# Variable and Response Manipulation: Don’t Let Hackers Control Your App
As we get down further in this article, the level of sophistication to pull off these attacks requires significantly more skill and knowledge on how software systems work and the architecture of the computers they run on. Make no mistake, there are a ton of people out there that understand security and how to exploit vulnerabilities.
Variable and response manipulation is another vulnerability that can be exploited in thick client applications. This vulnerability occurs when an application doesn’t properly validate input from users. Hackers can take advantage of this by manipulating variables or responses in order to gain access to sensitive data or perform unauthorized actions.
Developers should ensure that input is properly validated and responses appropriately sanitized. This can be achieved by implementing server-side validation of user input and ensuring that data received from the server is validated before being used. Additionally, mission-critical data, or data that can alter the behavior of your application, should never make its way to the client side at all… as in ever.
I could tell you stories about websites back in the day when you could have purchased things off the internet and name your own price. Like a computer printer for $1. By the way, hit me up in Slack or Twitter to reminisce about security failures you have witnessed. Those stories typically are unbelievable.
# Reverse Engineering: Keep Your Code Secure
Finally, one of the biggest risks to thick client applications is reverse engineering. Traditionally, this vulnerability occurs when hackers decompile or disassemble the code in order to discover vulnerabilities, but a more modern version of this type of attack is understanding the mindset of the individual(s) implementing the application (aka social engineering) and then exploiting it. Once vulnerabilities are discovered or can be deduced from predicting the developer’s next move, hackers can take advantage of them to gain unauthorized access to sensitive data or perform unauthorized actions.
These types of vulnerabilities are few and far between, but when these issues are found out in the wild, these tend to be the catastrophic ones. These ones affect users in the hundreds of thousands or cost the company millions of dollars to mitigate or fix because they are more architecture-related. If you are lucky, you get to avoid the lawsuit when this type of “oops” happens, and it’s contained to a couple of sleepless nights to produce a software patch to fix the problem. In the hardware world, this might be doing a tapeout again and spinning the hardware with a recall; when this happens, it’s potentially a “career-limiting” event.
For example in 2019, Facebook disclosed that two third-party Facebook app developers accidentally leaked over 540 million records related to users because a cache server did not implement proper security measures. Catastrophic indeed!
# Ok, So What Now?
This blog isn’t meant to bash Thick Clients, but rather call attention to what code is running on these Thick Clients, question whether that code should be executed in client space, and do the proper threat analysis on your project or application. I started to think about this a lot recently as I have seen an explosion of applications using frameworks (such as Angular, Vue, etc) where projects were implementing all of their business logic entirely on the client; effectively making these applications only a Thick Client.
You could always make the argument that if safety is the only concern, the safest thing to do in EVERY situation is to limit your security footprint and push as much code and processing of data as you can onto your backend servers. This would then place more development efforts into creating clearly defined interfaces, implementing RBAC, etc. Ultimately, turning your client into your traditional Thin Client used for display only (aka the “View” in the MVC pattern).
Having said that, not all applications have these massive implications if a breach exists. Pushing all of this logic into the backend can be extremely expensive due to requiring server infrastructure and even paying for the expertise of skilled backend developers. Even things like time to market might take all of the priority because this project is just a proof of concept or it’s for demo purposes only. Traditionally, it’s been significantly easier to implement client-only applications/code. So there are nuances in application development that need to be considered.
By the way, if you are looking to implement a conversation-based application and want to do it with enterprise security in mind, then you should take a look at our Enterprise Architecture Implementation Project in GitHub as a blueprint and implementation that you can repurpose for your own application! It turns out that design and implementation for that project pushes all audio stream processing server side, all conversation analytics on the backend, and sends application-level display only messages to the client. Reusing this project will cut down on implementation time, effort, costs, and give you that blueprint to implement your application securely!
To wrap this all up, I think about security a lot. Too much, in fact. Just this past week, a couple of my neighbors had break-ins to their garages and things were stolen. I have several security measures in place because my area is high in theft. So my garage has honeypots, structural door reinforcements, security screws/nuts have been used in key locations, etc., to name some of my security measures. The recent break-ins got me wondering what else can I do to turn my garage into a Home Alone booby trap situation (admittedly, a lot of it for my own amusement). The point is just because you aren’t thinking about securing your stuff, doesn’t mean someone else isn’t trying to figure out how to get in.
Until next time, cheers!