Technical input & supervision: Rafał Koguciuk
Web application development requires a holistic approach to cybersecurity that includes coding practices, authentication, encryption, monitoring, and proactive response strategies. Let’s explore fundamental principles of secure web application development for creating digital products that users can trust.
What are application security best practices? First and foremost, remember that potential attacks are carried out by very creative entities-your job is to anticipate the weaknesses of your application and build it to give them the least chance of successfully accessing or guessing the data. Second, remember that the weakest link is often a human being, so write your application to give users as few opportunities as possible to make simple mistakes that compromise the security of their data.
What practices will most effectively meet both of these conditions? For those who are short on time, the following table is a highlight of Java apps cybersecurity do’s and don’ts.
Cybersecurity best practices in developing a Java Web Application from scratch:
|Action/Challenge||Best Cybersecurity Practice|
|User Identification and Email Case-Sensitivity||Ensure email addresses are case-insensitive. Conceal email login from the frontend to prevent potential attacks.|
|Email Address Validation||Validate email addresses using RFC 5321 format. Employ Java’s Regular Expressions or annotations in Data Transfer Objects (DTOs).|
|Password Strength Verification||Validate password length (8-64 characters) and encourage diverse character usage.|
|Secure Password Storage||Abandon plaintext storage; employ hashing with salt and pepper. Opt for modern algorithms (Argon2id, bcrypt, PBKDF2).|
|Password Recovery||Return 200 HTTP Status Code for password reset request and implement asynchronous processing.|
|Secure Reset Link Generation||Use Java’s SecureRandom generator for unique, 32+ character reset tokens. Design links for single use and limit their validity.|
|Uniform Error Responses for Login||Use generic error messages for login failures.|
|Equal login success/failure||Hash passwords before checking user existence.|
|Secure Authorization Principles||Define roles and permissions for users and resources. Check for vulnerabilities in authorization libraries.|
Table 1. Best cybersecurity practices in developing a Java Web Application
Ready to dive deep and learn the details? Bare with me to understand the specifics of cybersecurity best practices, and feel free to contact our consultants if you have any questions!
Basic Application CyberSecurity Mechanisms
Ensuring the integrity of user identities is paramount to Web application security. User identification, when based on email addresses, must be case-insensitive to avoid ambiguity – whether the email is typed in uppercase or lowercase, it should be treated as belonging to the same user. In addition, if an email is used as a login, it should remain hidden at the front end, shielding it from potential malicious attackers. The use of measures such as password strength validation and user lockout after repeated unsuccessful login attempts are also essential safeguards.
Email Address Validation
Validating email addresses is a critical step in establishing strong security measures for your application. The format of these email addresses conforms to the RFC 5321 standard, ensuring uniformity and compliance. In Java, email address parsing can be enforced using regular expression (Regrex), ensuring the correct structure is maintained. However, for a more streamlined approach, we recommend implementing simple validation using annotations within Data Transfer Objects (DTOs). For example, integrating the jakarta.validation.constraints.email annotation directly into the appropriate field within the DTO simplifies the process. Once the email is sent, if the server rejects the address, it can be considered invalid.
Ensuring Robust Access Protection
The strength of a password is paramount in securing user accounts, and its verification involves several key considerations. A password should be an appropriate length, with a minimum of 8 characters and a maximum of 64 characters, allowing the use of any character type to increase complexity. In addition, enforcing regular password changes after a breach is essential to prevent potential attacks. Additionally, the front-end password strength meter is nice to have, as it provides users with a visual gauge of their password safety. This strategic addition not only empowers users to choose stronger passwords, but also serves as a persuasive tool in advocating for increased security awareness.
Safe password storing
The use of password hashing is a formidable shield against potential breaches. This approach converts passwords into a hashed representation, making it nearly impossible to reverse-engineer the original combination. To strengthen this defense, the inclusion of salt and pepper additionally boosts security, rendering pre-computed attacks futile. Another crucial practice is choosing a secure password hashing algorithm is paramount. Argon2id, bcrypt, and PBKDF2, available in Spring Security as Argon2PasswordEncoder, BCryptPasswordEncoder and Pbkdf2PasswordEncoder classes, are highly recommended. In the same breath, it is imperative to stay away from outdated algorithms such as MD5 and SHA-1, as their vulnerabilities have been extensively exploited, making them a glaring security risk.
Efficient Password Recovery
Password recovery is a vital part of user account management, involving a two-step process: requesting a password reset and creating a new one. After a password reset request, a consistent 200 HTTP status code should be returned to indicate success. Processing this asynchronously thwarts potential attackers trying to deduce user emails from frontend responses, preventing response time exploitation. Conversely, synchronous processing might expose clues. Another important thing that will counter attackers who guess the data from the system response is maintaining a uniform request processing time, regardless of user existence. It is also worth incorporating methods like security questions or SMS verification to bolster recovery even more. Last, forcing users to log in again afterpassword change ensures immediate new security activation.
Secure mechanism for generating reset links
To create unique reset links, it’s recommended to use Java’s SecureRandom generator. This ensures that the generated tokens are sufficiently long, spanning a minimum of 32 characters, and inherently resistant to predictability. These reset links should be designed for single-use purposes and come with a relatively short validity window, such as 24 hours.
Optimizing Login Operations
Make sure to shield your system also from attackers attempting to deduce sensitive information from login responses. Employ generic error messages for unsuccessful login attempts, irrespective of whether the error lies in the login credentials, account non-existence, account blockage, or deactivation. By keeping error responses uniform, you thwart attackers’ attempts to deduce which part of the login process they got right or wrong.
Implementing the login operation in an inappropriate way can inadvertently introduce variations in processing times, depending on whether a user exists or not. To achieve consistent processing times and mitigate these discrepancies, a careful approach is essential. One effective strategy involves first hashing the password, followed by a check for the existence of a user with that hashed password. Hashing algorithms, compared to the rest of the code, tend to have a lengthier execution time. Given that password hashing constitutes a significant portion of the operation, addressing this disparity early in the process is key to leveling the playing field.
Wrong pseudocode for login operation:
Ok pseudocode for login operation:
Foiling the Attacker’s Guesswork: Strategic Response Messages
When creating automated responses to certain actions, precision and discretion are paramount, particularly in the context of user existence. Again, employing best practices demands upholding the highest level of generality in these communications. For instance, during login attempts, a fitting response could be “Login attempt unsuccessful,” avoiding any specific indications of user presence or absence. Contrarily, exposing details such as “Incorrect password,” or “User with provided email doesn’t exist” can unintentionally disclose information about the system’s internal state. These careful communication practices safeguard user privacy and bolster overall system security.
|Action/Event||Example of Correct Response||Incorrect Response|
|Login Attempt||“Login attempt unsuccessful.”||“Incorrect password,” “Account inactive,” “User doesn’t exist.”|
|New User Registration||“An activation link has been sent to the provided email.”||“User with provided email already exists/doesn’t exist.”|
|Password restoring||“You will receive a link to reset your password.”||“User doesn’t exist,” “Incorrect e-mail.”|
Table 2. Best practices in writing strategic responses messages – examples
Safe authorization – thoughts on access control
In the area of access control, defining roles and permissions for user types and resources is pivotal. Specifying user permissions on each resource, avoiding overly broad permissions in favor of specific ones, enhances security by minimizing vulnerabilities. Starting with minimal permissions and gradually granting more access maintains the principle of least privilege. Moreover, emphasizing clear communication about resource access for different user types and rigorously validating requests across devices further fortifies security. Thoroughly verifying authorization libraries and frameworks prevents inadvertent exposure of sensitive resources. By embracing these practices, a solid foundation for secure authorization is laid, safeguarding resources and strengthening access controls’ integrity.
What are the challenges?
Web application security presents diverse challenges that demand strategic solutions. One such hurdle involves crafting a custom login endpoint. While Spring offers an automated endpoint for email and password login, leveraging JWT tokens and token renewal mechanisms may need a custom approach. Consider adding a rate limiting mechanism to your endpoints like reset password, register user or confirm activation.
Moreover, the convergence of business processes with security introduces intricacies. Tailoring the user journey based on client business preferences, like altering the order of email verification and registration, can inadvertently introduce vulnerabilities, as attackers might exploit these variations. If you struggle to navigate through these challenges, do not hesitate to contact our team to craft a tailored solution for your case.