CVE-2014-0121 (Java, published 2017-12-29T22:29Z)
Description: value: The admin terminal in Hawt.io does not require authentication, which allows remote attackers to execute arbitrary commands via the k parameter.
Severity: HIGH (CVSS v3 base score: 9.8)
Weakness: CWE-287 \u2014 Improper Authentication
When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
Repository: https://github.com/hawtio/hawtio
Files changed:
hawtio-karaf-terminal/pom.xml
hawtio-karaf-terminal/src/main/java/io/hawt/web/plugin/karaf/terminal/KarafTerminalContextListener.java
hawtio-karaf-terminal/src/main/java/io/hawt/web/plugin/karaf/terminal/TerminalServlet.java
hawtio-karaf-terminal/src/main/webapp/WEB-INF/web.xml
hawtio-karaf-terminal/src/main/webapp/app/js/gogo.js
hawtio-karaf-terminal/src/main/webapp/app/js/gogoPlugin.js
hawtio-system/src/main/java/io/hawt/web/AuthenticationFilter.java
Commit message: Ensure we secure hawtio-karaf-terminal's /term context


Vulnerable code:
        SessionTerminal st = (SessionTerminal) request.getSession(true).getAttribute("terminal");
            request.getSession().setAttribute("terminal", st);
gogo.Terminal_ctor = function(div, width, height) {
gogo.Terminal = function(div, width, height) {
   return new this.Terminal_ctor(div, width, height);
    }).directive('gogoTerminal', function(log) {
          gogo.Terminal(element.get(0), width, height);
        boolean doAuthenticate = path.startsWith("/auth") ||
                path.startsWith("/jolokia") ||
                path.startsWith("/upload");
            LOG.debug("No authentication needed for path {}", path);

Fixed code:
    <dependency>
      <groupId>io.hawt</groupId>
      <artifactId>hawtio-system</artifactId>
      <version>${project.version}</version>
    </dependency>

package io.hawt.web.plugin.karaf.terminal;

import io.hawt.system.ConfigManager;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

/**
 * @author Stan Lewis
 */
public class KarafTerminalContextListener implements ServletContextListener {

  private ConfigManager configManager = new ConfigManager();

  @Override
  public void contextInitialized(ServletContextEvent sce) {
    try {
      configManager.init();
    } catch (Exception e) {
      throw createServletException(e);
    }
    sce.getServletContext().setAttribute("ConfigManager", configManager);
  }

  @Override
  public void contextDestroyed(ServletContextEvent sce) {
    try {
      configManager.destroy();
    } catch (Exception e) {
      throw createServletException(e);
    }

  }
  protected RuntimeException createServletException(Exception e) {
    return new RuntimeException(e);
  }

}
import io.hawt.system.Helpers;
import javax.security.auth.Subject;
import javax.servlet.http.HttpSession;
import java.security.AccessControlContext;
import java.security.AccessController;

        HttpSession session = request.getSession(false);
        if (session == null) {
          AccessControlContext acc = AccessController.getContext();
          Subject subject = Subject.getSubject(acc);
          if (subject == null) {
            Helpers.doForbidden(response);
            return;
          }
          session = request.getSession(true);
          session.setAttribute("subject", subject);
        } else {
          Subject subject = (Subject) session.getAttribute("subject");
          if (subject == null) {
            session.invalidate();
            Helpers.doForbidden(response);
            return;
          }
        }

        SessionTerminal st = (SessionTerminal) session.getAttribute("terminal");
            session.setAttribute("terminal", st);
  <env-entry>
    <description>Enable/disable hawtio's authentication filter, value is really a boolean</description>
    <env-entry-name>hawtio/authenticationEnabled</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>false</env-entry-value>
  </env-entry>

  <env-entry>
    <description>Authorized user role, empty string disables authorization</description>
    <env-entry-name>hawtio/role</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value></env-entry-value>
  </env-entry>

  <env-entry>
    <description>JAAS classname that would contain the role principal, empty string disables authorization</description>
    <env-entry-name>hawtio/rolePrincipalClasses</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value></env-entry-value>
  </env-entry>

  <env-entry>
    <description>JAAS realm used to authenticate users</description>
    <env-entry-name>hawtio/realm</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>*</env-entry-value>
  </env-entry>

  <filter>
    <filter-name>AuthenticationFilter</filter-name>
    <filter-class>io.hawt.web.AuthenticationFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>AuthenticationFilter</filter-name>
    <url-pattern>/term/*</url-pattern>
  </filter-mapping>


  <listener>
    <listener-class>io.hawt.web.plugin.karaf.terminal.KarafTerminalContextListener</listener-class>
  </listener>

gogo.Terminal_ctor = function(div, width, height, authHeader) {
           r.setRequestHeader('Authorization', authHeader);
gogo.Terminal = function(div, width, height, authHeader) {
   return new this.Terminal_ctor(div, width, height, authHeader);
    }).directive('gogoTerminal', function(log, userDetails) {
          var authHeader = Core.getBasicAuthHeader(userDetails.username, userDetails.password);

          gogo.Terminal(element.get(0), width, height, authHeader);
        boolean doAuthenticate = true;
            LOG.warn("No authentication needed for path {}", path);