====================== Reflected XSS ====================== JForum has a reflected XSS flaw whose exploitation is uniquely non-trivial. To start: in my development environment, this URL causes an alert box to pop up, containing my session cookies: http://localhost:8080/JForum/nonexistent.page?module=js&action=list&js=../admin/admin_welcome.htm%00 This is an interesting story, and the reason this fires is complex, as far as XSS goes. First, that type of URL won't normally be found in JForum. The typical URL structure is REST. For example, the URL to list the recent posts in a category would look something like this: http://localhost:8080/JForum/recentTopics/list.page This is parsed by JForum into a "module" and an "action". The "recentTopics" substring represents the "module" of this URL, and "list", the "action." However, there is an alternative and possibly legacy representation for URLs that is honored by JForum, where URLs look like this: http://localhost:8080/JForum/servlet.page?module=recentTopics&action=list The "servlet" substring in this URL is arbitrary, since JForum's main engine catches all requests aimed at "*.page" and handles them identically based on parameters. This will end up making an attack signature difficult, as will be shown later. Normally, no user input in JForum is rendered without encoding. The text being output in this example is being done so by Freemarker, the templating system used by JForum. Because the template to execute is supplied by the user (the 'js' parameter), the user can choose any file on the target filesystem. If the file is not a pre-approved template, the application will error without doing anything necessarily beneficial to the attacker. The only alternative, then, is to provide a template that the application won't have correct contextual data for. This will happen, for instance, when a normal user attempts to view an admin template. When the expected data isn't found this will inevitably cause a problem, after which Freemarker will print an error message that contains the filename being executed, along with other data which is not controlled by the user. So, the only way for this to be useful is if the filename contained an attack. This is about the time a normal developer would cry theoretical and reject the vulnerability. Unfortunately for them, by supplying the null byte followed by a traditional XSS payload, we can make both JForum/Freemarker and the attacker happy. When JForum/Freemarker look up the file, the file system will acknowledge that the file exists and is a pre-approved template. However, when the filename is printed out by Freemarker after the error occurs, it will echo the entire filename parameter, not just the part of the filename understood by the lower level APIs. Because the attack is part of the extended filename, it gets echoed to the browser, and the JavaScript fires. This vulnerability could not exist without 3 combined failures of the OWASP Top 10 : flawed error handling (printing detailed error information), direct object references (specifying arbitrary templates in the URL) and XSS. This is a credit to the code of Rafael Steil, the maintainer of JForum, who otherwise makes a very security conscious product. Note: One might guess that the ability to specify arbitrary template constitutes an elevation of privileges. The templates are read-only and are publicly available, since the forum software is OSS. For it to be useful, the application would first have to queue the relevant admin information into memory before processing the template. This would require a seperate vulnerability. Also, here is another instance of a more vanilla reflected XSS: http://localhost:8080/JForum/jforum.page?module=user&action=recoverPassword&hash=foo%22%3E%3Cscript%3Ealert%28document.cookie%29%3C/script%3E%3Ca ====================== Lack of HttpOnly ====================== The application does not set the HttpOnly flag on session cookies. This is unsurprising, since there is no method of doing so in most J2EE servlet containers. Some application servers have a setting to enable this, but its often unused or unavailable due to corporate version-leapfrogging or fear of back-breakage. ====================== Lack of frame breaking ====================== The application does not supply any "frame breaking" code to the browser. This allows arbitrary sites to frame the JForum application on their own domains, which can lead to many types of cross-frame problems, most notably "clickjacking." ====================== Information disclosure: detailed error messages ====================== There are multiple places where the application leaks Java stack traces when errors occur. Here are two URLs that do so: This information can be used to fingerprint the Java technology stack, which may be useful in other attacks. ===================== Installion JSP file available after installation ===================== The application doesn't remove the installation JSP used to configure the application. This means that attackers who force browse to this URL can reconfigure the application to use their database and any other settings. This can lead to stored XSS and other information disclosure. WAF patch: a restrict-source-ip rule that will prevent any request not from a LAN or localhost from accessing that special installation JSP. ===================== Unchecked redirects ===================== JForum suffers from multiple unchecked redirect vulnerabilities. This type of vulnerability can be used for phishing and probably XSS. For instance, on my local development machines, the following URL will cause the user to end up at Aspect Security's web site: http://localhost:8080/JForum/jforum.page?module=user&action=validateLogin&returnPath=http%3A//www.aspectsecurity.com&username=admin&password=admin&redirect=&login=Login In a real phishing attack, a malicious user would send a link similar to the one above, where a naive user would think they were seeing the real page. Unfortunately, they would see a fake but convincing page created by the attacker. This fake page could then prompt the user for credentials the way the normal site does. Certain types of browsers [1] may also allow arbitrary redirect targets to point to non-HTTP protocols like "javascript", "data", or others. ===================== Account hijacking through insecure password reset ===================== The "forgot password" feature suffers from a critical design error. The application allows users to automatically reset their password through a "lost password" form. That form only requires a user enter an email address or username. When the form is submitted, the application sends an email containing a token to the associated user's email address. When the user clicks on the link with the token in it in the email, the server will then allow the user to reset their password through a form. In this design, the token is acting as a temporary password for the user. Therefore, if an attacker can predict what token the application will generate, they will be able to reset account passwords for other users. Unfortunately, this scenario is possible. The following code is from UserAction.java, starting at line 671: public User prepareLostPassword(String username, String email) ... String hash = MD5.crypt(user.getEmail() + System.currentTimeMillis()); ... um.writeLostPasswordHash(user.getEmail(), hash); user.setActivationKey(hash); As can be seen in the code snippet, the secret token is an unsalted hash of the user's email address and the number of milliseconds since the epoch. Neither of these pieces of information qualify as secrets in a strong cryptosystem. All that is needed to reset a user's password to a password of the attacker's choosing is the email address of the victim and the ability to generate a few thousand requests. An exploit was made to demonstrate this vulnerability. It's currently tuned to attack a local development environment, but no customizations have been made to make exploitation possible. Since the application leaks the server's time in several places, it's possible to increase the efficiency of the exploit so that remote systems only require a few hundred packets. The exploit is available at the following URL: http://i8jesus.com/stuff/jforum/ThereIsNoSpoon.java ===================== CSRF throughout JForum ===================== There is no effort to prevent unauthorized requests generated by malicious web pages that "piggy back" on a user's existing session.