What is HTTP response splitting? How do you prevent it -- especially in Java EE-based Web applications?
HTTP response splitting is a Web application input validation vulnerability that allows to exploit the HTTP headers of a Web application for initiating attacks leading to cross-site scripting (XSS), user/page hijacking, cookie poisoning, website spoofing/defacement, and so on. The attacker initiates this attack through the injection of a sequence of hex-coded Carriage-Return (CR) and Line-Feed (LF) characters in the HTTP header and then appending it with malicious HTTP Set-Cookie headers crafted to force the server to process and break the requests into two individual responses. To protect Java EE- (J2EE) based Web applications from HTTP response splitting related risks and vulnerabilities, the golden rule is to perform input validation and output sanitation of Web-tier/presentation components that allow user interaction via a Web browser or a client application.
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 the client side and the 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 mitigate HTTP response splitting risks, it becomes important to parse and verify the input for CRLF rn %0d%0a or any other form of encoding CRLF characters before processing them. When handling 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 as a special sequence of character sets that cannot be executed at the Java EE application server or Web server. This allows for the defeat of HTTP response splitting and related XSS attempts through malicious code and script injection. If the Web application relies on client-side data validation, it is always a safe and good practice to re-verify and re-validate input at the server side, even after client-side validation.
Output sanitation also plays a vital role in avoiding HTTP response splitting. Re-displaying or echoing the data values entered by users causes a potential 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 that may be able to change the content originally displayed by the site -- or perform malicious operations.
For Java EE Web application developers, 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 proactively thwarting related attacks:
1. 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 Secure Sockets Layer (SSL) communication with digital certificates offers confidentiality and integrity to data transmitted between the Web applications and client authentication.
2. Use stateful firewalls. Use a stateful firewall inspection to keep track of all Web-tier transmissions and protocol sessions. Make sure it blocks all un-requested transmissions.
3. Validate form fields. Ensure that any alteration, insertion, and removal of HTML form fields by the originating browser are detected and logged and result in an error message.
4. 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.
5. Track user sessions. Identify the originating user and the host destination making the application request in the user session identification. 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.
6. 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. These exceptions to the end user expose weakness in the application and allow hackers to design potential attacks.
7. 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 weaknesses in 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.