How do I prevent XSS in Java?
In a nutshell, input validation in a Java EE Web application is done via filtering and encoding mechanisms. In practice, it is quite important to validate the input parameters at both client-side and server-side before accepting the request and resuming the process on input parameters. The filtering mechanism should validate data in terms of data type (string, integer), format, length, range, null-value handling, verifying for character-set, locale, patterns, context, legal values, session validity, redirection URL, idle time and so on.
Although filtering is a promising solution, in some scenarios we cannot discard or reject data using filters where the user is requested to provide input content that includes special characters. To handle special input content with undiagnosed characters or scripts, it is often recommended to use encoding mechanisms that allow transformation of the stream of encoded characters to a special sequence of character sets that cannot be executed at the Java EE application server or Web server. This allows us to defeat XSS attempts through malicious hyperlinks and scriptlets. If the Web application relies on client-side data validation, it is always safe and good practice to re-verify and re-validate input at server-side, even after client-side validation.
Output sanitation is also plays a vital role in avoiding XSS. Re-displaying or echoing the data values entered by users causes a potential XSS threat because it provides a hacker with a means to match the given input and its output. This provides a way to explore the Web component by inserting malicious data inputs. If the page generated by a user's request is not properly sanitized before it is displayed, a hacker may be able to identify a weakness or loophole by reading the generated output. Using the weakness, the hacker can design and insert malicious scripts and hyperlinks. From there, a hacker may change the content originally displayed by the site or perform malicious operations.
From my experience, to thwart XSS attacks I strongly recommend using appropriate design strategies prescribed in the "Intercepting Validator" and "Secure Session Manager" patterns from the Core Security patterns catalog. In addition to input validation and output sanitization mechanisms, I often recommend the following best practices to be considered for identifying and preventing XSS-based attacks:
- Secure the Transport: For all security-sensitive Web applications and Web-based online transactions, make sure the session and data exchanged between the server and client remain confidential and tamper-proof during transit. Using SSL communication with digital certificates offers confidentiality and integrity of data transmitted between the Web applications and client authentication.
- Use stateful firewalls: Use a stateful firewall inspection to keep track of all Web-tier transmissions and protocol sessions. Make sure it blocks all unrequested transmissions.
- Validate form fields: Ensure that any alteration, insertion, and removal of HTML form fields by the originating browser are detected, logged, and result in an error message.
- Use HTTP POST: Use HTTP POST rather than HTTP GET and avoid using HTTP GET requests while generating HTML forms. HTTP GET requests reveal URL-appended information, allowing sensitive information to be revealed in the URL string. Also, disable processing of HTTP TRACE method in the target Java EE application or Web server to defeat cross-site tracing (XST) attacks.
- Track user sessions: Identify the originating user and the host destination making the application request in the user session ID. Verify that all subsequent requests are received from that same user's host origin until the user logs out. This protects application sessions from XSS hijacking and spoofing.
- Error reporting: Always return an error page or exception specific to the application error and the user's request. For example, you might use an application-specific InvalidUserException and NoAccessPrivilegesException. Do not expose remote, system-level and naming service specific exceptions to the user accessing the applications. To the end user, these exceptions expose weaknesses in the application and allow hackers to design potential attacks.
- Audit all relevant business tasks: Create audit trails for all identified user-level sessions and actions with timestamps and store them in a different log file with unique line identifiers. This helps identify any potential exploitation or weakness of the Web application. The audit trails should include user attempts and failures, logouts, disconnects, timeouts, administration tasks, user requests and responses, exceptions, database connections, and so forth.