Merge pull request #20999 from joefarebrother/java-spring-websocket

Java: Add models for spring WebSocketHandler
This commit is contained in:
Owen Mansel-Chan
2026-01-07 13:29:19 +00:00
committed by GitHub
17 changed files with 324 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Additional remote flow sources from the `org.springframework.web.socket` package have been modeled.

View File

@@ -0,0 +1,23 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: sourceModel
data:
- ["org.springframework.web.socket", "WebSocketHandler", True, "afterConnectionClosed", "", "", "Parameter[0]", "remote", "manual"]
- ["org.springframework.web.socket", "WebSocketHandler", True, "afterConnectionEstablished", "", "", "Parameter[0]", "remote", "manual"]
- ["org.springframework.web.socket", "WebSocketHandler", True, "handleMessage", "", "", "Parameter[0]", "remote", "manual"]
- ["org.springframework.web.socket", "WebSocketHandler", True, "handleMessage", "", "", "Parameter[1]", "remote", "manual"]
- ["org.springframework.web.socket", "WebSocketHandler", True, "handleTransportError", "", "", "Parameter[0]", "remote", "manual"]
- ["org.springframework.web.socket.handler", "AbstractWebSocketHandler", True, "handleBinaryMessage", "", "", "Parameter[0..1]", "remote", "manual"]
- ["org.springframework.web.socket.handler", "AbstractWebSocketHandler", True, "handlePongMessage", "", "", "Parameter[0..1]", "remote", "manual"]
- ["org.springframework.web.socket.handler", "AbstractWebSocketHandler", True, "handleTextMessage", "", "", "Parameter[0..1]", "remote", "manual"]
- addsTo:
pack: codeql/java-all
extensible: summaryModel
data:
- ["org.springframework.web.socket", "TextMessage", True, "asBytes", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
- ["org.springframework.web.socket", "WebSocketMessage", True, "getPayload", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
- ["org.springframework.web.socket", "WebSocketSession", True, "getAcceptedProtocol", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
- ["org.springframework.web.socket", "WebSocketSession", True, "getHandshakeHeaders", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
- ["org.springframework.web.socket", "WebSocketSession", True, "getPrincipal", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
- ["org.springframework.web.socket", "WebSocketSession", True, "getUri", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]

View File

@@ -0,0 +1,64 @@
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.PongMessage;
import org.springframework.web.socket.CloseStatus;
public class Test {
void sink(Object o) {}
public class A extends TextWebSocketHandler {
@Override
public void handleMessage(WebSocketSession s, WebSocketMessage<?> m) {
sink(s); // $hasTaintFlow
sink(s.getAcceptedProtocol()); // $hasTaintFlow
sink(s.getHandshakeHeaders()); // $hasTaintFlow
sink(s.getPrincipal()); // $hasTaintFlow
sink(s.getUri()); // $hasTaintFlow
sink(m); // $hasTaintFlow
sink(m.getPayload()); // $hasTaintFlow
}
@Override
protected void handleTextMessage(WebSocketSession s, TextMessage m) {
sink(s); // $hasTaintFlow
sink(m); // $hasTaintFlow
sink(m.asBytes()); // $hasTaintFlow
}
@Override
protected void handleBinaryMessage(WebSocketSession s, BinaryMessage m) {
sink(s); // $hasTaintFlow
sink(m); // $hasTaintFlow
}
@Override
protected void handlePongMessage(WebSocketSession s, PongMessage m) {
sink(s); // $hasTaintFlow
sink(m); // $hasTaintFlow
}
@Override
public void afterConnectionEstablished(WebSocketSession s) {
sink(s); // $hasTaintFlow
}
@Override
public void afterConnectionClosed(WebSocketSession s, CloseStatus c) {
sink(s); // $hasTaintFlow
}
@Override
public void handleTransportError(WebSocketSession s, Throwable exc) {
sink(s); // $hasTaintFlow
}
}
}

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x:${testdir}/../../../../stubs/javax-servlet-2.5:${testdir}/../../../../stubs/apache-commons-logging-1.2

View File

@@ -0,0 +1,16 @@
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.FlowSources
import utils.test.InlineFlowTest
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
DefaultFlowConfig::isSource(node)
or
node instanceof ActiveThreatModelSource
}
predicate isSink = DefaultFlowConfig::isSink/1;
}
import FlowTest<DefaultFlowConfig, Config>

View File

@@ -0,0 +1,16 @@
// Generated automatically from org.springframework.web.socket.AbstractWebSocketMessage for testing purposes
package org.springframework.web.socket;
import org.springframework.web.socket.WebSocketMessage;
abstract public class AbstractWebSocketMessage<T> implements WebSocketMessage<T>
{
protected AbstractWebSocketMessage() {}
protected abstract String toStringPayload();
public String toString(){ return null; }
public T getPayload(){ return null; }
public boolean equals(Object p0){ return false; }
public boolean isLast(){ return false; }
public int hashCode(){ return 0; }
}

View File

@@ -0,0 +1,18 @@
// Generated automatically from org.springframework.web.socket.BinaryMessage for testing purposes
package org.springframework.web.socket;
import java.nio.ByteBuffer;
import org.springframework.web.socket.AbstractWebSocketMessage;
public class BinaryMessage extends AbstractWebSocketMessage<ByteBuffer>
{
protected BinaryMessage() {}
protected String toStringPayload(){ return null; }
public BinaryMessage(ByteBuffer p0){}
public BinaryMessage(ByteBuffer p0, boolean p1){}
public BinaryMessage(byte[] p0){}
public BinaryMessage(byte[] p0, boolean p1){}
public BinaryMessage(byte[] p0, int p1, int p2, boolean p3){}
public int getPayloadLength(){ return 0; }
}

View File

@@ -0,0 +1,34 @@
// Generated automatically from org.springframework.web.socket.CloseStatus for testing purposes
package org.springframework.web.socket;
import java.io.Serializable;
public class CloseStatus implements Serializable
{
protected CloseStatus() {}
public CloseStatus withReason(String p0){ return null; }
public CloseStatus(int p0){}
public CloseStatus(int p0, String p1){}
public String getReason(){ return null; }
public String toString(){ return null; }
public boolean equals(Object p0){ return false; }
public boolean equalsCode(CloseStatus p0){ return false; }
public int getCode(){ return 0; }
public int hashCode(){ return 0; }
public static CloseStatus BAD_DATA = null;
public static CloseStatus GOING_AWAY = null;
public static CloseStatus NORMAL = null;
public static CloseStatus NOT_ACCEPTABLE = null;
public static CloseStatus NO_CLOSE_FRAME = null;
public static CloseStatus NO_STATUS_CODE = null;
public static CloseStatus POLICY_VIOLATION = null;
public static CloseStatus PROTOCOL_ERROR = null;
public static CloseStatus REQUIRED_EXTENSION = null;
public static CloseStatus SERVER_ERROR = null;
public static CloseStatus SERVICE_OVERLOAD = null;
public static CloseStatus SERVICE_RESTARTED = null;
public static CloseStatus SESSION_NOT_RELIABLE = null;
public static CloseStatus TLS_HANDSHAKE_FAILURE = null;
public static CloseStatus TOO_BIG_TO_PROCESS = null;
}

View File

@@ -0,0 +1,14 @@
// Generated automatically from org.springframework.web.socket.PongMessage for testing purposes
package org.springframework.web.socket;
import java.nio.ByteBuffer;
import org.springframework.web.socket.AbstractWebSocketMessage;
public class PongMessage extends AbstractWebSocketMessage<ByteBuffer>
{
protected String toStringPayload(){ return null; }
public PongMessage(){}
public PongMessage(ByteBuffer p0){}
public int getPayloadLength(){ return 0; }
}

View File

@@ -0,0 +1,16 @@
// Generated automatically from org.springframework.web.socket.TextMessage for testing purposes
package org.springframework.web.socket;
import org.springframework.web.socket.AbstractWebSocketMessage;
public class TextMessage extends AbstractWebSocketMessage<String>
{
protected TextMessage() {}
protected String toStringPayload(){ return null; }
public TextMessage(CharSequence p0){}
public TextMessage(CharSequence p0, boolean p1){}
public TextMessage(byte[] p0){}
public byte[] asBytes(){ return null; }
public int getPayloadLength(){ return 0; }
}

View File

@@ -0,0 +1,19 @@
// Generated automatically from org.springframework.web.socket.WebSocketExtension for testing purposes
package org.springframework.web.socket;
import java.util.List;
import java.util.Map;
public class WebSocketExtension
{
protected WebSocketExtension() {}
public Map<String, String> getParameters(){ return null; }
public String getName(){ return null; }
public String toString(){ return null; }
public WebSocketExtension(String p0){}
public WebSocketExtension(String p0, Map<String, String> p1){}
public boolean equals(Object p0){ return false; }
public int hashCode(){ return 0; }
public static List<WebSocketExtension> parseExtensions(String p0){ return null; }
}

View File

@@ -0,0 +1,16 @@
// Generated automatically from org.springframework.web.socket.WebSocketHandler for testing purposes
package org.springframework.web.socket;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
public interface WebSocketHandler
{
boolean supportsPartialMessages();
void afterConnectionClosed(WebSocketSession p0, CloseStatus p1);
void afterConnectionEstablished(WebSocketSession p0);
void handleMessage(WebSocketSession p0, WebSocketMessage<? extends Object> p1);
void handleTransportError(WebSocketSession p0, Throwable p1);
}

View File

@@ -0,0 +1,11 @@
// Generated automatically from org.springframework.web.socket.WebSocketMessage for testing purposes
package org.springframework.web.socket;
public interface WebSocketMessage<T>
{
T getPayload();
boolean isLast();
int getPayloadLength();
}

View File

@@ -0,0 +1,35 @@
// Generated automatically from org.springframework.web.socket.WebSocketSession for testing purposes
package org.springframework.web.socket;
import java.io.Closeable;
import java.net.InetSocketAddress;
import java.net.URI;
import java.security.Principal;
import java.util.List;
import java.util.Map;
import org.springframework.http.HttpHeaders;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketExtension;
import org.springframework.web.socket.WebSocketMessage;
public interface WebSocketSession extends Closeable
{
HttpHeaders getHandshakeHeaders();
InetSocketAddress getLocalAddress();
InetSocketAddress getRemoteAddress();
List<WebSocketExtension> getExtensions();
Map<String, Object> getAttributes();
Principal getPrincipal();
String getAcceptedProtocol();
String getId();
URI getUri();
boolean isOpen();
int getBinaryMessageSizeLimit();
int getTextMessageSizeLimit();
void close();
void close(CloseStatus p0);
void sendMessage(WebSocketMessage<? extends Object> p0);
void setBinaryMessageSizeLimit(int p0);
void setTextMessageSizeLimit(int p0);
}

View File

@@ -0,0 +1,24 @@
// Generated automatically from org.springframework.web.socket.handler.AbstractWebSocketHandler for testing purposes
package org.springframework.web.socket.handler;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.PongMessage;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
abstract public class AbstractWebSocketHandler implements WebSocketHandler
{
protected void handleBinaryMessage(WebSocketSession p0, BinaryMessage p1){}
protected void handlePongMessage(WebSocketSession p0, PongMessage p1){}
protected void handleTextMessage(WebSocketSession p0, TextMessage p1){}
public AbstractWebSocketHandler(){}
public boolean supportsPartialMessages(){ return false; }
public void afterConnectionClosed(WebSocketSession p0, CloseStatus p1){}
public void afterConnectionEstablished(WebSocketSession p0){}
public void handleMessage(WebSocketSession p0, WebSocketMessage<? extends Object> p1){}
public void handleTransportError(WebSocketSession p0, Throwable p1){}
}

View File

@@ -0,0 +1,13 @@
// Generated automatically from org.springframework.web.socket.handler.TextWebSocketHandler for testing purposes
package org.springframework.web.socket.handler;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
public class TextWebSocketHandler extends AbstractWebSocketHandler
{
protected void handleBinaryMessage(WebSocketSession p0, BinaryMessage p1){}
public TextWebSocketHandler(){}
}