mirror of
https://github.com/github/codeql.git
synced 2026-07-30 23:13:01 +02:00
Address Micronaut modeling review feedback
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["io.micronaut.context.annotation", "Property", True, "", "", "Annotated", "", "environment", "manual"]
|
||||
- ["io.micronaut.context.annotation", "Value", True, "", "", "Annotated", "", "environment", "manual"]
|
||||
@@ -3,31 +3,33 @@ extensions:
|
||||
pack: codeql/java-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
# HttpClient.toBlocking() returns BlockingHttpClient; retrieve/exchange with String URL are SSRF sinks
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "retrieve", "(String)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "retrieve", "(String,Class)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "exchange", "(HttpRequest)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "exchange", "(HttpRequest,Argument)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "exchange", "(HttpRequest,Argument,Argument)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "exchange", "(HttpRequest,Class)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "exchange", "(String)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "exchange", "(String,Class)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "exchange", "(String,Class,Class)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "retrieve", "(HttpRequest)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "retrieve", "(HttpRequest,Argument)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "retrieve", "(HttpRequest,Argument,Argument)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "retrieve", "(HttpRequest,Class)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "retrieve", "(String)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "retrieve", "(String,Class)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "BlockingHttpClient", True, "retrieve", "(String,Class,Class)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "HttpClient", True, "exchange", "(HttpRequest)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "HttpClient", True, "exchange", "(HttpRequest,Argument)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "HttpClient", True, "exchange", "(HttpRequest,Argument,Argument)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "HttpClient", True, "exchange", "(HttpRequest,Class)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "HttpClient", True, "exchange", "(String)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "HttpClient", True, "exchange", "(String,Class)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "HttpClient", True, "retrieve", "(HttpRequest)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "HttpClient", True, "retrieve", "(HttpRequest,Argument)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "HttpClient", True, "retrieve", "(HttpRequest,Argument,Argument)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "HttpClient", True, "retrieve", "(HttpRequest,Class)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["io.micronaut.http.client", "HttpClient", True, "retrieve", "(String)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
# HttpClient.toBlocking() taint propagation
|
||||
- ["io.micronaut.http.client", "HttpClient", True, "toBlocking", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
# HttpRequest.GET/POST/PUT/DELETE/PATCH factory methods propagate URI taint
|
||||
- ["io.micronaut.http", "HttpRequest", True, "GET", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "POST", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "PUT", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "DELETE", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "PATCH", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "HEAD", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "OPTIONS", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
# UriBuilder taint propagation
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "of", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "of", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "host", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "path", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "queryParam", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "queryParam", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "fragment", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "build", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
|
||||
@@ -4,35 +4,56 @@ extensions:
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getBody", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getHeaders", "", "", "ReturnValue.Element.MapValue.Element", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getParameters", "", "", "ReturnValue.Element.MapValue.Element.Element.MapValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getCookies", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getUri", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getPath", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getContentType", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getContentLength", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getContentType", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getCookies", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getHeaders", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getMethodName", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getParameters", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getPath", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "getUri", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["io.micronaut.http", "HttpHeaders", True, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpHeaders", True, "getAll", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpHeaders", True, "getFirst", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpHeaders", True, "values", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpParameters", True, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpParameters", True, "getAll", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpParameters", True, "getFirst", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.core.convert.value", "ConvertibleMultiValues", True, "get", "", "", "Argument[this].Element.MapValue", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.core.convert.value", "ConvertibleMultiValues", True, "getAll", "", "", "Argument[this].Element.MapValue", "ReturnValue", "value", "manual"]
|
||||
- ["io.micronaut.core.convert.value", "ConvertibleMultiValues", True, "getFirst", "", "", "Argument[this].Element.MapValue", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.core.convert.value", "ConvertibleValues", True, "asMap", "", "", "Argument[this].Element.MapValue", "ReturnValue.MapValue", "taint", "manual"]
|
||||
- ["io.micronaut.core.convert.value", "ConvertibleValues", True, "asProperties", "", "", "Argument[this].Element.MapValue", "ReturnValue.MapValue", "taint", "manual"]
|
||||
- ["io.micronaut.core.convert.value", "ConvertibleValues", True, "getValue", "", "", "Argument[this].Element.MapValue", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.core.convert.value", "ConvertibleValues", True, "subMap", "", "", "Argument[this].Element.MapValue", "ReturnValue.MapValue", "taint", "manual"]
|
||||
- ["io.micronaut.core.convert.value", "ConvertibleValues", True, "values", "", "", "Argument[this].Element.MapValue", "ReturnValue.Element", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "DELETE", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "DELETE", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "DELETE", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "DELETE", "(URI,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "GET", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "GET", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "HEAD", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "HEAD", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "OPTIONS", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "OPTIONS", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "PATCH", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "PATCH", "(URI,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "POST", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "POST", "(URI,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "PUT", "(String,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http", "HttpRequest", True, "PUT", "(URI,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.cookie", "Cookie", True, "getDomain", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.cookie", "Cookie", True, "getName", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.cookie", "Cookie", True, "getPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.cookie", "Cookie", True, "getValue", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.cookie", "Cookies", True, "findCookie", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.cookie", "Cookies", True, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.cookie", "Cookies", True, "getAll", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.cookie", "Cookies", True, "findCookie", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.cookie", "Cookie", True, "getValue", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.cookie", "Cookie", True, "getName", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.cookie", "Cookie", True, "getDomain", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.cookie", "Cookie", True, "getPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["io.micronaut.http", "MutableHttpResponse", True, "header", "(CharSequence,CharSequence)", "", "Argument[1]", "response-splitting", "manual"]
|
||||
- ["io.micronaut.http", "HttpResponse", True, "permanentRedirect", "(URI)", "", "Argument[0]", "url-redirection", "manual"]
|
||||
- ["io.micronaut.http", "HttpResponse", True, "redirect", "(URI)", "", "Argument[0]", "url-redirection", "manual"]
|
||||
- ["io.micronaut.http", "HttpResponse", True, "seeOther", "(URI)", "", "Argument[0]", "url-redirection", "manual"]
|
||||
- ["io.micronaut.http", "HttpResponse", True, "temporaryRedirect", "(URI)", "", "Argument[0]", "url-redirection", "manual"]
|
||||
- ["io.micronaut.http", "MutableHttpResponse", True, "header", "(CharSequence,CharSequence)", "", "Argument[1]", "response-splitting", "manual"]
|
||||
- ["io.micronaut.http", "MutableHttpResponse", True, "headers", "(Map)", "", "Argument[0]", "response-splitting", "manual"]
|
||||
|
||||
28
java/ql/lib/ext/io.micronaut.http.uri.model.yml
Normal file
28
java/ql/lib/ext/io.micronaut.http.uri.model.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "build", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "expand", "(Map)", "", "Argument[0].MapValue", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "expand", "(Map)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "fragment", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "fragment", "(String)", "", "Argument[this]", "ReturnValue", "value", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "host", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "host", "(String)", "", "Argument[this]", "ReturnValue", "value", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "of", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "of", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "path", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "path", "(String)", "", "Argument[this]", "ReturnValue", "value", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "queryParam", "(String,Object[])", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "queryParam", "(String,Object[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "queryParam", "(String,Object[])", "", "Argument[this]", "ReturnValue", "value", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "replacePath", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "replacePath", "(String)", "", "Argument[this]", "ReturnValue", "value", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "replaceQueryParam", "(String,Object[])", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "replaceQueryParam", "(String,Object[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "replaceQueryParam", "(String,Object[])", "", "Argument[this]", "ReturnValue", "value", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "scheme", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "scheme", "(String)", "", "Argument[this]", "ReturnValue", "value", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "userInfo", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["io.micronaut.http.uri", "UriBuilder", True, "userInfo", "(String)", "", "Argument[this]", "ReturnValue", "value", "manual"]
|
||||
@@ -32,7 +32,6 @@ import semmle.code.java.frameworks.Thrift
|
||||
import semmle.code.java.frameworks.javaee.jsf.JSFRenderer
|
||||
import semmle.code.java.frameworks.micronaut.MicronautController
|
||||
import semmle.code.java.frameworks.micronaut.MicronautWebSocket
|
||||
import semmle.code.java.frameworks.micronaut.MicronautConfig
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
private import codeql.threatmodels.ThreatModels
|
||||
|
||||
@@ -204,16 +203,6 @@ private class MicronautWebSocketParameterSource extends RemoteFlowSource {
|
||||
override string getSourceType() { result = "Micronaut WebSocket parameter" }
|
||||
}
|
||||
|
||||
private class MicronautConfigSource extends LocalUserInput {
|
||||
MicronautConfigSource() {
|
||||
this.asExpr() = any(MicronautConfigField f).getAnAccess()
|
||||
or
|
||||
this.asParameter() instanceof MicronautConfigParameter
|
||||
}
|
||||
|
||||
override string getThreatModel() { result = "environment" }
|
||||
}
|
||||
|
||||
private class MicronautErrorHandlerSource extends RemoteFlowSource {
|
||||
MicronautErrorHandlerSource() {
|
||||
this.asParameter() = any(MicronautErrorHandler h).getARemoteParameter()
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/** Provides classes for identifying Micronaut configuration injection sources. */
|
||||
overlay[local?]
|
||||
module;
|
||||
|
||||
import java
|
||||
|
||||
/** The annotation type `@Value` from `io.micronaut.context.annotation`. */
|
||||
class MicronautValueAnnotation extends AnnotationType {
|
||||
MicronautValueAnnotation() { this.hasQualifiedName("io.micronaut.context.annotation", "Value") }
|
||||
}
|
||||
|
||||
/** The annotation type `@Property` from `io.micronaut.context.annotation`. */
|
||||
class MicronautPropertyAnnotation extends AnnotationType {
|
||||
MicronautPropertyAnnotation() {
|
||||
this.hasQualifiedName("io.micronaut.context.annotation", "Property")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A field annotated with Micronaut's `@Value` or `@Property` annotation,
|
||||
* representing an injected configuration value.
|
||||
*/
|
||||
class MicronautConfigField extends Field {
|
||||
MicronautConfigField() {
|
||||
this.getAnAnnotation().getType() instanceof MicronautValueAnnotation
|
||||
or
|
||||
this.getAnAnnotation().getType() instanceof MicronautPropertyAnnotation
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A parameter annotated with Micronaut's `@Value` or `@Property` annotation,
|
||||
* representing an injected configuration value.
|
||||
*/
|
||||
class MicronautConfigParameter extends Parameter {
|
||||
MicronautConfigParameter() {
|
||||
this.getAnAnnotation().getType() instanceof MicronautValueAnnotation
|
||||
or
|
||||
this.getAnAnnotation().getType() instanceof MicronautPropertyAnnotation
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,25 @@ class MicronautHttpInputAnnotation extends Annotation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if `parameter` is explicitly bound to remote HTTP request data. */
|
||||
private predicate isExplicitlyTaintedInput(Parameter parameter) {
|
||||
parameter.getAnAnnotation() instanceof MicronautHttpInputAnnotation
|
||||
or
|
||||
parameter.getAnAnnotation().getType() instanceof MicronautRequestBeanAnnotation
|
||||
or
|
||||
parameter
|
||||
.getType()
|
||||
.(RefType)
|
||||
.getASourceSupertype*()
|
||||
.hasQualifiedName("io.micronaut.http", ["HttpRequest", "HttpHeaders", "HttpParameters"])
|
||||
or
|
||||
parameter
|
||||
.getType()
|
||||
.(RefType)
|
||||
.getASourceSupertype*()
|
||||
.hasQualifiedName("io.micronaut.http.cookie", "Cookies")
|
||||
}
|
||||
|
||||
/** A parameter of a `MicronautRequestMappingMethod`. */
|
||||
class MicronautRequestMappingParameter extends Parameter {
|
||||
MicronautRequestMappingParameter() { this.getCallable() instanceof MicronautRequestMappingMethod }
|
||||
@@ -67,11 +86,6 @@ class MicronautRequestMappingParameter extends Parameter {
|
||||
predicate isNotDirectlyTaintedInput() {
|
||||
this.getType().(RefType).getAnAncestor().hasQualifiedName("io.micronaut.http", "HttpResponse")
|
||||
or
|
||||
this.getType()
|
||||
.(RefType)
|
||||
.getAnAncestor()
|
||||
.hasQualifiedName("io.micronaut.http", "MutableHttpResponse")
|
||||
or
|
||||
this.getType().(RefType).getAnAncestor().hasQualifiedName("java.security", "Principal")
|
||||
or
|
||||
this.getType().(RefType).getAnAncestor().hasQualifiedName("java.util", "Locale")
|
||||
@@ -80,35 +94,19 @@ class MicronautRequestMappingParameter extends Parameter {
|
||||
or
|
||||
this.getType().(RefType).getAnAncestor().hasQualifiedName("java.time", "ZoneId")
|
||||
or
|
||||
this.getType().(RefType).getAnAncestor() instanceof TypeInputStream
|
||||
or
|
||||
this.getType().(RefType).getAnAncestor().hasQualifiedName("java.io", "Reader")
|
||||
or
|
||||
// @Value/@Property parameters are configuration injection, not HTTP input
|
||||
this.getAnAnnotation()
|
||||
.getType()
|
||||
.hasQualifiedName("io.micronaut.context.annotation", ["Value", "Property"])
|
||||
}
|
||||
|
||||
private predicate isExplicitlyTaintedInput() {
|
||||
// The MicronautHttpInputAnnotation allows access to the URI path,
|
||||
// request parameters, cookie values, headers, and the body of the request.
|
||||
this.getAnAnnotation() instanceof MicronautHttpInputAnnotation
|
||||
or
|
||||
// A @RequestBean parameter binds multiple request attributes into a POJO
|
||||
this.getAnAnnotation().getType() instanceof MicronautRequestBeanAnnotation
|
||||
or
|
||||
// An HttpRequest parameter provides access to request data
|
||||
this.getType()
|
||||
.(RefType)
|
||||
.getASourceSupertype*()
|
||||
.hasQualifiedName("io.micronaut.http", "HttpRequest")
|
||||
or
|
||||
// InputStream or Reader parameters allow access to the body of a request
|
||||
this.getType().(RefType).getAnAncestor() instanceof TypeInputStream
|
||||
or
|
||||
this.getType().(RefType).getAnAncestor().hasQualifiedName("java.io", "Reader")
|
||||
}
|
||||
|
||||
/** Holds if the input is tainted (i.e. comes from user-controlled input). */
|
||||
predicate isTaintedInput() {
|
||||
this.isExplicitlyTaintedInput()
|
||||
isExplicitlyTaintedInput(this)
|
||||
or
|
||||
not this.isNotDirectlyTaintedInput()
|
||||
}
|
||||
@@ -126,11 +124,7 @@ class MicronautErrorHandler extends Method {
|
||||
/** Gets a parameter that carries user-controlled request data. */
|
||||
Parameter getARemoteParameter() {
|
||||
result = this.getAParameter() and
|
||||
result
|
||||
.getType()
|
||||
.(RefType)
|
||||
.getASourceSupertype*()
|
||||
.hasQualifiedName("io.micronaut.http", "HttpRequest")
|
||||
isExplicitlyTaintedInput(result)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class MicronautServerWebSocketClass extends Class {
|
||||
class MicronautWebSocketHandlerAnnotation extends AnnotationType {
|
||||
MicronautWebSocketHandlerAnnotation() {
|
||||
this.getPackage().hasName("io.micronaut.websocket.annotation") and
|
||||
this.hasName(["OnMessage", "OnOpen"])
|
||||
this.hasName(["OnClose", "OnMessage", "OnOpen"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ class MicronautWebSocketMessageHandler extends Method {
|
||||
class MicronautWebSocketParameter extends Parameter {
|
||||
MicronautWebSocketParameter() {
|
||||
this.getCallable() instanceof MicronautWebSocketMessageHandler and
|
||||
// Exclude WebSocketSession parameters
|
||||
// Exclude framework-provided WebSocket lifecycle parameters
|
||||
not this.getType()
|
||||
.(RefType)
|
||||
.getAnAncestor()
|
||||
.hasQualifiedName("io.micronaut.websocket", "WebSocketSession")
|
||||
.hasQualifiedName("io.micronaut.websocket", ["CloseReason", "WebSocketSession"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import io.micronaut.context.annotation.Value;
|
||||
import io.micronaut.context.annotation.Property;
|
||||
import io.micronaut.http.annotation.*;
|
||||
|
||||
@Controller("/config")
|
||||
class MicronautConfigTest {
|
||||
|
||||
void sink(Object o) {}
|
||||
|
||||
@Value("${app.secret}")
|
||||
String secretValue;
|
||||
|
||||
@Property(name = "app.api-key")
|
||||
String apiKey;
|
||||
|
||||
@Get("/secret")
|
||||
void testValueField() {
|
||||
sink(secretValue); // $hasTaintFlow
|
||||
}
|
||||
|
||||
@Get("/key")
|
||||
void testPropertyField() {
|
||||
sink(apiKey); // $hasTaintFlow
|
||||
}
|
||||
|
||||
@Get("/param")
|
||||
void testValueParam(@Value("${app.name}") String appName) {
|
||||
sink(appName); // $hasTaintFlow
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import io.micronaut.http.annotation.*;
|
||||
import io.micronaut.http.*;
|
||||
import io.micronaut.http.cookie.Cookies;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
@@ -58,14 +59,29 @@ class MicronautControllerTest {
|
||||
sink(request); // $hasTaintFlow
|
||||
}
|
||||
|
||||
@Get("/headers")
|
||||
void testHttpHeaders(HttpHeaders headers) {
|
||||
sink(headers); // $hasTaintFlow
|
||||
}
|
||||
|
||||
@Get("/parameters")
|
||||
void testHttpParameters(HttpParameters parameters) {
|
||||
sink(parameters); // $hasTaintFlow
|
||||
}
|
||||
|
||||
@Get("/cookies")
|
||||
void testCookies(Cookies cookies) {
|
||||
sink(cookies); // $hasTaintFlow
|
||||
}
|
||||
|
||||
@Post("/stream")
|
||||
void testInputStream(InputStream stream) {
|
||||
void testInputStream(@Body InputStream stream) {
|
||||
sink(stream); // $hasTaintFlow
|
||||
}
|
||||
|
||||
@Post("/reader")
|
||||
void testReader(Reader reader) {
|
||||
sink(reader); // $hasTaintFlow
|
||||
sink(reader);
|
||||
}
|
||||
|
||||
@Post("/post")
|
||||
@@ -92,4 +108,17 @@ class MicronautControllerTest {
|
||||
void testErrorHandler(HttpRequest<?> request) {
|
||||
sink(request); // $hasTaintFlow
|
||||
}
|
||||
|
||||
@io.micronaut.http.annotation.Error
|
||||
void testAnnotatedErrorHandler(@Header String header, @RequestBean Object bean) {
|
||||
sink(header); // $hasTaintFlow
|
||||
sink(bean); // $hasTaintFlow
|
||||
}
|
||||
|
||||
@io.micronaut.http.annotation.Error
|
||||
void testErrorHandlerCarriers(HttpHeaders headers, HttpParameters parameters, Cookies cookies) {
|
||||
sink(headers); // $hasTaintFlow
|
||||
sink(parameters); // $hasTaintFlow
|
||||
sink(cookies); // $hasTaintFlow
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@ import io.micronaut.http.*;
|
||||
import io.micronaut.http.client.HttpClient;
|
||||
import io.micronaut.http.client.BlockingHttpClient;
|
||||
import io.micronaut.http.uri.UriBuilder;
|
||||
import io.micronaut.core.type.Argument;
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
|
||||
class MicronautHttpClientTest {
|
||||
|
||||
@@ -34,6 +36,39 @@ class MicronautHttpClientTest {
|
||||
client.toBlocking().exchange(url, String.class); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testRetrieveStringClassClass() {
|
||||
client.toBlocking().retrieve(taint(), String.class, Object.class); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testExchangeStringClassClass() {
|
||||
client.toBlocking().exchange(taint(), String.class, Object.class); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testBlockingRequest() {
|
||||
client.toBlocking().retrieve(HttpRequest.GET(taint())); // $hasTaintFlow
|
||||
client.toBlocking().retrieve(HttpRequest.GET(taint()), String.class); // $hasTaintFlow
|
||||
client.toBlocking().retrieve(HttpRequest.GET(taint()), new Argument<String>()); // $hasTaintFlow
|
||||
client.toBlocking().retrieve(HttpRequest.GET(taint()), new Argument<String>(), new Argument<Object>()); // $hasTaintFlow
|
||||
client.toBlocking().exchange(HttpRequest.GET(taint())); // $hasTaintFlow
|
||||
client.toBlocking().exchange(HttpRequest.GET(taint()), String.class); // $hasTaintFlow
|
||||
client.toBlocking().exchange(HttpRequest.GET(taint()), new Argument<String>()); // $hasTaintFlow
|
||||
client.toBlocking().exchange(HttpRequest.GET(taint()), new Argument<String>(), new Argument<Object>()); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testNonBlockingClient() {
|
||||
client.retrieve(taint()); // $hasTaintFlow
|
||||
client.exchange(taint()); // $hasTaintFlow
|
||||
client.exchange(taint(), String.class); // $hasTaintFlow
|
||||
client.retrieve(HttpRequest.GET(taint())); // $hasTaintFlow
|
||||
client.retrieve(HttpRequest.GET(taint()), String.class); // $hasTaintFlow
|
||||
client.retrieve(HttpRequest.GET(taint()), new Argument<String>()); // $hasTaintFlow
|
||||
client.retrieve(HttpRequest.GET(taint()), new Argument<String>(), new Argument<Object>()); // $hasTaintFlow
|
||||
client.exchange(HttpRequest.GET(taint())); // $hasTaintFlow
|
||||
client.exchange(HttpRequest.GET(taint()), String.class); // $hasTaintFlow
|
||||
client.exchange(HttpRequest.GET(taint()), new Argument<String>()); // $hasTaintFlow
|
||||
client.exchange(HttpRequest.GET(taint()), new Argument<String>(), new Argument<Object>()); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testGetFactory() {
|
||||
HttpRequest<?> req = HttpRequest.GET(taint());
|
||||
sink(req); // $hasTaintFlow
|
||||
@@ -69,6 +104,21 @@ class MicronautHttpClientTest {
|
||||
sink(req); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testUriFactories() {
|
||||
sink(HttpRequest.GET(URI.create(taint()))); // $hasTaintFlow
|
||||
sink(HttpRequest.POST(URI.create(taint()), "body")); // $hasTaintFlow
|
||||
sink(HttpRequest.PUT(URI.create(taint()), "body")); // $hasTaintFlow
|
||||
sink(HttpRequest.DELETE(URI.create(taint()))); // $hasTaintFlow
|
||||
sink(HttpRequest.DELETE(URI.create(taint()), "body")); // $hasTaintFlow
|
||||
sink(HttpRequest.PATCH(URI.create(taint()), "body")); // $hasTaintFlow
|
||||
sink(HttpRequest.HEAD(URI.create(taint()))); // $hasTaintFlow
|
||||
sink(HttpRequest.OPTIONS(URI.create(taint()))); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testDeleteFactoryWithBody() {
|
||||
sink(HttpRequest.DELETE(taint(), "body")); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testUriBuilderOfCharSequence() {
|
||||
URI uri = UriBuilder.of(taint()).build();
|
||||
sink(uri); // $hasTaintFlow
|
||||
@@ -103,4 +153,32 @@ class MicronautHttpClientTest {
|
||||
URI uri = UriBuilder.of("http://example.com").fragment(taint()).build();
|
||||
sink(uri); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testUriBuilderMutation() {
|
||||
UriBuilder builder = UriBuilder.of("http://example.com");
|
||||
builder.host(taint());
|
||||
sink(builder.build()); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testUriBuilderReplaceQueryParam() {
|
||||
URI uri = UriBuilder.of("http://example.com").replaceQueryParam("key", taint()).build();
|
||||
sink(uri); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testUriBuilderAdditionalFluentMethods() {
|
||||
sink(UriBuilder.of("http://example.com").scheme(taint()).build()); // $hasTaintFlow
|
||||
sink(UriBuilder.of("http://example.com").userInfo(taint()).build()); // $hasTaintFlow
|
||||
sink(UriBuilder.of("http://example.com").replacePath(taint()).build()); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testUriBuilderExpandBuilder() {
|
||||
URI uri = UriBuilder.of(taint()).expand(Collections.singletonMap("id", "value"));
|
||||
sink(uri); // $hasTaintFlow
|
||||
}
|
||||
|
||||
void testUriBuilderExpandValue() {
|
||||
URI uri = UriBuilder.of("http://example.com/{id}")
|
||||
.expand(Collections.singletonMap("id", taint()));
|
||||
sink(uri); // $hasTaintFlow
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import io.micronaut.http.annotation.*;
|
||||
import io.micronaut.http.*;
|
||||
import io.micronaut.http.cookie.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Controller("/http")
|
||||
class MicronautHttpRequestTest {
|
||||
@@ -11,17 +13,27 @@ class MicronautHttpRequestTest {
|
||||
void testHeaders(HttpRequest<?> request) {
|
||||
sink(request.getHeaders()); // $hasTaintFlow
|
||||
sink(request.getHeaders().get("X-Custom")); // $hasTaintFlow
|
||||
sink(request.getHeaders().getAll("X-Custom")); // $hasTaintFlow
|
||||
sink(request.getHeaders().getFirst("X-Custom")); // $hasTaintFlow
|
||||
sink(request.getHeaders().values()); // $hasTaintFlow
|
||||
sink(request.getHeaders().getAll("X-Custom").get(0)); // $hasTaintFlow
|
||||
sink(request.getHeaders().getFirst("X-Custom").get()); // $hasTaintFlow
|
||||
sink(request.getHeaders().getValue("X-Custom").get(0)); // $hasTaintFlow
|
||||
sink(request.getHeaders().values().iterator().next().get(0)); // $hasTaintFlow
|
||||
sink(request.getHeaders().asMap().get("X-Custom").get(0)); // $hasTaintFlow
|
||||
sink(request.getHeaders().asProperties().get("X-Custom")); // $hasTaintFlow
|
||||
sink(request.getHeaders().subMap("X", List.class).get("Custom").get(0)); // $hasTaintFlow
|
||||
for (Map.Entry<String, List<String>> header : request.getHeaders()) {
|
||||
sink(header.getValue().get(0)); // $hasTaintFlow
|
||||
}
|
||||
}
|
||||
|
||||
@Get("/params")
|
||||
void testParameters(HttpRequest<?> request) {
|
||||
sink(request.getParameters()); // $hasTaintFlow
|
||||
sink(request.getParameters().get("q")); // $hasTaintFlow
|
||||
sink(request.getParameters().getAll("q")); // $hasTaintFlow
|
||||
sink(request.getParameters().getFirst("q")); // $hasTaintFlow
|
||||
sink(request.getParameters().getAll("q").get(0)); // $hasTaintFlow
|
||||
sink(request.getParameters().getFirst("q").get()); // $hasTaintFlow
|
||||
sink(request.getParameters().getValue("q").get(0)); // $hasTaintFlow
|
||||
sink(request.getParameters().values().iterator().next().get(0)); // $hasTaintFlow
|
||||
sink(request.getParameters().asMap().get("q").get(0)); // $hasTaintFlow
|
||||
}
|
||||
|
||||
@Get("/cookies")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import io.micronaut.websocket.annotation.*;
|
||||
import io.micronaut.websocket.CloseReason;
|
||||
import io.micronaut.websocket.WebSocketSession;
|
||||
|
||||
@ServerWebSocket("/chat/{room}")
|
||||
@@ -15,4 +16,11 @@ class MicronautWebSocketTest {
|
||||
void onOpen(String room, WebSocketSession session) {
|
||||
sink(room); // $hasTaintFlow
|
||||
}
|
||||
|
||||
@OnClose
|
||||
void onClose(String room, CloseReason reason, WebSocketSession session) {
|
||||
sink(room); // $hasTaintFlow
|
||||
sink(reason);
|
||||
sink(session);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import io.micronaut.http.annotation.Get;
|
||||
import io.micronaut.http.annotation.QueryValue;
|
||||
import io.micronaut.http.HttpResponse;
|
||||
import io.micronaut.http.MutableHttpResponse;
|
||||
import java.util.Collections;
|
||||
|
||||
@Controller("/headers")
|
||||
public class MicronautResponseSplitting {
|
||||
@@ -19,4 +20,10 @@ public class MicronautResponseSplitting {
|
||||
String sanitized = headerValue.replace('\n', ' ').replace('\r', ' ');
|
||||
return HttpResponse.ok().header("X-Custom", sanitized);
|
||||
}
|
||||
|
||||
@Get("/bad-map")
|
||||
public MutableHttpResponse<?> badMap(@QueryValue String headerValue) {
|
||||
// BAD: user-controlled header value
|
||||
return HttpResponse.ok().headers(Collections.singletonMap("X-Custom", headerValue));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,33 @@
|
||||
#select
|
||||
| MicronautResponseSplitting.java:13:53:13:63 | headerValue | MicronautResponseSplitting.java:11:39:11:68 | headerValue : String | MicronautResponseSplitting.java:13:53:13:63 | headerValue | This header depends on a $@, which may cause a response-splitting vulnerability. | MicronautResponseSplitting.java:11:39:11:68 | headerValue | user-provided value |
|
||||
| MicronautResponseSplitting.java:14:53:14:63 | headerValue | MicronautResponseSplitting.java:12:39:12:68 | headerValue : String | MicronautResponseSplitting.java:14:53:14:63 | headerValue | This header depends on a $@, which may cause a response-splitting vulnerability. | MicronautResponseSplitting.java:12:39:12:68 | headerValue | user-provided value |
|
||||
| MicronautResponseSplitting.java:27:42:27:90 | singletonMap(...) | MicronautResponseSplitting.java:25:42:25:71 | headerValue : String | MicronautResponseSplitting.java:27:42:27:90 | singletonMap(...) | This header depends on a $@, which may cause a response-splitting vulnerability. | MicronautResponseSplitting.java:25:42:25:71 | headerValue | user-provided value |
|
||||
| ResponseSplitting.java:23:23:23:28 | cookie | ResponseSplitting.java:22:39:22:66 | getParameter(...) : String | ResponseSplitting.java:23:23:23:28 | cookie | This header depends on a $@, which may cause a response-splitting vulnerability. | ResponseSplitting.java:22:39:22:66 | getParameter(...) | user-provided value |
|
||||
| ResponseSplitting.java:28:38:28:72 | getParameter(...) | ResponseSplitting.java:28:38:28:72 | getParameter(...) | ResponseSplitting.java:28:38:28:72 | getParameter(...) | This header depends on a $@, which may cause a response-splitting vulnerability. | ResponseSplitting.java:28:38:28:72 | getParameter(...) | user-provided value |
|
||||
| ResponseSplitting.java:29:38:29:72 | getParameter(...) | ResponseSplitting.java:29:38:29:72 | getParameter(...) | ResponseSplitting.java:29:38:29:72 | getParameter(...) | This header depends on a $@, which may cause a response-splitting vulnerability. | ResponseSplitting.java:29:38:29:72 | getParameter(...) | user-provided value |
|
||||
| ResponseSplitting.java:59:27:59:57 | replaceFirst(...) | ResponseSplitting.java:53:14:53:48 | getParameter(...) : String | ResponseSplitting.java:59:27:59:57 | replaceFirst(...) | This header depends on a $@, which may cause a response-splitting vulnerability. | ResponseSplitting.java:53:14:53:48 | getParameter(...) | user-provided value |
|
||||
edges
|
||||
| MicronautResponseSplitting.java:11:39:11:68 | headerValue : String | MicronautResponseSplitting.java:13:53:13:63 | headerValue | provenance | Sink:MaD:1 |
|
||||
| ResponseSplitting.java:22:20:22:67 | new Cookie(...) : Cookie | ResponseSplitting.java:23:23:23:28 | cookie | provenance | Sink:MaD:2 |
|
||||
| ResponseSplitting.java:22:39:22:66 | getParameter(...) : String | ResponseSplitting.java:22:20:22:67 | new Cookie(...) : Cookie | provenance | Src:MaD:4 MaD:6 |
|
||||
| ResponseSplitting.java:53:14:53:48 | getParameter(...) : String | ResponseSplitting.java:59:27:59:27 | t : String | provenance | Src:MaD:4 |
|
||||
| ResponseSplitting.java:59:27:59:27 | t : String | ResponseSplitting.java:59:27:59:57 | replaceFirst(...) | provenance | MaD:5 Sink:MaD:3 |
|
||||
| MicronautResponseSplitting.java:12:39:12:68 | headerValue : String | MicronautResponseSplitting.java:14:53:14:63 | headerValue | provenance | Sink:MaD:1 |
|
||||
| MicronautResponseSplitting.java:25:42:25:71 | headerValue : String | MicronautResponseSplitting.java:27:79:27:89 | headerValue : String | provenance | |
|
||||
| MicronautResponseSplitting.java:27:79:27:89 | headerValue : String | MicronautResponseSplitting.java:27:42:27:90 | singletonMap(...) | provenance | MaD:7 Sink:MaD:2 |
|
||||
| ResponseSplitting.java:22:20:22:67 | new Cookie(...) : Cookie | ResponseSplitting.java:23:23:23:28 | cookie | provenance | Sink:MaD:3 |
|
||||
| ResponseSplitting.java:22:39:22:66 | getParameter(...) : String | ResponseSplitting.java:22:20:22:67 | new Cookie(...) : Cookie | provenance | Src:MaD:5 MaD:8 |
|
||||
| ResponseSplitting.java:53:14:53:48 | getParameter(...) : String | ResponseSplitting.java:59:27:59:27 | t : String | provenance | Src:MaD:5 |
|
||||
| ResponseSplitting.java:59:27:59:27 | t : String | ResponseSplitting.java:59:27:59:57 | replaceFirst(...) | provenance | MaD:6 Sink:MaD:4 |
|
||||
models
|
||||
| 1 | Sink: io.micronaut.http; MutableHttpResponse; true; header; (CharSequence,CharSequence); ; Argument[1]; response-splitting; manual |
|
||||
| 2 | Sink: javax.servlet.http; HttpServletResponse; false; addCookie; ; ; Argument[0]; response-splitting; manual |
|
||||
| 3 | Sink: javax.servlet.http; HttpServletResponse; false; setHeader; ; ; Argument[0..1]; response-splitting; manual |
|
||||
| 4 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual |
|
||||
| 5 | Summary: java.lang; String; false; replaceFirst; ; ; Argument[this]; ReturnValue; taint; manual |
|
||||
| 6 | Summary: javax.servlet.http; Cookie; false; Cookie; ; ; Argument[1]; Argument[this]; taint; manual |
|
||||
| 2 | Sink: io.micronaut.http; MutableHttpResponse; true; headers; (Map); ; Argument[0]; response-splitting; manual |
|
||||
| 3 | Sink: javax.servlet.http; HttpServletResponse; false; addCookie; ; ; Argument[0]; response-splitting; manual |
|
||||
| 4 | Sink: javax.servlet.http; HttpServletResponse; false; setHeader; ; ; Argument[0..1]; response-splitting; manual |
|
||||
| 5 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual |
|
||||
| 6 | Summary: java.lang; String; false; replaceFirst; ; ; Argument[this]; ReturnValue; taint; manual |
|
||||
| 7 | Summary: java.util; Collections; false; singletonMap; (Object,Object); ; Argument[1]; ReturnValue.MapValue; value; manual |
|
||||
| 8 | Summary: javax.servlet.http; Cookie; false; Cookie; ; ; Argument[1]; Argument[this]; taint; manual |
|
||||
nodes
|
||||
| MicronautResponseSplitting.java:11:39:11:68 | headerValue : String | semmle.label | headerValue : String |
|
||||
| MicronautResponseSplitting.java:13:53:13:63 | headerValue | semmle.label | headerValue |
|
||||
| MicronautResponseSplitting.java:12:39:12:68 | headerValue : String | semmle.label | headerValue : String |
|
||||
| MicronautResponseSplitting.java:14:53:14:63 | headerValue | semmle.label | headerValue |
|
||||
| MicronautResponseSplitting.java:25:42:25:71 | headerValue : String | semmle.label | headerValue : String |
|
||||
| MicronautResponseSplitting.java:27:42:27:90 | singletonMap(...) | semmle.label | singletonMap(...) |
|
||||
| MicronautResponseSplitting.java:27:79:27:89 | headerValue : String | semmle.label | headerValue : String |
|
||||
| ResponseSplitting.java:22:20:22:67 | new Cookie(...) : Cookie | semmle.label | new Cookie(...) : Cookie |
|
||||
| ResponseSplitting.java:22:39:22:66 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| ResponseSplitting.java:23:23:23:28 | cookie | semmle.label | cookie |
|
||||
|
||||
@@ -22,4 +22,19 @@ public class MicronautUrlRedirect {
|
||||
}
|
||||
return HttpResponse.ok();
|
||||
}
|
||||
|
||||
@Get("/permanent")
|
||||
public MutableHttpResponse<?> permanent(@QueryValue String target) {
|
||||
return HttpResponse.permanentRedirect(URI.create(target));
|
||||
}
|
||||
|
||||
@Get("/see-other")
|
||||
public MutableHttpResponse<?> seeOther(@QueryValue String target) {
|
||||
return HttpResponse.seeOther(URI.create(target));
|
||||
}
|
||||
|
||||
@Get("/temporary")
|
||||
public MutableHttpResponse<?> temporary(@QueryValue String target) {
|
||||
return HttpResponse.temporaryRedirect(URI.create(target));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#select
|
||||
| MicronautUrlRedirect.java:14:38:14:55 | create(...) | MicronautUrlRedirect.java:12:39:12:63 | target : String | MicronautUrlRedirect.java:14:38:14:55 | create(...) | Untrusted URL redirection depends on a $@. | MicronautUrlRedirect.java:12:39:12:63 | target | user-provided value |
|
||||
| MicronautUrlRedirect.java:28:47:28:64 | create(...) | MicronautUrlRedirect.java:27:45:27:69 | target : String | MicronautUrlRedirect.java:28:47:28:64 | create(...) | Untrusted URL redirection depends on a $@. | MicronautUrlRedirect.java:27:45:27:69 | target | user-provided value |
|
||||
| MicronautUrlRedirect.java:33:38:33:55 | create(...) | MicronautUrlRedirect.java:32:44:32:68 | target : String | MicronautUrlRedirect.java:33:38:33:55 | create(...) | Untrusted URL redirection depends on a $@. | MicronautUrlRedirect.java:32:44:32:68 | target | user-provided value |
|
||||
| MicronautUrlRedirect.java:38:47:38:64 | create(...) | MicronautUrlRedirect.java:37:45:37:69 | target : String | MicronautUrlRedirect.java:38:47:38:64 | create(...) | Untrusted URL redirection depends on a $@. | MicronautUrlRedirect.java:37:45:37:69 | target | user-provided value |
|
||||
| UrlRedirect2.java:27:25:27:54 | getParameter(...) | UrlRedirect2.java:27:25:27:54 | getParameter(...) | UrlRedirect2.java:27:25:27:54 | getParameter(...) | Untrusted URL redirection depends on a $@. | UrlRedirect2.java:27:25:27:54 | getParameter(...) | user-provided value |
|
||||
| UrlRedirect.java:23:25:23:54 | getParameter(...) | UrlRedirect.java:23:25:23:54 | getParameter(...) | UrlRedirect.java:23:25:23:54 | getParameter(...) | Untrusted URL redirection depends on a $@. | UrlRedirect.java:23:25:23:54 | getParameter(...) | user-provided value |
|
||||
| UrlRedirect.java:32:25:32:67 | weakCleanup(...) | UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:32:25:32:67 | weakCleanup(...) | Untrusted URL redirection depends on a $@. | UrlRedirect.java:32:37:32:66 | getParameter(...) | user-provided value |
|
||||
@@ -8,23 +11,41 @@
|
||||
| mad/Test.java:14:22:14:38 | (...)... | mad/Test.java:9:16:9:41 | getParameter(...) : String | mad/Test.java:14:22:14:38 | (...)... | Untrusted URL redirection depends on a $@. | mad/Test.java:9:16:9:41 | getParameter(...) | user-provided value |
|
||||
edges
|
||||
| MicronautUrlRedirect.java:12:39:12:63 | target : String | MicronautUrlRedirect.java:14:49:14:54 | target : String | provenance | |
|
||||
| MicronautUrlRedirect.java:14:49:14:54 | target : String | MicronautUrlRedirect.java:14:38:14:55 | create(...) | provenance | MaD:5 Sink:MaD:1 |
|
||||
| UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:32:25:32:67 | weakCleanup(...) | provenance | Src:MaD:3 MaD:4 |
|
||||
| UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:45:28:45:39 | input : String | provenance | Src:MaD:3 |
|
||||
| MicronautUrlRedirect.java:14:49:14:54 | target : String | MicronautUrlRedirect.java:14:38:14:55 | create(...) | provenance | MaD:8 Sink:MaD:2 |
|
||||
| MicronautUrlRedirect.java:27:45:27:69 | target : String | MicronautUrlRedirect.java:28:58:28:63 | target : String | provenance | |
|
||||
| MicronautUrlRedirect.java:28:58:28:63 | target : String | MicronautUrlRedirect.java:28:47:28:64 | create(...) | provenance | MaD:8 Sink:MaD:1 |
|
||||
| MicronautUrlRedirect.java:32:44:32:68 | target : String | MicronautUrlRedirect.java:33:49:33:54 | target : String | provenance | |
|
||||
| MicronautUrlRedirect.java:33:49:33:54 | target : String | MicronautUrlRedirect.java:33:38:33:55 | create(...) | provenance | MaD:8 Sink:MaD:3 |
|
||||
| MicronautUrlRedirect.java:37:45:37:69 | target : String | MicronautUrlRedirect.java:38:58:38:63 | target : String | provenance | |
|
||||
| MicronautUrlRedirect.java:38:58:38:63 | target : String | MicronautUrlRedirect.java:38:47:38:64 | create(...) | provenance | MaD:8 Sink:MaD:4 |
|
||||
| UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:32:25:32:67 | weakCleanup(...) | provenance | Src:MaD:6 MaD:7 |
|
||||
| UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:45:28:45:39 | input : String | provenance | Src:MaD:6 |
|
||||
| UrlRedirect.java:45:28:45:39 | input : String | UrlRedirect.java:46:10:46:14 | input : String | provenance | |
|
||||
| UrlRedirect.java:46:10:46:14 | input : String | UrlRedirect.java:46:10:46:40 | replaceAll(...) : String | provenance | MaD:4 |
|
||||
| mad/Test.java:9:16:9:41 | getParameter(...) : String | mad/Test.java:14:31:14:38 | source(...) : String | provenance | Src:MaD:3 |
|
||||
| mad/Test.java:14:31:14:38 | source(...) : String | mad/Test.java:14:22:14:38 | (...)... | provenance | Sink:MaD:2 |
|
||||
| UrlRedirect.java:46:10:46:14 | input : String | UrlRedirect.java:46:10:46:40 | replaceAll(...) : String | provenance | MaD:7 |
|
||||
| mad/Test.java:9:16:9:41 | getParameter(...) : String | mad/Test.java:14:31:14:38 | source(...) : String | provenance | Src:MaD:6 |
|
||||
| mad/Test.java:14:31:14:38 | source(...) : String | mad/Test.java:14:22:14:38 | (...)... | provenance | Sink:MaD:5 |
|
||||
models
|
||||
| 1 | Sink: io.micronaut.http; HttpResponse; true; redirect; (URI); ; Argument[0]; url-redirection; manual |
|
||||
| 2 | Sink: org.kohsuke.stapler; HttpResponses; true; redirectTo; (String); ; Argument[0]; url-redirection; ai-manual |
|
||||
| 3 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual |
|
||||
| 4 | Summary: java.lang; String; false; replaceAll; ; ; Argument[this]; ReturnValue; taint; manual |
|
||||
| 5 | Summary: java.net; URI; false; create; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 1 | Sink: io.micronaut.http; HttpResponse; true; permanentRedirect; (URI); ; Argument[0]; url-redirection; manual |
|
||||
| 2 | Sink: io.micronaut.http; HttpResponse; true; redirect; (URI); ; Argument[0]; url-redirection; manual |
|
||||
| 3 | Sink: io.micronaut.http; HttpResponse; true; seeOther; (URI); ; Argument[0]; url-redirection; manual |
|
||||
| 4 | Sink: io.micronaut.http; HttpResponse; true; temporaryRedirect; (URI); ; Argument[0]; url-redirection; manual |
|
||||
| 5 | Sink: org.kohsuke.stapler; HttpResponses; true; redirectTo; (String); ; Argument[0]; url-redirection; ai-manual |
|
||||
| 6 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual |
|
||||
| 7 | Summary: java.lang; String; false; replaceAll; ; ; Argument[this]; ReturnValue; taint; manual |
|
||||
| 8 | Summary: java.net; URI; false; create; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
nodes
|
||||
| MicronautUrlRedirect.java:12:39:12:63 | target : String | semmle.label | target : String |
|
||||
| MicronautUrlRedirect.java:14:38:14:55 | create(...) | semmle.label | create(...) |
|
||||
| MicronautUrlRedirect.java:14:49:14:54 | target : String | semmle.label | target : String |
|
||||
| MicronautUrlRedirect.java:27:45:27:69 | target : String | semmle.label | target : String |
|
||||
| MicronautUrlRedirect.java:28:47:28:64 | create(...) | semmle.label | create(...) |
|
||||
| MicronautUrlRedirect.java:28:58:28:63 | target : String | semmle.label | target : String |
|
||||
| MicronautUrlRedirect.java:32:44:32:68 | target : String | semmle.label | target : String |
|
||||
| MicronautUrlRedirect.java:33:38:33:55 | create(...) | semmle.label | create(...) |
|
||||
| MicronautUrlRedirect.java:33:49:33:54 | target : String | semmle.label | target : String |
|
||||
| MicronautUrlRedirect.java:37:45:37:69 | target : String | semmle.label | target : String |
|
||||
| MicronautUrlRedirect.java:38:47:38:64 | create(...) | semmle.label | create(...) |
|
||||
| MicronautUrlRedirect.java:38:58:38:63 | target : String | semmle.label | target : String |
|
||||
| UrlRedirect2.java:27:25:27:54 | getParameter(...) | semmle.label | getParameter(...) |
|
||||
| UrlRedirect.java:23:25:23:54 | getParameter(...) | semmle.label | getParameter(...) |
|
||||
| UrlRedirect.java:32:25:32:67 | weakCleanup(...) | semmle.label | weakCleanup(...) |
|
||||
|
||||
@@ -2,6 +2,7 @@ import io.micronaut.http.annotation.Controller;
|
||||
import io.micronaut.http.annotation.Get;
|
||||
import io.micronaut.http.annotation.QueryValue;
|
||||
import io.micronaut.http.client.HttpClient;
|
||||
import io.micronaut.http.HttpRequest;
|
||||
import io.micronaut.http.uri.UriBuilder;
|
||||
import java.net.URI;
|
||||
|
||||
@@ -30,4 +31,19 @@ public class MicronautSSRF {
|
||||
URI uri = UriBuilder.of("http://example.com").host(host).build();
|
||||
return client.toBlocking().retrieve(uri.toString()); // $ Alert
|
||||
}
|
||||
|
||||
@Get("/blocking-request")
|
||||
public Object testBlockingRequest(@QueryValue String url) { // $ Source
|
||||
return client.toBlocking().exchange(HttpRequest.GET(url)); // $ Alert
|
||||
}
|
||||
|
||||
@Get("/non-blocking")
|
||||
public Object testNonBlocking(@QueryValue String url) { // $ Source
|
||||
return client.exchange(url); // $ Alert
|
||||
}
|
||||
|
||||
@Get("/non-blocking-request")
|
||||
public Object testNonBlockingRequest(@QueryValue String url) { // $ Source
|
||||
return client.exchange(HttpRequest.GET(url)); // $ Alert
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
10
java/ql/test/stubs/micronaut-4.x/io/micronaut/core/convert/value/ConvertibleMultiValues.java
generated
Normal file
10
java/ql/test/stubs/micronaut-4.x/io/micronaut/core/convert/value/ConvertibleMultiValues.java
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
package io.micronaut.core.convert.value;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface ConvertibleMultiValues<V> extends ConvertibleValues<List<V>> {
|
||||
V get(CharSequence name);
|
||||
List<V> getAll(CharSequence name);
|
||||
Optional<V> getFirst(CharSequence name);
|
||||
}
|
||||
15
java/ql/test/stubs/micronaut-4.x/io/micronaut/core/convert/value/ConvertibleValues.java
generated
Normal file
15
java/ql/test/stubs/micronaut-4.x/io/micronaut/core/convert/value/ConvertibleValues.java
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
package io.micronaut.core.convert.value;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public interface ConvertibleValues<V> extends Iterable<Map.Entry<String, V>> {
|
||||
Map<String, V> asMap();
|
||||
Properties asProperties();
|
||||
V getValue(CharSequence name);
|
||||
Iterator<Map.Entry<String, V>> iterator();
|
||||
Map<String, V> subMap(String prefix, Class<?> valueType);
|
||||
Collection<V> values();
|
||||
}
|
||||
4
java/ql/test/stubs/micronaut-4.x/io/micronaut/core/type/Argument.java
generated
Normal file
4
java/ql/test/stubs/micronaut-4.x/io/micronaut/core/type/Argument.java
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
package io.micronaut.core.type;
|
||||
|
||||
public class Argument<T> {
|
||||
}
|
||||
@@ -1,11 +1,6 @@
|
||||
package io.micronaut.http;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import io.micronaut.core.convert.value.ConvertibleMultiValues;
|
||||
|
||||
public interface HttpHeaders {
|
||||
String get(CharSequence name);
|
||||
List<String> getAll(CharSequence name);
|
||||
Optional<String> getFirst(CharSequence name);
|
||||
java.util.Collection<List<String>> values();
|
||||
public interface HttpHeaders extends ConvertibleMultiValues<String> {
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package io.micronaut.http;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import io.micronaut.core.convert.value.ConvertibleMultiValues;
|
||||
|
||||
public interface HttpParameters {
|
||||
String get(CharSequence name);
|
||||
List<String> getAll(CharSequence name);
|
||||
Optional<String> getFirst(CharSequence name);
|
||||
public interface HttpParameters extends ConvertibleMultiValues<String> {
|
||||
}
|
||||
|
||||
@@ -17,10 +17,19 @@ public interface HttpRequest<B> {
|
||||
String getMethodName();
|
||||
|
||||
static <T> HttpRequest<T> GET(String uri) { return null; }
|
||||
static <T> HttpRequest<T> GET(URI uri) { return null; }
|
||||
static <T> HttpRequest<T> POST(String uri, T body) { return null; }
|
||||
static <T> HttpRequest<T> POST(URI uri, T body) { return null; }
|
||||
static <T> HttpRequest<T> PUT(String uri, T body) { return null; }
|
||||
static <T> HttpRequest<T> PUT(URI uri, T body) { return null; }
|
||||
static HttpRequest<?> DELETE(String uri) { return null; }
|
||||
static <T> HttpRequest<T> DELETE(String uri, T body) { return null; }
|
||||
static HttpRequest<?> DELETE(URI uri) { return null; }
|
||||
static <T> HttpRequest<T> DELETE(URI uri, T body) { return null; }
|
||||
static <T> HttpRequest<T> PATCH(String uri, T body) { return null; }
|
||||
static <T> HttpRequest<T> PATCH(URI uri, T body) { return null; }
|
||||
static HttpRequest<?> HEAD(String uri) { return null; }
|
||||
static HttpRequest<?> HEAD(URI uri) { return null; }
|
||||
static HttpRequest<?> OPTIONS(String uri) { return null; }
|
||||
static HttpRequest<?> OPTIONS(URI uri) { return null; }
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ public interface HttpResponse<B> {
|
||||
static <T> MutableHttpResponse<T> ok() { return null; }
|
||||
static <T> MutableHttpResponse<T> ok(T body) { return null; }
|
||||
static MutableHttpResponse<?> redirect(URI location) { return null; }
|
||||
static MutableHttpResponse<?> permanentRedirect(URI location) { return null; }
|
||||
static MutableHttpResponse<?> seeOther(URI location) { return null; }
|
||||
static MutableHttpResponse<?> temporaryRedirect(URI location) { return null; }
|
||||
static MutableHttpResponse<?> notFound() { return null; }
|
||||
static MutableHttpResponse<?> badRequest() { return null; }
|
||||
static MutableHttpResponse<?> serverError() { return null; }
|
||||
|
||||
@@ -2,12 +2,21 @@ package io.micronaut.http.client;
|
||||
|
||||
import io.micronaut.http.HttpRequest;
|
||||
import io.micronaut.http.HttpResponse;
|
||||
import io.micronaut.core.type.Argument;
|
||||
|
||||
public interface BlockingHttpClient {
|
||||
<I, O> HttpResponse<O> exchange(HttpRequest<I> request, Class<O> bodyType);
|
||||
<I, O> HttpResponse<O> exchange(HttpRequest<I> request, Argument<O> bodyType);
|
||||
<I, O, E> HttpResponse<O> exchange(HttpRequest<I> request, Argument<O> bodyType, Argument<E> errorType);
|
||||
<I, O> HttpResponse<O> exchange(HttpRequest<I> request);
|
||||
<I> String retrieve(HttpRequest<I> request);
|
||||
<I, O> O retrieve(HttpRequest<I> request, Class<O> bodyType);
|
||||
<I, O> O retrieve(HttpRequest<I> request, Argument<O> bodyType);
|
||||
<I, O, E> O retrieve(HttpRequest<I> request, Argument<O> bodyType, Argument<E> errorType);
|
||||
String retrieve(String uri);
|
||||
<O> O retrieve(String uri, Class<O> bodyType);
|
||||
<O, E> O retrieve(String uri, Class<O> bodyType, Class<E> errorType);
|
||||
String exchange(String uri);
|
||||
<O> HttpResponse<O> exchange(String uri, Class<O> bodyType);
|
||||
<O, E> HttpResponse<O> exchange(String uri, Class<O> bodyType, Class<E> errorType);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
package io.micronaut.http.client;
|
||||
|
||||
import io.micronaut.http.HttpRequest;
|
||||
import io.micronaut.core.type.Argument;
|
||||
|
||||
public interface HttpClient {
|
||||
BlockingHttpClient toBlocking();
|
||||
Object exchange(HttpRequest<?> request);
|
||||
<O> Object exchange(HttpRequest<?> request, Class<O> bodyType);
|
||||
<O> Object exchange(HttpRequest<?> request, Argument<O> bodyType);
|
||||
<O, E> Object exchange(HttpRequest<?> request, Argument<O> bodyType, Argument<E> errorType);
|
||||
Object exchange(String uri);
|
||||
<O> Object exchange(String uri, Class<O> bodyType);
|
||||
Object retrieve(HttpRequest<?> request);
|
||||
<O> Object retrieve(HttpRequest<?> request, Class<O> bodyType);
|
||||
<O> Object retrieve(HttpRequest<?> request, Argument<O> bodyType);
|
||||
<O, E> Object retrieve(HttpRequest<?> request, Argument<O> bodyType, Argument<E> errorType);
|
||||
Object retrieve(String uri);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.micronaut.http.uri;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
public interface UriBuilder {
|
||||
static UriBuilder of(CharSequence uri) { return null; }
|
||||
@@ -8,6 +9,11 @@ public interface UriBuilder {
|
||||
UriBuilder host(String host);
|
||||
UriBuilder path(String path);
|
||||
UriBuilder queryParam(String name, Object... values);
|
||||
UriBuilder replacePath(String path);
|
||||
UriBuilder replaceQueryParam(String name, Object... values);
|
||||
UriBuilder scheme(String scheme);
|
||||
UriBuilder userInfo(String userInfo);
|
||||
UriBuilder fragment(String fragment);
|
||||
URI build();
|
||||
URI expand(Map<String, ? super Object> values);
|
||||
}
|
||||
|
||||
4
java/ql/test/stubs/micronaut-4.x/io/micronaut/websocket/CloseReason.java
generated
Normal file
4
java/ql/test/stubs/micronaut-4.x/io/micronaut/websocket/CloseReason.java
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
package io.micronaut.websocket;
|
||||
|
||||
public class CloseReason {
|
||||
}
|
||||
Reference in New Issue
Block a user