Technical information leak - API - Java

Technical information leak - API - Java

Need

Protection of sensitive technical information from unauthorized access

Context

  • Usage of Java 8 for developing applications with enhanced features and performance
  • Usage of javax.servlet-api for building Java web applications
  • Usage of graphql-java for implementing GraphQL in Java applications
  • Usage of graphql-java-tools for building and executing GraphQL schemas in Java

Description

Non compliant code

        import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import graphql.schema.idl.SchemaPrinter;
import graphql.schema.idl.TypeDefinitionRegistry;
import graphql.schema.GraphQLSchema;

public class APIServlet extends HttpServlet {

    private GraphQLSchema schema;

    public APIServlet(GraphQLSchema schema) {
        this.schema = schema;
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        SchemaPrinter schemaPrinter = new SchemaPrinter();
        String printedSchema = schemaPrinter.print(schema);
        resp.getWriter().println(printedSchema);
    }
}
        
        

The above code is a simple Java servlet that uses the javax.servlet.http.HttpServlet class. This servlet is designed to handle HTTP GET requests and responds with the entire GraphQL schema of the API.

In the doGet method, the SchemaPrinter object is created and used to print the entire GraphQL schema, which is then written to the response. This means that anyone who sends a GET request to this servlet can retrieve the entire schema.

The vulnerability lies in the fact that the entire GraphQL schema, including both queries and mutations, is exposed to anyone who sends a GET request to this servlet. This can lead to a technical information leak, as an attacker can use this information to understand the structure of your API, potentially identifying weak points and areas to exploit.

This kind of information should not be exposed in a production environment, as it gives away too much information about the internal workings of the application. Therefore, it is considered a security vulnerability.

Steps

  • Restrict access to the API schema endpoint
  • Implement authentication and authorization mechanisms
  • Apply rate limiting to prevent excessive requests
  • Obfuscate or encrypt sensitive information in the schema
  • Regularly update and patch the GraphQL library and dependencies
  • Implement input validation and sanitization to prevent injection attacks
  • Monitor and log access to the API schema endpoint for suspicious activity
  • Conduct security audits and penetration testing to identify and fix vulnerabilities

Compliant code

        import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import graphql.schema.idl.SchemaPrinter;
import graphql.schema.idl.TypeDefinitionRegistry;
import graphql.schema.GraphQLSchema;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpSession;

@WebServlet("/api/*")
public class APIServlet extends HttpServlet {

    private GraphQLSchema schema;

    public APIServlet(GraphQLSchema schema) {
        this.schema = schema;
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession(false);
        if (session == null || session.getAttribute("authenticated") == null) {
            resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized access");
            return;
        }

        SchemaPrinter schemaPrinter = new SchemaPrinter();
        String printedSchema = schemaPrinter.print(schema);
        // Encrypt or obfuscate the printed schema here before sending it
        resp.getWriter().println(printedSchema);
    }
}
        
        

The updated code now includes an authentication check in the doGet method. This check ensures that only authenticated users can access the API schema. If a user is not authenticated, the server responds with an "Unauthorized access" error.

The @WebServlet("/api/*") annotation is used to map this servlet to all URLs that start with "/api/". This is where you would implement rate limiting and other security measures to protect your API.

The HttpSession object is used to check if the user is authenticated. This is a simple form of session management. In a real-world application, you would likely use a more robust form of authentication and session management.

The printed schema is still sent as plain text. In a real-world application, you should encrypt or obfuscate this information to protect it from prying eyes.

Remember to regularly update and patch your GraphQL library and dependencies to protect against known vulnerabilities. Also, implement input validation and sanitization to prevent injection attacks.

Finally, monitor and log access to your API schema endpoint. Regularly conduct security audits and penetration testing to identify and fix any vulnerabilities.

References