diff --git a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll index 21aa7610de75..37b166f4750c 100644 --- a/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll @@ -79,6 +79,7 @@ private module Frameworks { private import semmle.code.java.frameworks.apache.Lang private import semmle.code.java.frameworks.guava.Guava private import semmle.code.java.frameworks.jackson.JacksonSerializability + private import semmle.code.java.frameworks.Netty private import semmle.code.java.security.ResponseSplitting private import semmle.code.java.security.InformationLeak private import semmle.code.java.security.XSS diff --git a/java/ql/src/semmle/code/java/dataflow/FlowSources.qll b/java/ql/src/semmle/code/java/dataflow/FlowSources.qll index 3d3cac9ca4b6..9b8ef7ea9428 100644 --- a/java/ql/src/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/src/semmle/code/java/dataflow/FlowSources.qll @@ -25,6 +25,7 @@ import semmle.code.java.frameworks.spring.SpringWebClient import semmle.code.java.frameworks.Guice import semmle.code.java.frameworks.struts.StrutsActions import semmle.code.java.frameworks.Thrift +import semmle.code.java.frameworks.Netty private import semmle.code.java.dataflow.ExternalFlow /** A data flow source of remote user input. */ diff --git a/java/ql/src/semmle/code/java/dataflow/FlowSteps.qll b/java/ql/src/semmle/code/java/dataflow/FlowSteps.qll index d30cca6afe6a..199eee1dd5b0 100644 --- a/java/ql/src/semmle/code/java/dataflow/FlowSteps.qll +++ b/java/ql/src/semmle/code/java/dataflow/FlowSteps.qll @@ -14,6 +14,7 @@ private module Frameworks { private import semmle.code.java.frameworks.android.Intent private import semmle.code.java.frameworks.android.SQLite private import semmle.code.java.frameworks.Guice + private import semmle.code.java.frameworks.Netty private import semmle.code.java.frameworks.Protobuf private import semmle.code.java.frameworks.guava.Guava private import semmle.code.java.frameworks.apache.Lang diff --git a/java/ql/src/semmle/code/java/frameworks/Netty.qll b/java/ql/src/semmle/code/java/frameworks/Netty.qll new file mode 100644 index 000000000000..8f93fa72d5f6 --- /dev/null +++ b/java/ql/src/semmle/code/java/frameworks/Netty.qll @@ -0,0 +1,63 @@ +import java +private import semmle.code.java.dataflow.FlowSteps +private import semmle.code.java.dataflow.FlowSources +private import semmle.code.java.dataflow.ExternalFlow + +/** + * Netty methods that access user-supplied request data. + */ +private class NettySource extends SourceModelCsv { + override predicate row(string row) { + row = [ + "io.netty.channel;ChannelInboundHandler;true;channelRead;;;Parameter[1];remote", + "io.netty.handler.codec;ByteToMessageDecoder;true;callDecode;;;Parameter[1];remote", + "io.netty.handler.codec;ByteToMessageDecoder;true;decode;;;Parameter[1];remote", + "io.netty.handler.codec;ByteToMessageDecoder;true;decodeLast;;;Parameter[1];remote" + ] + } +} + +/** + * Netty methods that propagate user-supplied request data as tainted. + */ +private class NettyModel extends SummaryModelCsv { + override predicate row(string row) { + row = [ + "io.netty.buffer;ByteBuf;true;getBuffer;;;Argument[-1];ReturnValue;taint", + "io.netty.buffer;ByteBuf;true;getByte;;;Argument[-1];ReturnValue;taint", + "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;taint", + "io.netty.buffer;ByteBuf;true;getChar;;;Argument[-1];ReturnValue;taint", + "io.netty.buffer;ByteBuf;true;getCharSequence;;;Argument[-1];ReturnValue;taint", + "io.netty.buffer;ByteBuf;true;getCharSequence;;;Argument[-1];ReturnValue;taint", + "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;taint", + "io.netty.buffer;ByteBuf;true;readChar;;;Argument[-1];ReturnValue;taint", + "io.netty.buffer;ByteBuf;true;readCharSequence;;;Argument[-1];ReturnValue;taint", + "io.netty.buffer;ByteBuf;true;readSlice;;;Argument[-1];ReturnValue;taint", + "io.netty.buffer;ByteBufHolder;true;content;;;Argument[-1];ReturnValue;taint", + + "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint", + + "io.netty.buffer;ByteBuf;true;setByte;;;Argument[1];Argument[-1];taint", + "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint", + "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint", + "io.netty.buffer;ByteBuf;true;setCharSequence;;;Argument[1];Argument[-1];taint", + + "io.netty.buffer;ByteBuf;true;writeByte;;;Argument[0];Argument[-1];taint", + "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint", + "io.netty.buffer;ByteBuf;true;writeChar;;;Argument[0];Argument[-1];taint", + "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[1];Argument[-1];taint", + + "io.netty.handler.codec.http;HttpHeaders;true;entries;;;Argument[-1];ReturnValue;taint", + "io.netty.handler.codec.http;HttpHeaders;true;get;;;Argument[-1];ReturnValue;taint", + "io.netty.handler.codec.http;HttpHeaders;true;getAll;;;Argument[-1];ReturnValue;taint", + "io.netty.handler.codec.http;HttpHeaders;true;getAllAsString;;;Argument[-1];ReturnValue;taint", + "io.netty.handler.codec.http;HttpHeaders;true;getAsString;;;Argument[-1];ReturnValue;taint", + "io.netty.handler.codec.http;HttpHeaders;true;getHeader;;;Argument[-1];ReturnValue;taint", + "io.netty.handler.codec.http;HttpHeaders;true;valueCharSequenceIterator;;;Argument[-1];ReturnValue;taint", + "io.netty.handler.codec.http;HttpHeaders;true;valueStringIterator;;;Argument[-1];ReturnValue;taint", + "io.netty.handler.codec.http;HttpMessage;true;headers;;;Argument[-1];ReturnValue;taint", + "io.netty.handler.codec.http;HttpMessage;true;trailingHeaders;;;Argument[-1];ReturnValue;taint" + ] + } +} +