mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Query to detect main method in servlets
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
public class ServletMain implements Servlet {
|
||||
// BAD - Implement a main method in servlet.
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Connect to my server
|
||||
URL url = new URL("https://www.example.com");
|
||||
url.openConnection();
|
||||
}
|
||||
|
||||
// GOOD - Not to have a main method in servlet.
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Debug code can create unintended entry points in a deployed web application therefore should never make into production. There is no reason to have a main method in a web application. Having a main method in a web application increases the attack surface that an attacker can exploit to attack the application logic.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>Remove the main method from web components including servlets, filters and listeners.</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>The following example shows two ways of implementing web components. In the 'BAD' case, a main method is implemented. In the 'GOOD' case, no main method is implemented.</p>
|
||||
<sample src="ServletMain.java" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
Fortify:
|
||||
<a href="https://vulncat.fortify.com/en/detail?id=desc.structural.java.j2ee_badpractices_leftover_debug_code">J2EE Bad Practices: Leftover Debug Code</a>
|
||||
</li>
|
||||
<li>
|
||||
SonarSource:
|
||||
<a href="https://rules.sonarsource.com/java/tag/owasp/RSPEC-2653">Web applications should not have a "main" method</a>
|
||||
</li>
|
||||
<li>
|
||||
Carnegie Mellon University:
|
||||
<a href="https://wiki.sei.cmu.edu/confluence/display/java/ENV06-J.+Production+code+must+not+contain+debugging+entry+points">ENV06-J. Production code must not contain debugging entry points</a>
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
49
java/ql/src/experimental/Security/CWE/CWE-489/ServletMain.ql
Normal file
49
java/ql/src/experimental/Security/CWE/CWE-489/ServletMain.ql
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @name Main Method in Servlet
|
||||
* @description Jave EE web applications with a main method.
|
||||
* @kind problem
|
||||
* @id java/main-method-in-servlet
|
||||
* @tags security
|
||||
* external/cwe-489
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.frameworks.Servlets
|
||||
|
||||
/** The java type `javax.servlet.Filter` */
|
||||
class ServletFilterClass extends Class {
|
||||
ServletFilterClass() { this.getASupertype*().hasQualifiedName("javax.servlet", "Filter") }
|
||||
}
|
||||
|
||||
/** Listener class in the package `javax.servlet` and `javax.servlet.http` */
|
||||
class ServletListenerClass extends Class {
|
||||
// Various listener classes of Java EE such as ServletContextListener. They all have a name ending with the word "Listener".
|
||||
ServletListenerClass() {
|
||||
this.getASupertype*()
|
||||
.getQualifiedName()
|
||||
.regexpMatch([
|
||||
"javax\\.servlet\\.[a-zA-Z]+Listener", "javax\\.servlet\\.http\\.[a-zA-Z]+Listener"
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
/** The `main` method in `Servlet`. */
|
||||
class ServletMainMethod extends Method {
|
||||
ServletMainMethod() {
|
||||
(
|
||||
this.getDeclaringType() instanceof ServletClass or
|
||||
this.getDeclaringType() instanceof ServletFilterClass or
|
||||
this.getDeclaringType() instanceof ServletListenerClass
|
||||
) and
|
||||
this.hasName("main") and
|
||||
this.isStatic() and
|
||||
this.getReturnType() instanceof VoidType and
|
||||
this.isPublic() and
|
||||
this.getNumberOfParameters() = 1 and
|
||||
this.getParameter(0).getType() instanceof Array and
|
||||
not this.getDeclaringType().getName().matches("%Test%") // Simple check to exclude test classes to reduce FPs
|
||||
}
|
||||
}
|
||||
|
||||
from ServletMainMethod sm
|
||||
select sm, "Web application has a main method."
|
||||
@@ -0,0 +1,25 @@
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import java.net.URL;
|
||||
|
||||
public class ServletContextListenerMain implements ServletContextListener {
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
System.out.println("listener starts to work!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
System.out.println("listener stopped!");
|
||||
}
|
||||
|
||||
// BAD - Implement a main method in servlet listener.
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
URL url = new URL("https://www.example.com");
|
||||
url.openConnection();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
| ServletContextListenerMain.java:17:21:17:24 | main | Web application has a main method. |
|
||||
| ServletMain.java:28:21:28:24 | main | Web application has a main method. |
|
||||
@@ -0,0 +1,33 @@
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletConfig;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
public class ServletMain implements Servlet {
|
||||
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
|
||||
}
|
||||
|
||||
public void init(ServletConfig servletConfig) throws ServletException {
|
||||
}
|
||||
|
||||
public ServletConfig getServletConfig() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getServletInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
// BAD - Implement a main method in servlet.
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Connect to my server
|
||||
URL url = new URL("https://www.example.com");
|
||||
url.openConnection();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE/CWE-489/ServletMain.ql
|
||||
@@ -0,0 +1 @@
|
||||
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2004 The Apache Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package javax.servlet;
|
||||
|
||||
/**
|
||||
* This is the event class for notifications about changes to
|
||||
* the servlet context of a web application.
|
||||
* @see ServletContextListener
|
||||
*
|
||||
* @since Servlet 2.3
|
||||
*/
|
||||
|
||||
public class ServletContextEvent extends java.util.EventObject {
|
||||
|
||||
/** Construct a ServletContextEvent from the given context.
|
||||
*
|
||||
* @param source - the ServletContext that is sending the event.
|
||||
*/
|
||||
public ServletContextEvent(ServletContext source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ServletContext that changed.
|
||||
*
|
||||
* @return the ServletContext that sent the event.
|
||||
*/
|
||||
public ServletContext getServletContext () {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2004 The Apache Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package javax.servlet;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* Interface for receiving notification events about ServletContext
|
||||
* lifecycle changes.
|
||||
*
|
||||
* <p>In order to receive these notification events, the implementation
|
||||
* class must be either declared in the deployment descriptor of the web
|
||||
* application, annotated with {@link javax.servlet.annotation.WebListener},
|
||||
* or registered via one of the addListener methods defined on
|
||||
* {@link ServletContext}.
|
||||
*
|
||||
* <p>Implementations of this interface are invoked at their
|
||||
* {@link #contextInitialized} method in the order in which they have been
|
||||
* declared, and at their {@link #contextDestroyed} method in reverse
|
||||
* order.
|
||||
*
|
||||
* @see ServletContextEvent
|
||||
*
|
||||
* @since Servlet 2.3
|
||||
*/
|
||||
public interface ServletContextListener extends EventListener {
|
||||
|
||||
/**
|
||||
* Receives notification that the web application initialization
|
||||
* process is starting.
|
||||
*
|
||||
* <p>All ServletContextListeners are notified of context
|
||||
* initialization before any filters or servlets in the web
|
||||
* application are initialized.
|
||||
*
|
||||
* @param sce the ServletContextEvent containing the ServletContext
|
||||
* that is being initialized
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation takes no action.
|
||||
*/
|
||||
default public void contextInitialized(ServletContextEvent sce) {}
|
||||
|
||||
/**
|
||||
* Receives notification that the ServletContext is about to be
|
||||
* shut down.
|
||||
*
|
||||
* <p>All servlets and filters will have been destroyed before any
|
||||
* ServletContextListeners are notified of context
|
||||
* destruction.
|
||||
*
|
||||
* @param sce the ServletContextEvent containing the ServletContext
|
||||
* that is being destroyed
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation takes no action.
|
||||
*/
|
||||
default public void contextDestroyed(ServletContextEvent sce) {}
|
||||
}
|
||||
Reference in New Issue
Block a user