This repository provides practical examples and code snippets aimed at helping Java developers implement security best practices. It covers key topics such as security design principles, authentication and authorization, API security, Java process security, common attack mitigations, and security testing - all essential for building secure Java applications.
These examples are designed to complement the curriculum of the đź“š Application Security for Java Developers Course.
If you're looking to take your skills to the next level, 🎓 enroll now and master the art of secure coding in Java!
For more resources and insights, feel free to visit my website.
- Security Concepts
- Project Modules
- Architectural Diagrams
- Technology Stack
- SetUp
- Security Checks
- License
Among the security concepts demonstrated in this project:
- Security Design Principles
- Least privilege
- Defense in depth
- Fail securely
- Compartmentalization
- OAuth 2.0 Grant Types:
- Password Flow
- Client Credentials Flow
- Authorization Code Flow
- Authorization Code Flow with Proof Key for Code Exchange (PKCE)
- API and Microservices Security
- Token introspection
- JSON Web Key Set (JWKS)
- Roles-based access control
- Java Process Security
- Input data validation and sanitization
- Handling input files from external sources
- Security logging best practices
- Content Security Policy (CSP)
- Cross-Origin Resource Sharing (CORS)
- HTTP security headers (e.g., Strict-Transport-Security, X-XSS-Protection, X-Frame-Options)
- Java deserialization
- Security Testing
- Software Composition Analysis (SCA)
- Static Application Security Testing (SAST)
- Dynamic Application Security Testing (DAST)
Below is a breakdown and description of each module in the current project.
Module | Description |
---|---|
pizza-order-* , pizza-cooking-* , pizza-delivery-* |
These modules represent 3 microservices and their APIs (Pizza Cooking, Delivery, and Order) that demonstrate various OAuth 2.0 flows (e.g., token introspection, JWKS, client credentials), roles-based access control and security logging concepts. |
security-feign-logger-enricher |
Enriches and enables standard Feign client logging with additional custom Mapped Diagnostic Context (MDC) attributes (e.g., correlation ID) using SLF4J's MDC. |
security-slf4j-logger-enricher |
Enriches SLF4J-based logging with security-specific attributes (e.g., remote host, remote port, user agent, request URI, request method, correlation ID) using SLF4J's MDC. |
security-token-client-credentials-fetcher |
Fetches tokens from the Identity Provider (IdP) using the client credentials flow. |
security-token-introspection |
Introspects and validates access tokens using the IdP's token introspection endpoint. Additionally, it disables security for specific /public endpoints (e.g., OpenAPI definition endpoint), configures CORS and Content Security Policy (CSP), adds HTTP security headers, and parses JWT claim roles, adding them as granted authorities. |
security-token-jwks |
Handles JSON Web Key Set (JWKS) validation and signature verification of JWT tokens using the IdP's JWKS endpoint. Additionally, it disables security for specific /public endpoints (e.g., OpenAPI definition endpoint) and parses JWT claim roles, adding them as granted authorities. |
serialization-deserialization |
Demonstrates security risks in serialization and deserialization, including exploits like Java class deserialization attacks, XML external entities, YAML bombs, and ZIP bombs. |
This software architecture diagram illustrates the microservices as components within the system and highlights key security aspects, including OAuth 2.0 flows (e.g., Token introspection, JWKS) and endpoint roles checks.
sequenceDiagram
actor User
User->>IdP: Authenticate and fetch JWT (authorization code flow)
User->>Pizza Order Service: Submit order with JWT as HTTP Bearer token
Pizza Order Service->>IdP: Introspect JWT to verify validity
Pizza Order Service->>Pizza Order Service: Check user roles/permissions
Pizza Order Service->>Pizza Cooking Service: Submit cooking order with JWT as HTTP Bearer token
Pizza Cooking Service->>IdP: Fetch JWKS keys (if missing or expired) for local JWT validation
Pizza Cooking Service->>Pizza Cooking Service: Validate JWT signature using JWKS
Pizza Cooking Service->>Pizza Cooking Service: Check user roles/permissions
Note right of Pizza Cooking Service: Pizza is cooked ...
Pizza Cooking Service->>IdP: Fetch JWT (client credentials flow)
Pizza Cooking Service->>Pizza Delivery Service: Submit delivery order with JWT as HTTP Bearer token
Pizza Delivery Service->>IdP: Fetch JWKS keys (if missing or expired) for local JWT validation
Pizza Delivery Service->>Pizza Delivery Service: Validate JWT signature using JWKS
Pizza Delivery Service->>Pizza Delivery Service: Check user roles/permissions
Pizza Delivery Service->>Pizza Delivery Service: Confirm order delivered
Pizza Delivery Service->>Pizza Order Service: Send order status update
Pizza Order Service->>IdP: Introspect JWT to verify validity
Pizza Order Service->>Pizza Order Service: Check user roles/permissions
Pizza Order Service->>Pizza Order Service: Update order status
This project includes the following technologies, frameworks, and libraries:
- Spring Boot
- Spotless as a code formatter
- Docker compose
- Keycloak as an Identity and Access Management solution
- OWASP Dependency-Check as a Software Composition Analysis (SCA) tool
- Spotbugs with FindSecBugs plugin as a Static Application Security Testing (SAST) tool
- The Zed Attack Proxy (ZAP) as a Dynamic Application Security Testing (DAST) tool
- OWASP WebGoat a deliberately insecure application
Please ensure you have properly downloaded, installed, and configured the following tools:
Tool | Link |
---|---|
JDK 21 | Download (i.e., latest LTS) |
Docker | Download |
Postman | Download |
curl command line |
Download |
jq command line |
Download |
The course is developed to work best on GNU/Linux. However, if you prefer to use a Windows machine, you can use one of the following alternatives to properly execute the bash scripts:
To compile the project, run tests, and package it, use the following command:
./mvnw clean package
Note: Please ensure that the Docker daemon is running; otherwise, the commands will not execute successfully.
-
Run the following command to start the
Keycloak
service in Docker:./bootstrap-keycloak.sh
-
To start the
Pizza
application, which includes multiple microservices running in Docker, execute:./bootstrap-pizza-application.sh
-
Next, run the following command to start the
OWASP WebGoat
application in Docker:./bootstrap-webgoat.sh
-
Finally, check that all Docker containers are up and running by executing:
docker ps -a
To set up a basic Keycloak configuration, run the following script:
./keycloak-init.sh
The script creates OAuth 2.0 clients, users, and roles under the master
realm and assigns the roles to the users:
Type | Name | Password | Purpose |
---|---|---|---|
User | demo_user |
Test1234! |
Used for authorization code flow with PKCE. |
Client ID | demo_public_client |
6EuUNXQzFmxu6xwPHDvvoh56z1uzrBMw |
Used for authorization code flow. |
Client ID | demo_private_client |
6EuUNXQzFmxu6xwPHDvvoh56z1uzrBMw |
Used for client credentials flow. |
This setup utilizes Keycloak's REST API to perform these operations and provides output at each step, ensuring efficient user and client management within the Keycloak environment.
Open a browser and navigate to http://localhost:9090 to access the Keycloak UI (using the credentials admin:admin
).
Open a browser and navigate to http://localhost:9090/realms/master/.well-known/openid-configuration to access the Keycloak OpenID Connect configuration.
Open a browser and navigate to http://localhost:18080/public/swagger-ui/index.html to access the Pizza Order OpenAPI definition.
Open a browser and navigate to http://localhost:28080/public/swagger-ui/index.html to access the Pizza Cooking OpenAPI definition.
Open a browser and navigate to http://localhost:38080/public/swagger-ui/index.html to access the Pizza Delivery OpenAPI definition.
Open a browser and navigate to http://localhost:48080/WebGoat/login to access the OWASP WebGoat UI.
- Open
Postman
and import the Postman collections. - To simulate a basic test scenario, follow these steps in the given sequence:
- a) Fetch the JWT token using either:
- The Password Flow:
POST http://localhost:9090/realms/master/protocol/openid-connect/token
- Or the Client Credentials Flow:
POST http://localhost:9090/realms/master/protocol/openid-connect/token
- Or the Authorization Code Flow with PKCE:
POST http://localhost:9090/realms/master/protocol/openid-connect/auth
- The Password Flow:
- b) Initiate an order request to the
pizza-order-service
:POST http://localhost:18080/pizza/orders
OWASP Dependency-Check is an open-source Software Composition Analysis (SCA) tool that identifies vulnerabilities in project dependencies, helping reveal and address known security risks.
To check for potential dependency vulnerabilities, execute the following command:
./mvnw clean compile org.owasp:dependency-check-maven:check
Note: The first run of this command might take a significant amount of time (e.g., from a couple of minutes to even tens of minutes, depending on the internet connection) to initially download the NVD Data Feeds hosted by NIST.
Spotbugs is an open-source static analysis tool that detects bugs in Java programs by analyzing bytecode.
With the help of the FindSecBugs plugin plugin, it can be used as a Static Application Security Testing (SAST) tool to identify security vulnerabilities in Java applications.
To check for potential code vulnerabilities, execute the following command:
./mvnw clean compile spotbugs:check
The Zed Attack Proxy (ZAP) is an open-source Dynamic Application Security Testing (DAST) tool specifically designed for identifying vulnerabilities in applications during runtime.
To check for API security vulnerabilities, execute the following command:
./zap-scan.sh
The command starts ZAP in Docker, launches an API scan using the zap-api-scan rules against one of the services, and saves the scan report in the ./zap/reports folder.
This project is licensed under the Apache License, Version 2.0.
Please see the LICENSE file for full license.
/*
* Application Security for Java Developers
*
* Copyright (C) 2024 Ionut Balosin
* Website: www.ionutbalosin.com
* X: @ionutbalosin | LinkedIn: ionutbalosin | Mastodon: [email protected]
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/