mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
Merge pull request #5587 from smowton/smowton/admin/promote-ssrf-query
Promote SSRF query from experimental
This commit is contained in:
4
java/change-notes/2021-04-06-ssrf-query.md
Normal file
4
java/change-notes/2021-04-06-ssrf-query.md
Normal file
@@ -0,0 +1,4 @@
|
||||
lgtm,codescanning
|
||||
* The query "Server-side request forgery (SSRF)" (`java/ssrf`) has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @porcupineyhairs](https://github.com/github/codeql/pull/3454).
|
||||
* Models for `URI` and `HttpRequest` in the `java.net` package have been improved. This may lead to more results from any query where these types' methods are relevant.
|
||||
* Models for Apache HttpComponents' `RequestLine` and `BasicRequestLine` types. This may lead to more results from any query where these types' methods are relevant.
|
||||
@@ -5,22 +5,24 @@
|
||||
|
||||
|
||||
<overview>
|
||||
<p>Directly incorporating user input into a HTTP request without validating the input
|
||||
can facilitate Server Side Request Forgery (SSRF) attacks. In these attacks, the server
|
||||
may be tricked into making a request and interacting with an attacker-controlled server.
|
||||
<p>Directly incorporating user input into an HTTP request without validating the input
|
||||
can facilitate server-side request forgery (SSRF) attacks. In these attacks, the server
|
||||
may be tricked into making a request and interacting with an attacker-controlled server.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>To guard against SSRF attacks, it is advisable to avoid putting user input
|
||||
directly into the request URL. Instead, maintain a list of authorized
|
||||
URLs on the server; then choose from that list based on the user input provided.</p>
|
||||
<p>To guard against SSRF attacks, you should avoid putting user-provided input
|
||||
directly into a request URL. Instead, maintain a list of authorized
|
||||
URLs on the server; then choose from that list based on the input provided.
|
||||
Alternatively, ensure requests constructed from user input are limited to
|
||||
a particular host or more restrictive URL prefix.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>The following example shows an HTTP request parameter being used directly in a forming a
|
||||
<p>The following example shows an HTTP request parameter being used directly to form a
|
||||
new request without validating the input, which facilitates SSRF attacks.
|
||||
It also shows how to remedy the problem by validating the user input against a known fixed string.
|
||||
</p>
|
||||
20
java/ql/src/Security/CWE/CWE-918/RequestForgery.ql
Normal file
20
java/ql/src/Security/CWE/CWE-918/RequestForgery.ql
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @name Server-side request forgery
|
||||
* @description Making web requests based on unvalidated user-input
|
||||
* may cause the server to communicate with malicious servers.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/ssrf
|
||||
* @tags security
|
||||
* external/cwe/cwe-918
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.security.RequestForgeryConfig
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, RequestForgeryConfiguration conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Potential server-side request forgery due to $@.",
|
||||
source.getNode(), "a user-provided value"
|
||||
@@ -194,15 +194,6 @@ predicate urlOpen(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
)
|
||||
}
|
||||
|
||||
/** Constructor of `BasicRequestLine` */
|
||||
predicate basicRequestLine(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(ConstructorCall mcc |
|
||||
mcc.getConstructedType().hasQualifiedName("org.apache.http.message", "BasicRequestLine") and
|
||||
mcc.getArgument(1) = node1.asExpr() and // `BasicRequestLine(String method, String uri, ProtocolVersion version)
|
||||
node2.asExpr() = mcc
|
||||
)
|
||||
}
|
||||
|
||||
class BasicAuthFlowConfig extends TaintTracking::Configuration {
|
||||
BasicAuthFlowConfig() { this = "InsecureBasicAuth::BasicAuthFlowConfig" }
|
||||
|
||||
@@ -236,7 +227,6 @@ class BasicAuthFlowConfig extends TaintTracking::Configuration {
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
apacheHttpRequest(node1, node2) or
|
||||
createURI(node1, node2) or
|
||||
basicRequestLine(node1, node2) or
|
||||
createURL(node1, node2) or
|
||||
urlOpen(node1, node2)
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/**
|
||||
* @name Server Side Request Forgery (SSRF)
|
||||
* @description Making web requests based on unvalidated user-input
|
||||
* may cause server to communicate with malicious servers.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/ssrf
|
||||
* @tags security
|
||||
* external/cwe/cwe-918
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import RequestForgery
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class RequestForgeryConfiguration extends TaintTracking::Configuration {
|
||||
RequestForgeryConfiguration() { this = "Server Side Request Forgery" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
requestForgeryStep(pred, succ)
|
||||
}
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, RequestForgeryConfiguration conf
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Potential server side request forgery due to $@.",
|
||||
source.getNode(), "a user-provided value"
|
||||
@@ -1,192 +0,0 @@
|
||||
import java
|
||||
import semmle.code.java.frameworks.Networking
|
||||
import semmle.code.java.frameworks.ApacheHttp
|
||||
import semmle.code.java.frameworks.spring.Spring
|
||||
import semmle.code.java.frameworks.JaxWS
|
||||
import semmle.code.java.frameworks.javase.Http
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
|
||||
predicate requestForgeryStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
// propagate to a URI when its host is assigned to
|
||||
exists(UriCreation c | c.getHostArg() = pred.asExpr() | succ.asExpr() = c)
|
||||
or
|
||||
// propagate to a URL when its host is assigned to
|
||||
exists(UrlConstructorCall c | c.getHostArg() = pred.asExpr() | succ.asExpr() = c)
|
||||
or
|
||||
// propagate to a RequestEntity when its url is assigned to
|
||||
exists(MethodAccess m |
|
||||
m.getMethod().getDeclaringType() instanceof SpringRequestEntity and
|
||||
(
|
||||
m.getMethod().hasName(["get", "post", "head", "delete", "options", "patch", "put"]) and
|
||||
m.getArgument(0) = pred.asExpr() and
|
||||
m = succ.asExpr()
|
||||
or
|
||||
m.getMethod().hasName("method") and
|
||||
m.getArgument(1) = pred.asExpr() and
|
||||
m = succ.asExpr()
|
||||
)
|
||||
)
|
||||
or
|
||||
// propagate from a `RequestEntity<>$BodyBuilder` to a `RequestEntity`
|
||||
// when the builder is tainted
|
||||
exists(MethodAccess m, RefType t |
|
||||
m.getMethod().getDeclaringType() = t and
|
||||
t.hasQualifiedName("org.springframework.http", "RequestEntity<>$BodyBuilder") and
|
||||
m.getMethod().hasName("body") and
|
||||
m.getQualifier() = pred.asExpr() and
|
||||
m = succ.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/** A data flow sink for request forgery vulnerabilities. */
|
||||
abstract class RequestForgerySink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* An argument to an url `openConnection` or `openStream` call
|
||||
* taken as a sink for request forgery vulnerabilities.
|
||||
*/
|
||||
private class UrlOpen extends RequestForgerySink {
|
||||
UrlOpen() {
|
||||
exists(MethodAccess ma |
|
||||
ma.getMethod() instanceof UrlOpenConnectionMethod or
|
||||
ma.getMethod() instanceof UrlOpenStreamMethod
|
||||
|
|
||||
this.asExpr() = ma.getQualifier()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to an Apache `setURI` call taken as a
|
||||
* sink for request forgery vulnerabilities.
|
||||
*/
|
||||
private class ApacheSetUri extends RequestForgerySink {
|
||||
ApacheSetUri() {
|
||||
exists(MethodAccess ma |
|
||||
ma.getReceiverType() instanceof ApacheHttpRequest and
|
||||
ma.getMethod().hasName("setURI")
|
||||
|
|
||||
this.asExpr() = ma.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to any Apache Request Instantiation call taken as a
|
||||
* sink for request forgery vulnerabilities.
|
||||
*/
|
||||
private class ApacheHttpRequestInstantiation extends RequestForgerySink {
|
||||
ApacheHttpRequestInstantiation() {
|
||||
exists(ClassInstanceExpr c | c.getConstructedType() instanceof ApacheHttpRequest |
|
||||
this.asExpr() = c.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to a Apache RequestBuilder method call taken as a
|
||||
* sink for request forgery vulnerabilities.
|
||||
*/
|
||||
private class ApacheHttpRequestBuilderArgument extends RequestForgerySink {
|
||||
ApacheHttpRequestBuilderArgument() {
|
||||
exists(MethodAccess ma |
|
||||
ma.getReceiverType() instanceof TypeApacheHttpRequestBuilder and
|
||||
ma.getMethod().hasName(["setURI", "get", "post", "put", "optons", "head", "delete"])
|
||||
|
|
||||
this.asExpr() = ma.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to any Java.net.http.request Instantiation call taken as a
|
||||
* sink for request forgery vulnerabilities.
|
||||
*/
|
||||
private class HttpRequestNewBuilder extends RequestForgerySink {
|
||||
HttpRequestNewBuilder() {
|
||||
exists(MethodAccess call |
|
||||
call.getCallee().hasName("newBuilder") and
|
||||
call.getMethod().getDeclaringType().getName() = "HttpRequest"
|
||||
|
|
||||
this.asExpr() = call.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to an Http Builder `uri` call taken as a
|
||||
* sink for request forgery vulnerabilities.
|
||||
*/
|
||||
private class HttpBuilderUriArgument extends RequestForgerySink {
|
||||
HttpBuilderUriArgument() {
|
||||
exists(MethodAccess ma | ma.getMethod() instanceof HttpBuilderUri |
|
||||
this.asExpr() = ma.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to a Spring Rest Template method call taken as a
|
||||
* sink for request forgery vulnerabilities.
|
||||
*/
|
||||
private class SpringRestTemplateArgument extends RequestForgerySink {
|
||||
SpringRestTemplateArgument() {
|
||||
exists(MethodAccess ma |
|
||||
this.asExpr() = ma.getMethod().(SpringRestTemplateUrlMethods).getUrlArgument(ma)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to `javax.ws.rs.Client`s `target` method call taken as a
|
||||
* sink for request forgery vulnerabilities.
|
||||
*/
|
||||
private class JaxRsClientTarget extends RequestForgerySink {
|
||||
JaxRsClientTarget() {
|
||||
exists(MethodAccess ma |
|
||||
ma.getMethod().getDeclaringType() instanceof JaxRsClient and
|
||||
ma.getMethod().hasName("target")
|
||||
|
|
||||
this.asExpr() = ma.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to `org.springframework.http.RequestEntity`s constructor call
|
||||
* which is an URI taken as a sink for request forgery vulnerabilities.
|
||||
*/
|
||||
private class RequestEntityUriArg extends RequestForgerySink {
|
||||
RequestEntityUriArg() {
|
||||
exists(ClassInstanceExpr e, Argument a |
|
||||
e.getConstructedType() instanceof SpringRequestEntity and
|
||||
e.getAnArgument() = a and
|
||||
a.getType() instanceof TypeUri and
|
||||
this.asExpr() = a
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class representing all Spring Rest Template methods
|
||||
* which take an URL as an argument.
|
||||
*/
|
||||
private class SpringRestTemplateUrlMethods extends Method {
|
||||
SpringRestTemplateUrlMethods() {
|
||||
this.getDeclaringType() instanceof SpringRestTemplate and
|
||||
this.hasName([
|
||||
"doExecute", "postForEntity", "postForLocation", "postForObject", "put", "exchange",
|
||||
"execute", "getForEntity", "getForObject", "patchForObject"
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the argument which corresponds to a URL argument
|
||||
* passed as a `java.net.URL` object or as a string or the like
|
||||
*/
|
||||
Argument getUrlArgument(MethodAccess ma) {
|
||||
// doExecute(URI url, HttpMethod method, RequestCallback requestCallback,
|
||||
// ResponseExtractor<T> responseExtractor)
|
||||
result = ma.getArgument(0)
|
||||
}
|
||||
}
|
||||
@@ -175,6 +175,19 @@ class FormattingCall extends Call {
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the `i`th argument to be formatted. The index `i` is one-based. */
|
||||
Expr getArgumentToBeFormatted(int i) {
|
||||
i >= 1 and
|
||||
if this.hasExplicitVarargsArray()
|
||||
then
|
||||
result =
|
||||
this.getArgument(1 + this.getFormatStringIndex())
|
||||
.(ArrayCreationExpr)
|
||||
.getInit()
|
||||
.getInit(i - 1)
|
||||
else result = this.getArgument(this.getFormatStringIndex() + i)
|
||||
}
|
||||
|
||||
/** Holds if the varargs argument is given as an explicit array. */
|
||||
private predicate hasExplicitVarargsArray() {
|
||||
this.getNumArgument() = this.getFormatStringIndex() + 2 and
|
||||
@@ -353,6 +366,11 @@ class FormatString extends string {
|
||||
* is not referred by any format specifier.
|
||||
*/
|
||||
/*abstract*/ int getASkippedFmtSpecIndex() { none() }
|
||||
|
||||
/**
|
||||
* Gets an offset (zero-based) in this format string where argument `argNo` (1-based) will be interpolated, if any.
|
||||
*/
|
||||
int getAnArgUsageOffset(int argNo) { none() }
|
||||
}
|
||||
|
||||
private class PrintfFormatString extends FormatString {
|
||||
@@ -425,6 +443,22 @@ private class PrintfFormatString extends FormatString {
|
||||
result > count(int i | fmtSpecRefersToSequentialIndex(i)) and
|
||||
not result = fmtSpecRefersToSpecificIndex(_)
|
||||
}
|
||||
|
||||
private int getFmtSpecRank(int specOffset) {
|
||||
rank[result](int i | this.fmtSpecIsRef(i)) = specOffset
|
||||
}
|
||||
|
||||
override int getAnArgUsageOffset(int argNo) {
|
||||
argNo = fmtSpecRefersToSpecificIndex(result)
|
||||
or
|
||||
result = rank[argNo](int i | fmtSpecRefersToSequentialIndex(i))
|
||||
or
|
||||
fmtSpecRefersToPrevious(result) and
|
||||
exists(int previousOffset |
|
||||
getFmtSpecRank(previousOffset) = getFmtSpecRank(result) - 1 and
|
||||
previousOffset = getAnArgUsageOffset(argNo)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class LoggerFormatString extends FormatString {
|
||||
@@ -449,4 +483,6 @@ private class LoggerFormatString extends FormatString {
|
||||
}
|
||||
|
||||
override int getMaxFmtSpecIndex() { result = count(int i | fmtPlaceholder(i)) }
|
||||
|
||||
override int getAnArgUsageOffset(int argNo) { result = rank[argNo](int i | fmtPlaceholder(i)) }
|
||||
}
|
||||
|
||||
@@ -82,6 +82,8 @@ private module Frameworks {
|
||||
private import semmle.code.java.frameworks.guava.Guava
|
||||
private import semmle.code.java.frameworks.jackson.JacksonSerializability
|
||||
private import semmle.code.java.frameworks.JaxWS
|
||||
private import semmle.code.java.frameworks.spring.SpringHttp
|
||||
private import semmle.code.java.frameworks.spring.SpringWebClient
|
||||
private import semmle.code.java.security.ResponseSplitting
|
||||
private import semmle.code.java.security.InformationLeak
|
||||
private import semmle.code.java.security.XSS
|
||||
@@ -209,6 +211,8 @@ private predicate sinkModelCsv(string row) {
|
||||
// Open URL
|
||||
"java.net;URL;false;openConnection;;;Argument[-1];open-url",
|
||||
"java.net;URL;false;openStream;;;Argument[-1];open-url",
|
||||
"java.net.http;HttpRequest;false;newBuilder;;;Argument[0];open-url",
|
||||
"java.net.http;HttpRequest$Builder;false;uri;;;Argument[0];open-url",
|
||||
// Create file
|
||||
"java.io;FileOutputStream;false;FileOutputStream;;;Argument[0];create-file",
|
||||
"java.io;RandomAccessFile;false;RandomAccessFile;;;Argument[0];create-file",
|
||||
@@ -248,6 +252,8 @@ private predicate summaryModelCsv(string row) {
|
||||
"javax.xml.transform.stream;StreamSource;false;getInputStream;;;Argument[-1];ReturnValue;taint",
|
||||
"java.nio;ByteBuffer;false;get;;;Argument[-1];ReturnValue;taint",
|
||||
"java.net;URI;false;toURL;;;Argument[-1];ReturnValue;taint",
|
||||
"java.net;URI;false;toString;;;Argument[-1];ReturnValue;taint",
|
||||
"java.net;URI;false;toAsciiString;;;Argument[-1];ReturnValue;taint",
|
||||
"java.io;File;false;toURI;;;Argument[-1];ReturnValue;taint",
|
||||
"java.io;File;false;toPath;;;Argument[-1];ReturnValue;taint",
|
||||
"java.nio.file;Path;false;toFile;;;Argument[-1];ReturnValue;taint",
|
||||
|
||||
@@ -92,6 +92,39 @@ private class ApacheHttpXssSink extends SinkModelCsv {
|
||||
}
|
||||
}
|
||||
|
||||
private class ApacheHttpOpenUrlSink extends SinkModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
"org.apache.http;HttpRequest;true;setURI;;;Argument[0];open-url",
|
||||
"org.apache.http.message;BasicHttpRequest;false;BasicHttpRequest;(RequestLine);;Argument[0];open-url",
|
||||
"org.apache.http.message;BasicHttpRequest;false;BasicHttpRequest;(String,String);;Argument[1];open-url",
|
||||
"org.apache.http.message;BasicHttpRequest;false;BasicHttpRequest;(String,String,ProtocolVersion);;Argument[1];open-url",
|
||||
"org.apache.http.message;BasicHttpEntityEnclosingRequest;false;BasicHttpEntityEnclosingRequest;(RequestLine);;Argument[0];open-url",
|
||||
"org.apache.http.message;BasicHttpEntityEnclosingRequest;false;BasicHttpEntityEnclosingRequest;(String,String);;Argument[1];open-url",
|
||||
"org.apache.http.message;BasicHttpEntityEnclosingRequest;false;BasicHttpEntityEnclosingRequest;(String,String,ProtocolVersion);;Argument[1];open-url",
|
||||
"org.apache.http.client.methods;HttpGet;false;HttpGet;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;HttpHead;false;HttpHead;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;HttpPut;false;HttpPut;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;HttpPost;false;HttpPost;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;HttpDelete;false;HttpDelete;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;HttpOptions;false;HttpOptions;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;HttpTrace;false;HttpTrace;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;HttpPatch;false;HttpPatch;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;HttpRequestBase;true;setURI;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;RequestBuilder;false;setUri;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;RequestBuilder;false;get;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;RequestBuilder;false;post;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;RequestBuilder;false;put;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;RequestBuilder;false;options;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;RequestBuilder;false;head;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;RequestBuilder;false;delete;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;RequestBuilder;false;trace;;;Argument[0];open-url",
|
||||
"org.apache.http.client.methods;RequestBuilder;false;patch;;;Argument[0];open-url"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private class ApacheHttpFlowStep extends SummaryModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
@@ -228,7 +261,10 @@ private class ApacheHttpFlowStep extends SummaryModelCsv {
|
||||
"org.apache.hc.core5.util;CharArrayBuffer;true;toString;();;Argument[-1];ReturnValue;taint",
|
||||
"org.apache.hc.core5.util;CharArrayBuffer;true;substring;(int,int);;Argument[-1];ReturnValue;taint",
|
||||
"org.apache.hc.core5.util;CharArrayBuffer;true;subSequence;(int,int);;Argument[-1];ReturnValue;taint",
|
||||
"org.apache.hc.core5.util;CharArrayBuffer;true;substringTrimmed;(int,int);;Argument[-1];ReturnValue;taint"
|
||||
"org.apache.hc.core5.util;CharArrayBuffer;true;substringTrimmed;(int,int);;Argument[-1];ReturnValue;taint",
|
||||
"org.apache.http.message;BasicRequestLine;false;BasicRequestLine;;;Argument[1];Argument[-1];taint",
|
||||
"org.apache.http;RequestLine;true;getUri;;;Argument[-1];ReturnValue;taint",
|
||||
"org.apache.http;RequestLine;true;toString;;;Argument[-1];ReturnValue;taint"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -786,3 +786,13 @@ private class UriBuilderModel extends SummaryModelCsv {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private class JaxRsUrlOpenSink extends SinkModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
"javax.ws.rs.client;Client;true;target;;;Argument[0];open-url",
|
||||
"jakarta.ws.rs.client;Client;true;target;;;Argument[0];open-url"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
/** The class `org.springframework.http.HttpEntity` or an instantiation of it. */
|
||||
class SpringHttpEntity extends Class {
|
||||
@@ -38,3 +39,25 @@ class SpringResponseEntityBodyBuilder extends Interface {
|
||||
class SpringHttpHeaders extends Class {
|
||||
SpringHttpHeaders() { this.hasQualifiedName("org.springframework.http", "HttpHeaders") }
|
||||
}
|
||||
|
||||
private class UrlOpenSink extends SinkModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
"org.springframework.http;RequestEntity;false;get;;;Argument[0];open-url",
|
||||
"org.springframework.http;RequestEntity;false;post;;;Argument[0];open-url",
|
||||
"org.springframework.http;RequestEntity;false;head;;;Argument[0];open-url",
|
||||
"org.springframework.http;RequestEntity;false;delete;;;Argument[0];open-url",
|
||||
"org.springframework.http;RequestEntity;false;options;;;Argument[0];open-url",
|
||||
"org.springframework.http;RequestEntity;false;patch;;;Argument[0];open-url",
|
||||
"org.springframework.http;RequestEntity;false;put;;;Argument[0];open-url",
|
||||
"org.springframework.http;RequestEntity;false;method;;;Argument[1];open-url",
|
||||
"org.springframework.http;RequestEntity;false;RequestEntity;(HttpMethod,URI);;Argument[1];open-url",
|
||||
"org.springframework.http;RequestEntity;false;RequestEntity;(MultiValueMap,HttpMethod,URI);;Argument[2];open-url",
|
||||
"org.springframework.http;RequestEntity;false;RequestEntity;(Object,HttpMethod,URI);;Argument[2];open-url",
|
||||
"org.springframework.http;RequestEntity;false;RequestEntity;(Object,HttpMethod,URI,Type);;Argument[2];open-url",
|
||||
"org.springframework.http;RequestEntity;false;RequestEntity;(Object,MultiValueMap,HttpMethod,URI);;Argument[3];open-url",
|
||||
"org.springframework.http;RequestEntity;false;RequestEntity;(Object,MultiValueMap,HttpMethod,URI,Type);;Argument[3];open-url"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import java
|
||||
import SpringHttp
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
/** The class `org.springframework.web.client.RestTemplate`. */
|
||||
class SpringRestTemplate extends Class {
|
||||
@@ -27,3 +28,24 @@ class SpringWebClient extends Interface {
|
||||
this.hasQualifiedName("org.springframework.web.reactive.function.client", "WebClient")
|
||||
}
|
||||
}
|
||||
|
||||
private class UrlOpenSink extends SinkModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
"org.springframework.web.client;RestTemplate;false;delete;;;Argument[0];open-url",
|
||||
"org.springframework.web.client;RestTemplate;false;doExecute;;;Argument[0];open-url",
|
||||
"org.springframework.web.client;RestTemplate;false;exchange;;;Argument[0];open-url",
|
||||
"org.springframework.web.client;RestTemplate;false;execute;;;Argument[0];open-url",
|
||||
"org.springframework.web.client;RestTemplate;false;getForEntity;;;Argument[0];open-url",
|
||||
"org.springframework.web.client;RestTemplate;false;getForObject;;;Argument[0];open-url",
|
||||
"org.springframework.web.client;RestTemplate;false;headForHeaders;;;Argument[0];open-url",
|
||||
"org.springframework.web.client;RestTemplate;false;optionsForAllow;;;Argument[0];open-url",
|
||||
"org.springframework.web.client;RestTemplate;false;patchForObject;;;Argument[0];open-url",
|
||||
"org.springframework.web.client;RestTemplate;false;postForEntity;;;Argument[0];open-url",
|
||||
"org.springframework.web.client;RestTemplate;false;postForLocation;;;Argument[0];open-url",
|
||||
"org.springframework.web.client;RestTemplate;false;postForObject;;;Argument[0];open-url",
|
||||
"org.springframework.web.client;RestTemplate;false;put;;;Argument[0];open-url"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
213
java/ql/src/semmle/code/java/security/RequestForgery.qll
Normal file
213
java/ql/src/semmle/code/java/security/RequestForgery.qll
Normal file
@@ -0,0 +1,213 @@
|
||||
/** Provides classes to reason about server-side request forgery (SSRF) attacks. */
|
||||
|
||||
import java
|
||||
import semmle.code.java.frameworks.Networking
|
||||
import semmle.code.java.frameworks.ApacheHttp
|
||||
import semmle.code.java.frameworks.spring.Spring
|
||||
import semmle.code.java.frameworks.JaxWS
|
||||
import semmle.code.java.frameworks.javase.Http
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
private import semmle.code.java.StringFormat
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
/**
|
||||
* A unit class for adding additional taint steps that are specific to server-side request forgery (SSRF) attacks.
|
||||
*
|
||||
* Extend this class to add additional taint steps to the SSRF query.
|
||||
*/
|
||||
class RequestForgeryAdditionalTaintStep extends Unit {
|
||||
/**
|
||||
* Holds if the step from `pred` to `succ` should be considered a taint
|
||||
* step for server-side request forgery.
|
||||
*/
|
||||
abstract predicate propagatesTaint(DataFlow::Node pred, DataFlow::Node succ);
|
||||
}
|
||||
|
||||
private class DefaultRequestForgeryAdditionalTaintStep extends RequestForgeryAdditionalTaintStep {
|
||||
override predicate propagatesTaint(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
// propagate to a URI when its host is assigned to
|
||||
exists(UriCreation c | c.getHostArg() = pred.asExpr() | succ.asExpr() = c)
|
||||
or
|
||||
// propagate to a URL when its host is assigned to
|
||||
exists(UrlConstructorCall c | c.getHostArg() = pred.asExpr() | succ.asExpr() = c)
|
||||
}
|
||||
}
|
||||
|
||||
/** A data flow sink for server-side request forgery (SSRF) vulnerabilities. */
|
||||
abstract class RequestForgerySink extends DataFlow::Node { }
|
||||
|
||||
private class UrlOpenSinkAsRequestForgerySink extends RequestForgerySink {
|
||||
UrlOpenSinkAsRequestForgerySink() { sinkNode(this, "open-url") }
|
||||
}
|
||||
|
||||
/** A sanitizer for request forgery vulnerabilities. */
|
||||
abstract class RequestForgerySanitizer extends DataFlow::Node { }
|
||||
|
||||
private class PrimitiveSanitizer extends RequestForgerySanitizer {
|
||||
PrimitiveSanitizer() {
|
||||
this.getType() instanceof PrimitiveType or
|
||||
this.getType() instanceof BoxedType or
|
||||
this.getType() instanceof NumberType
|
||||
}
|
||||
}
|
||||
|
||||
private class HostnameSanitizingConstantPrefix extends CompileTimeConstantExpr {
|
||||
int offset;
|
||||
|
||||
HostnameSanitizingConstantPrefix() {
|
||||
// Matches strings that look like when prepended to untrusted input, they will restrict
|
||||
// the host or entity addressed: for example, anything containing `?` or `#`, or a slash that
|
||||
// doesn't appear to be a protocol specifier (e.g. `http://` is not sanitizing), or specifically
|
||||
// the string "/".
|
||||
exists(
|
||||
this.getStringValue()
|
||||
.regexpFind(".*([?#]|[^?#:/\\\\][/\\\\]).*|[/\\\\][^/\\\\].*|^/$", 0, offset)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the offset in this constant string where a sanitizing substring begins.
|
||||
*/
|
||||
int getOffset() { result = offset }
|
||||
}
|
||||
|
||||
private Expr getAHostnameSanitizingPrefix() {
|
||||
result instanceof HostnameSanitizingConstantPrefix
|
||||
or
|
||||
result.(AddExpr).getAnOperand() = getAHostnameSanitizingPrefix()
|
||||
}
|
||||
|
||||
private class StringBuilderAppend extends MethodAccess {
|
||||
StringBuilderAppend() {
|
||||
this.getMethod().getDeclaringType() instanceof StringBuildingType and
|
||||
this.getMethod().hasName("append")
|
||||
}
|
||||
}
|
||||
|
||||
private class StringBuilderConstructorOrAppend extends Call {
|
||||
StringBuilderConstructorOrAppend() {
|
||||
this instanceof StringBuilderAppend or
|
||||
this.(ClassInstanceExpr).getConstructedType() instanceof StringBuildingType
|
||||
}
|
||||
}
|
||||
|
||||
private Expr getQualifier(Expr e) { result = e.(MethodAccess).getQualifier() }
|
||||
|
||||
/**
|
||||
* An extension of `StringBuilderVar` that also accounts for strings appended in StringBuilder/Buffer's constructor
|
||||
* and in `append` calls chained onto the constructor call.
|
||||
*
|
||||
* The original `StringBuilderVar` doesn't care about these because it is designed to model taint, and
|
||||
* in taint rules terms these are not needed, as the connection between construction, appends and the
|
||||
* eventual `toString` is more obvious.
|
||||
*/
|
||||
private class StringBuilderVarExt extends StringBuilderVar {
|
||||
/**
|
||||
* Returns a first assignment after this StringBuilderVar is first assigned.
|
||||
*
|
||||
* For example, for `StringBuilder sbv = new StringBuilder("1").append("2"); sbv.append("3").append("4");`
|
||||
* this returns the append of `"3"`.
|
||||
*/
|
||||
private StringBuilderAppend getAFirstAppendAfterAssignment() {
|
||||
result = this.getAnAppend() and not result = this.getNextAppend(_)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next `append` after `prev`, where `prev` is, perhaps after some more `append` or other
|
||||
* chained calls, assigned to this `StringBuilderVar`.
|
||||
*/
|
||||
private StringBuilderAppend getNextAssignmentChainedAppend(StringBuilderConstructorOrAppend prev) {
|
||||
getQualifier*(result) = this.getAnAssignedValue() and
|
||||
result.getQualifier() = prev
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a constructor call or `append` call that contributes a string to this string builder.
|
||||
*/
|
||||
StringBuilderConstructorOrAppend getAConstructorOrAppend() {
|
||||
exists(this.getNextAssignmentChainedAppend(result)) or
|
||||
result = this.getAnAssignedValue() or
|
||||
result = this.getAnAppend()
|
||||
}
|
||||
|
||||
/**
|
||||
* Like `StringBuilderVar.getNextAppend`, except including appends and constructors directly
|
||||
* assigned to this `StringBuilderVar`.
|
||||
*/
|
||||
private StringBuilderAppend getNextAppendIncludingAssignmentChains(
|
||||
StringBuilderConstructorOrAppend prev
|
||||
) {
|
||||
result = getNextAssignmentChainedAppend(prev)
|
||||
or
|
||||
prev = this.getAnAssignedValue() and
|
||||
result = this.getAFirstAppendAfterAssignment()
|
||||
or
|
||||
result = this.getNextAppend(prev)
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements `StringBuilderVarExt.getNextAppendIncludingAssignmentChains+(prev)`.
|
||||
*/
|
||||
StringBuilderAppend getSubsequentAppendIncludingAssignmentChains(
|
||||
StringBuilderConstructorOrAppend prev
|
||||
) {
|
||||
result = this.getNextAppendIncludingAssignmentChains(prev) or
|
||||
result =
|
||||
this.getSubsequentAppendIncludingAssignmentChains(this.getNextAppendIncludingAssignmentChains(prev))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression that is sanitized because it is concatenated onto a string that looks like
|
||||
* a hostname or a URL separator, preventing the appended string from arbitrarily controlling
|
||||
* the addressed server.
|
||||
*/
|
||||
private class HostnameSanitizedExpr extends Expr {
|
||||
HostnameSanitizedExpr() {
|
||||
// Sanitize expressions that come after a sanitizing prefix in a tree of string additions:
|
||||
this =
|
||||
any(AddExpr add | add.getLeftOperand() = getAHostnameSanitizingPrefix()).getRightOperand()
|
||||
or
|
||||
// Sanitize expressions that come after a sanitizing prefix in a sequence of StringBuilder operations:
|
||||
exists(
|
||||
StringBuilderConstructorOrAppend appendSanitizingConstant,
|
||||
StringBuilderAppend subsequentAppend, StringBuilderVarExt v
|
||||
|
|
||||
appendSanitizingConstant = v.getAConstructorOrAppend() and
|
||||
appendSanitizingConstant.getArgument(0) = getAHostnameSanitizingPrefix() and
|
||||
v.getSubsequentAppendIncludingAssignmentChains(appendSanitizingConstant) = subsequentAppend and
|
||||
this = subsequentAppend.getArgument(0)
|
||||
)
|
||||
or
|
||||
// Sanitize expressions that come after a sanitizing prefix in the args to a format call:
|
||||
exists(
|
||||
FormattingCall formatCall, FormatString formatString, HostnameSanitizingConstantPrefix prefix,
|
||||
int sanitizedFromOffset, int laterOffset, int sanitizedArg
|
||||
|
|
||||
formatString = unique(FormatString fs | fs = formatCall.getAFormatString()) and
|
||||
(
|
||||
// A sanitizing argument comes before this:
|
||||
exists(int argIdx |
|
||||
formatCall.getArgumentToBeFormatted(argIdx) = prefix and
|
||||
sanitizedFromOffset = formatString.getAnArgUsageOffset(argIdx)
|
||||
)
|
||||
or
|
||||
// The format string itself sanitizes subsequent arguments:
|
||||
formatString = prefix.getStringValue() and
|
||||
sanitizedFromOffset = prefix.getOffset()
|
||||
) and
|
||||
laterOffset > sanitizedFromOffset and
|
||||
laterOffset = formatString.getAnArgUsageOffset(sanitizedArg) and
|
||||
this = formatCall.getArgumentToBeFormatted(sanitizedArg)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A value that is the result of prepending a string that prevents any value from controlling the
|
||||
* host of a URL.
|
||||
*/
|
||||
private class HostnameSantizer extends RequestForgerySanitizer {
|
||||
HostnameSantizer() { this.asExpr() instanceof HostnameSanitizedExpr }
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Provides a taint-tracking configuration characterising request-forgery risks.
|
||||
*
|
||||
* Only import this directly from .ql files, to avoid the possibility of polluting the Configuration hierarchy accidentally.
|
||||
*/
|
||||
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.security.RequestForgery
|
||||
|
||||
/**
|
||||
* A taint-tracking configuration characterising request-forgery risks.
|
||||
*/
|
||||
class RequestForgeryConfiguration extends TaintTracking::Configuration {
|
||||
RequestForgeryConfiguration() { this = "Server-Side Request Forgery" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source instanceof RemoteFlowSource and
|
||||
// Exclude results of remote HTTP requests: fetching something else based on that result
|
||||
// is no worse than following a redirect returned by the remote server, and typically
|
||||
// we're requesting a resource via https which we trust to only send us to safe URLs.
|
||||
not source.asExpr().(MethodAccess).getCallee() instanceof URLConnectionGetInputStreamMethod
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
any(RequestForgeryAdditionalTaintStep r).propagatesTaint(pred, succ)
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof RequestForgerySanitizer }
|
||||
}
|
||||
@@ -11,7 +11,9 @@ edges
|
||||
| InsecureBasicAuth.java:62:21:62:26 | uriStr : String | InsecureBasicAuth.java:62:13:62:27 | new URI(...) : URI |
|
||||
| InsecureBasicAuth.java:78:47:78:52 | "http" : String | InsecureBasicAuth.java:86:3:86:6 | post |
|
||||
| InsecureBasicAuth.java:93:19:93:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:102:3:102:6 | post |
|
||||
| InsecureBasicAuth.java:109:19:109:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:119:3:119:6 | post |
|
||||
| InsecureBasicAuth.java:109:19:109:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:110:58:110:63 | uriStr : String |
|
||||
| InsecureBasicAuth.java:110:29:110:70 | new BasicRequestLine(...) : BasicRequestLine | InsecureBasicAuth.java:119:3:119:6 | post |
|
||||
| InsecureBasicAuth.java:110:58:110:63 | uriStr : String | InsecureBasicAuth.java:110:29:110:70 | new BasicRequestLine(...) : BasicRequestLine |
|
||||
| InsecureBasicAuth.java:126:19:126:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:130:28:130:67 | (...)... : URLConnection |
|
||||
| InsecureBasicAuth.java:130:28:130:67 | (...)... : URLConnection | InsecureBasicAuth.java:133:3:133:6 | conn |
|
||||
| InsecureBasicAuth.java:145:21:145:28 | protocol : String | InsecureBasicAuth.java:146:28:146:67 | (...)... : URLConnection |
|
||||
@@ -34,6 +36,8 @@ nodes
|
||||
| InsecureBasicAuth.java:93:19:93:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | semmle.label | "http://www.example.com/rest/getuser.do?uid=abcdx" : String |
|
||||
| InsecureBasicAuth.java:102:3:102:6 | post | semmle.label | post |
|
||||
| InsecureBasicAuth.java:109:19:109:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | semmle.label | "http://www.example.com/rest/getuser.do?uid=abcdx" : String |
|
||||
| InsecureBasicAuth.java:110:29:110:70 | new BasicRequestLine(...) : BasicRequestLine | semmle.label | new BasicRequestLine(...) : BasicRequestLine |
|
||||
| InsecureBasicAuth.java:110:58:110:63 | uriStr : String | semmle.label | uriStr : String |
|
||||
| InsecureBasicAuth.java:119:3:119:6 | post | semmle.label | post |
|
||||
| InsecureBasicAuth.java:126:19:126:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | semmle.label | "http://www.example.com/rest/getuser.do?uid=abcdx" : String |
|
||||
| InsecureBasicAuth.java:130:28:130:67 | (...)... : URLConnection | semmle.label | (...)... : URLConnection |
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
edges
|
||||
| JaxWsSSRF.java:21:22:21:48 | getParameter(...) : String | JaxWsSSRF.java:22:23:22:25 | url |
|
||||
| RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:25:31:25:34 | sink : String |
|
||||
| RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:55:32:55:35 | url1 |
|
||||
| RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:58:32:58:35 | url1 |
|
||||
| RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:59:30:59:33 | url1 |
|
||||
| RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:63:65:63:68 | uri2 |
|
||||
| RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:64:59:64:61 | uri |
|
||||
| RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:67:43:67:45 | uri |
|
||||
| RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:69:29:69:32 | uri2 |
|
||||
| RequestForgery2.java:25:23:25:35 | new URI(...) : URI | RequestForgery2.java:64:59:64:61 | uri |
|
||||
| RequestForgery2.java:25:23:25:35 | new URI(...) : URI | RequestForgery2.java:67:43:67:45 | uri |
|
||||
| RequestForgery2.java:25:31:25:34 | sink : String | RequestForgery2.java:25:23:25:35 | new URI(...) : URI |
|
||||
| RequestForgery.java:19:23:19:58 | new URI(...) : URI | RequestForgery.java:22:52:22:54 | uri |
|
||||
| RequestForgery.java:19:23:19:58 | new URI(...) : URI | RequestForgery.java:27:57:27:59 | uri |
|
||||
| RequestForgery.java:19:31:19:57 | getParameter(...) : String | RequestForgery.java:19:23:19:58 | new URI(...) : URI |
|
||||
| RequestForgery.java:19:31:19:57 | getParameter(...) : String | RequestForgery.java:22:52:22:54 | uri |
|
||||
| RequestForgery.java:19:31:19:57 | getParameter(...) : String | RequestForgery.java:27:57:27:59 | uri |
|
||||
| SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:32:47:32:67 | ... + ... |
|
||||
| SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:37:43:37:56 | fooResourceUrl |
|
||||
| SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:41:42:41:55 | fooResourceUrl |
|
||||
| SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:45:47:45:60 | fooResourceUrl |
|
||||
| SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:54:59:54:72 | fooResourceUrl |
|
||||
| SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:58:74:58:96 | new URI(...) |
|
||||
| SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:58:82:58:95 | fooResourceUrl : String |
|
||||
| SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:62:57:62:70 | fooResourceUrl |
|
||||
| SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:66:48:66:61 | fooResourceUrl |
|
||||
| SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:69:30:69:43 | fooResourceUrl |
|
||||
| SpringSSRF.java:58:82:58:95 | fooResourceUrl : String | SpringSSRF.java:58:74:58:96 | new URI(...) |
|
||||
nodes
|
||||
| JaxWsSSRF.java:21:22:21:48 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| JaxWsSSRF.java:22:23:22:25 | url | semmle.label | url |
|
||||
| RequestForgery2.java:23:27:23:53 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| RequestForgery2.java:25:23:25:35 | new URI(...) : URI | semmle.label | new URI(...) : URI |
|
||||
| RequestForgery2.java:25:31:25:34 | sink : String | semmle.label | sink : String |
|
||||
| RequestForgery2.java:55:32:55:35 | url1 | semmle.label | url1 |
|
||||
| RequestForgery2.java:58:32:58:35 | url1 | semmle.label | url1 |
|
||||
| RequestForgery2.java:59:30:59:33 | url1 | semmle.label | url1 |
|
||||
| RequestForgery2.java:63:65:63:68 | uri2 | semmle.label | uri2 |
|
||||
| RequestForgery2.java:64:59:64:61 | uri | semmle.label | uri |
|
||||
| RequestForgery2.java:67:43:67:45 | uri | semmle.label | uri |
|
||||
| RequestForgery2.java:69:29:69:32 | uri2 | semmle.label | uri2 |
|
||||
| RequestForgery.java:19:23:19:58 | new URI(...) : URI | semmle.label | new URI(...) : URI |
|
||||
| RequestForgery.java:19:31:19:57 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| RequestForgery.java:22:52:22:54 | uri | semmle.label | uri |
|
||||
| RequestForgery.java:27:57:27:59 | uri | semmle.label | uri |
|
||||
| SpringSSRF.java:26:33:26:60 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| SpringSSRF.java:32:47:32:67 | ... + ... | semmle.label | ... + ... |
|
||||
| SpringSSRF.java:37:43:37:56 | fooResourceUrl | semmle.label | fooResourceUrl |
|
||||
| SpringSSRF.java:41:42:41:55 | fooResourceUrl | semmle.label | fooResourceUrl |
|
||||
| SpringSSRF.java:45:47:45:60 | fooResourceUrl | semmle.label | fooResourceUrl |
|
||||
| SpringSSRF.java:54:59:54:72 | fooResourceUrl | semmle.label | fooResourceUrl |
|
||||
| SpringSSRF.java:58:74:58:96 | new URI(...) | semmle.label | new URI(...) |
|
||||
| SpringSSRF.java:58:82:58:95 | fooResourceUrl : String | semmle.label | fooResourceUrl : String |
|
||||
| SpringSSRF.java:62:57:62:70 | fooResourceUrl | semmle.label | fooResourceUrl |
|
||||
| SpringSSRF.java:66:48:66:61 | fooResourceUrl | semmle.label | fooResourceUrl |
|
||||
| SpringSSRF.java:69:30:69:43 | fooResourceUrl | semmle.label | fooResourceUrl |
|
||||
#select
|
||||
| JaxWsSSRF.java:22:23:22:25 | url | JaxWsSSRF.java:21:22:21:48 | getParameter(...) : String | JaxWsSSRF.java:22:23:22:25 | url | Potential server side request forgery due to $@. | JaxWsSSRF.java:21:22:21:48 | getParameter(...) | a user-provided value |
|
||||
| RequestForgery2.java:55:32:55:35 | url1 | RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:55:32:55:35 | url1 | Potential server side request forgery due to $@. | RequestForgery2.java:23:27:23:53 | getParameter(...) | a user-provided value |
|
||||
| RequestForgery2.java:58:32:58:35 | url1 | RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:58:32:58:35 | url1 | Potential server side request forgery due to $@. | RequestForgery2.java:23:27:23:53 | getParameter(...) | a user-provided value |
|
||||
| RequestForgery2.java:59:30:59:33 | url1 | RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:59:30:59:33 | url1 | Potential server side request forgery due to $@. | RequestForgery2.java:23:27:23:53 | getParameter(...) | a user-provided value |
|
||||
| RequestForgery2.java:63:65:63:68 | uri2 | RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:63:65:63:68 | uri2 | Potential server side request forgery due to $@. | RequestForgery2.java:23:27:23:53 | getParameter(...) | a user-provided value |
|
||||
| RequestForgery2.java:64:59:64:61 | uri | RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:64:59:64:61 | uri | Potential server side request forgery due to $@. | RequestForgery2.java:23:27:23:53 | getParameter(...) | a user-provided value |
|
||||
| RequestForgery2.java:67:43:67:45 | uri | RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:67:43:67:45 | uri | Potential server side request forgery due to $@. | RequestForgery2.java:23:27:23:53 | getParameter(...) | a user-provided value |
|
||||
| RequestForgery2.java:69:29:69:32 | uri2 | RequestForgery2.java:23:27:23:53 | getParameter(...) : String | RequestForgery2.java:69:29:69:32 | uri2 | Potential server side request forgery due to $@. | RequestForgery2.java:23:27:23:53 | getParameter(...) | a user-provided value |
|
||||
| RequestForgery.java:22:52:22:54 | uri | RequestForgery.java:19:31:19:57 | getParameter(...) : String | RequestForgery.java:22:52:22:54 | uri | Potential server side request forgery due to $@. | RequestForgery.java:19:31:19:57 | getParameter(...) | a user-provided value |
|
||||
| RequestForgery.java:27:57:27:59 | uri | RequestForgery.java:19:31:19:57 | getParameter(...) : String | RequestForgery.java:27:57:27:59 | uri | Potential server side request forgery due to $@. | RequestForgery.java:19:31:19:57 | getParameter(...) | a user-provided value |
|
||||
| SpringSSRF.java:32:47:32:67 | ... + ... | SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:32:47:32:67 | ... + ... | Potential server side request forgery due to $@. | SpringSSRF.java:26:33:26:60 | getParameter(...) | a user-provided value |
|
||||
| SpringSSRF.java:37:43:37:56 | fooResourceUrl | SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:37:43:37:56 | fooResourceUrl | Potential server side request forgery due to $@. | SpringSSRF.java:26:33:26:60 | getParameter(...) | a user-provided value |
|
||||
| SpringSSRF.java:41:42:41:55 | fooResourceUrl | SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:41:42:41:55 | fooResourceUrl | Potential server side request forgery due to $@. | SpringSSRF.java:26:33:26:60 | getParameter(...) | a user-provided value |
|
||||
| SpringSSRF.java:45:47:45:60 | fooResourceUrl | SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:45:47:45:60 | fooResourceUrl | Potential server side request forgery due to $@. | SpringSSRF.java:26:33:26:60 | getParameter(...) | a user-provided value |
|
||||
| SpringSSRF.java:54:59:54:72 | fooResourceUrl | SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:54:59:54:72 | fooResourceUrl | Potential server side request forgery due to $@. | SpringSSRF.java:26:33:26:60 | getParameter(...) | a user-provided value |
|
||||
| SpringSSRF.java:58:74:58:96 | new URI(...) | SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:58:74:58:96 | new URI(...) | Potential server side request forgery due to $@. | SpringSSRF.java:26:33:26:60 | getParameter(...) | a user-provided value |
|
||||
| SpringSSRF.java:62:57:62:70 | fooResourceUrl | SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:62:57:62:70 | fooResourceUrl | Potential server side request forgery due to $@. | SpringSSRF.java:26:33:26:60 | getParameter(...) | a user-provided value |
|
||||
| SpringSSRF.java:66:48:66:61 | fooResourceUrl | SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:66:48:66:61 | fooResourceUrl | Potential server side request forgery due to $@. | SpringSSRF.java:26:33:26:60 | getParameter(...) | a user-provided value |
|
||||
| SpringSSRF.java:69:30:69:43 | fooResourceUrl | SpringSSRF.java:26:33:26:60 | getParameter(...) : String | SpringSSRF.java:69:30:69:43 | fooResourceUrl | Potential server side request forgery due to $@. | SpringSSRF.java:26:33:26:60 | getParameter(...) | a user-provided value |
|
||||
@@ -1,34 +0,0 @@
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class RequestForgery extends HttpServlet {
|
||||
private static final String VALID_URI = "http://lgtm.com";
|
||||
private HttpClient client = HttpClient.newHttpClient();
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
|
||||
URI uri = new URI(request.getParameter("uri"));
|
||||
// BAD: a request parameter is incorporated without validation into a Http
|
||||
// request
|
||||
HttpRequest r = HttpRequest.newBuilder(uri).build();
|
||||
client.send(r, null);
|
||||
|
||||
// GOOD: the request parameter is validated against a known fixed string
|
||||
if (VALID_URI.equals(request.getParameter("uri"))) {
|
||||
HttpRequest r2 = HttpRequest.newBuilder(uri).build();
|
||||
client.send(r2, null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security/CWE/CWE-918/RequestForgery.ql
|
||||
@@ -1,84 +0,0 @@
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.*;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.Proxy.Type;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class RequestForgery2 extends HttpServlet {
|
||||
private static final String VALID_URI = "http://lgtm.com";
|
||||
private HttpClient client = HttpClient.newHttpClient();
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
|
||||
String sink = request.getParameter("uri");
|
||||
// URI(String str)
|
||||
URI uri = new URI(sink);
|
||||
|
||||
// URI(String scheme, String ssp, String fragment)
|
||||
URI uri2 = new URI("http", sink, "fragement");
|
||||
|
||||
// URI(String scheme, String userInfo, String host, int port, String path,
|
||||
// String query, String fragment)
|
||||
URI uri3 = new URI("http", "userinfo", "host", 1, "path", "query", "fragment");
|
||||
// URI(String scheme, String host, String path, String fragment)
|
||||
URI uri4 = new URI("http", "host", "path", "fragment");
|
||||
// URI(String scheme, String authority, String path, String query, String
|
||||
// fragment)
|
||||
URI uri5 = new URI("http", "authority", "path", "query", "fragment");
|
||||
URI uri6 = URI.create("http://foo.com/");
|
||||
|
||||
// URL(String spec)
|
||||
URL url1 = new URL(sink);
|
||||
// URL(String protocol, String host, int port, String file)
|
||||
URL url2 = new URL("http", "host", 1, "file");
|
||||
// URL(String protocol, String host, String file)
|
||||
URL url3 = new URL("http", "host", "file");
|
||||
// URL(URL context, String spec)
|
||||
URL url4 = new URL(url3, "http");
|
||||
// URL(String protocol, String host, int port, String file, URLStreamHandler
|
||||
// handler)
|
||||
URL url5 = new URL("http", "host", 1, "file", new Helper2());
|
||||
|
||||
// URL(URL context, String spec, URLStreamHandler handler)
|
||||
URL url6 = new URL(url3, "spec", new Helper2());
|
||||
|
||||
URLConnection c1 = url1.openConnection();
|
||||
SocketAddress sa = new SocketAddress() {
|
||||
};
|
||||
URLConnection c2 = url1.openConnection(new Proxy(Type.HTTP, sa));
|
||||
InputStream c3 = url1.openStream();
|
||||
|
||||
// java.net.http
|
||||
HttpClient client = HttpClient.newHttpClient();
|
||||
HttpRequest request2 = HttpRequest.newBuilder().uri(uri2).build();
|
||||
HttpRequest request3 = HttpRequest.newBuilder(uri).build();
|
||||
|
||||
// Apache HTTPlib
|
||||
HttpGet httpGet = new HttpGet(uri);
|
||||
HttpGet httpGet2 = new HttpGet();
|
||||
httpGet2.setURI(uri2);
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Helper2 extends URLStreamHandler {
|
||||
Helper2() {
|
||||
}
|
||||
|
||||
protected URLConnection openConnection(URL u) throws IOException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.Proxy.Type;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
// import java.net.http.HttpClient;
|
||||
// import java.net.http.HttpRequest;
|
||||
|
||||
public class Sinks {
|
||||
public static void main(String[] args) throws Exception {
|
||||
// URI(String str)
|
||||
URI uri = new URI("uri1");
|
||||
|
||||
// URI(String scheme, String ssp, String fragment)
|
||||
URI uri2 = new URI("http", "ssp", "fragement");
|
||||
|
||||
// URI(String scheme, String userInfo, String host, int port, String path,
|
||||
// String query, String fragment)
|
||||
URI uri3 = new URI("http", "userinfo", "host", 1, "path", "query", "fragment");
|
||||
// URI(String scheme, String host, String path, String fragment)
|
||||
URI uri4 = new URI("http", "host", "path", "fragment");
|
||||
// URI(String scheme, String authority, String path, String query, String
|
||||
// fragment)
|
||||
URI uri5 = new URI("http", "authority", "path", "query", "fragment");
|
||||
URI uri6 = URI.create("http://foo.com/");
|
||||
|
||||
// URL(String spec)
|
||||
URL url1 = new URL("spec");
|
||||
// URL(String protocol, String host, int port, String file)
|
||||
URL url2 = new URL("http", "host", 1, "file");
|
||||
// URL(String protocol, String host, String file)
|
||||
URL url3 = new URL("http", "host", "file");
|
||||
// URL(URL context, String spec)
|
||||
URL url4 = new URL(url3, "http");
|
||||
// URL(String protocol, String host, int port, String file, URLStreamHandler
|
||||
// handler)
|
||||
URL url5 = new URL("http", "host", 1, "file", new Helper());
|
||||
|
||||
// URL(URL context, String spec, URLStreamHandler handler)
|
||||
URL url6 = new URL(url3, "spec", new Helper());
|
||||
|
||||
URLConnection c1 = url1.openConnection();
|
||||
SocketAddress sa = new SocketAddress() {
|
||||
};
|
||||
URLConnection c2 = url1.openConnection(new Proxy(Type.HTTP, sa));
|
||||
InputStream c3 = url1.openStream();
|
||||
|
||||
// java.net.http
|
||||
// HttpClient client = HttpClient.newHttpClient();
|
||||
// HttpRequest request2 = HttpRequest.newBuilder().uri(uri2).build();
|
||||
// HttpRequest request3 = HttpRequest.newBuilder(uri).build();
|
||||
|
||||
// Apache HTTPlib
|
||||
HttpGet httpGet = new HttpGet(uri);
|
||||
HttpGet httpGet2 = new HttpGet();
|
||||
httpGet2.setURI(uri2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Helper extends URLStreamHandler {
|
||||
@Override
|
||||
protected URLConnection openConnection(URL arg0) throws IOException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import java.net.URI;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.*;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.Proxy.Type;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class SpringSSRF extends HttpServlet {
|
||||
|
||||
protected void doGet(HttpServletRequest request2, HttpServletResponse response2)
|
||||
throws ServletException, IOException {
|
||||
String fooResourceUrl = request2.getParameter("uri");;
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
HttpEntity<String> request = new HttpEntity<>(new String("bar"));
|
||||
try {
|
||||
{
|
||||
ResponseEntity<String> response =
|
||||
restTemplate.getForEntity(fooResourceUrl + "/1", String.class);
|
||||
}
|
||||
|
||||
{
|
||||
ResponseEntity<String> response =
|
||||
restTemplate.exchange(fooResourceUrl, HttpMethod.POST, request, String.class);
|
||||
}
|
||||
{
|
||||
ResponseEntity<String> response =
|
||||
restTemplate.execute(fooResourceUrl, HttpMethod.POST, null, null, "test");
|
||||
}
|
||||
{
|
||||
ResponseEntity<String> response =
|
||||
restTemplate.getForEntity(fooResourceUrl, String.class, "test");
|
||||
}
|
||||
{
|
||||
String body = new String("body");
|
||||
RequestEntity<String> requestEntity =
|
||||
RequestEntity.post(new URI(fooResourceUrl)).body(body);
|
||||
ResponseEntity<String> response = restTemplate.exchange(requestEntity, String.class);
|
||||
}
|
||||
{
|
||||
String response = restTemplate.patchForObject(fooResourceUrl, new String("object"),
|
||||
String.class, "hi");
|
||||
}
|
||||
{
|
||||
ResponseEntity<String> response = restTemplate.postForEntity(new URI(fooResourceUrl),
|
||||
new String("object"), String.class);
|
||||
}
|
||||
{
|
||||
URI response = restTemplate.postForLocation(fooResourceUrl, new String("object"));
|
||||
}
|
||||
{
|
||||
String response =
|
||||
restTemplate.postForObject(fooResourceUrl, new String("object"), String.class);
|
||||
}
|
||||
{
|
||||
restTemplate.put(fooResourceUrl, new String("object"));
|
||||
}
|
||||
} catch (org.springframework.web.client.RestClientException | java.net.URISyntaxException e) {}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../../stubs/apache-http-4.4.13/:${testdir}/../../../../stubs/servlet-api-2.4/
|
||||
@@ -1,12 +0,0 @@
|
||||
package javax.ws.rs.client;
|
||||
|
||||
public abstract interface Client extends javax.ws.rs.core.Configurable {
|
||||
|
||||
public abstract javax.ws.rs.client.WebTarget target(java.lang.String arg0);
|
||||
|
||||
public abstract javax.ws.rs.client.WebTarget target(java.net.URI arg0);
|
||||
|
||||
public abstract javax.ws.rs.client.WebTarget target(javax.ws.rs.core.UriBuilder arg0);
|
||||
|
||||
public abstract javax.ws.rs.client.WebTarget target(javax.ws.rs.core.Link arg0);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package javax.ws.rs.core;
|
||||
|
||||
public abstract interface Configurable<C extends javax.ws.rs.core.Configurable> {
|
||||
|
||||
public abstract javax.ws.rs.core.Configuration getConfiguration();
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package javax.ws.rs.core;
|
||||
|
||||
public abstract class Link {
|
||||
|
||||
public static final java.lang.String TITLE = "title";
|
||||
|
||||
public static final java.lang.String REL = "rel";
|
||||
|
||||
public static final java.lang.String TYPE = "type";
|
||||
|
||||
public Link() {
|
||||
}
|
||||
|
||||
public abstract java.net.URI getUri();
|
||||
|
||||
public abstract javax.ws.rs.core.UriBuilder getUriBuilder();
|
||||
|
||||
public abstract java.lang.String getRel();
|
||||
|
||||
public abstract java.util.List<java.lang.String> getRels();
|
||||
|
||||
public abstract java.lang.String getTitle();
|
||||
|
||||
public abstract java.lang.String getType();
|
||||
|
||||
public abstract java.util.Map<java.lang.String, java.lang.String> getParams();
|
||||
|
||||
public abstract java.lang.String toString();
|
||||
|
||||
public static javax.ws.rs.core.Link valueOf(java.lang.String value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// public static javax.ws.rs.core.Link.Builder fromUri(java.net.URI uri) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// public static javax.ws.rs.core.Link.Builder fromUri(java.lang.String uri) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// public static javax.ws.rs.core.Link.Builder fromUriBuilder(javax.ws.rs.core.UriBuilder uriBuilder) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// public static javax.ws.rs.core.Link.Builder fromLink(javax.ws.rs.core.Link link) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// public static javax.ws.rs.core.Link.Builder fromPath(java.lang.String path) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// public static javax.ws.rs.core.Link.Builder fromResource(java.lang.Class<?> resource) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// public static javax.ws.rs.core.Link.Builder fromMethod(java.lang.Class<?> resource, java.lang.String method) {
|
||||
// return null;
|
||||
// }
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
// Failed to get sources. Instead, stub sources have been generated by the disassembler.
|
||||
// Implementation of methods is unavailable.
|
||||
package javax.ws.rs.core;
|
||||
|
||||
public abstract class UriBuilder {
|
||||
|
||||
protected UriBuilder() {
|
||||
}
|
||||
|
||||
protected static javax.ws.rs.core.UriBuilder newInstance() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static javax.ws.rs.core.UriBuilder fromUri(java.net.URI uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static javax.ws.rs.core.UriBuilder fromUri(java.lang.String uriTemplate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static javax.ws.rs.core.UriBuilder fromLink(javax.ws.rs.core.Link link) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static javax.ws.rs.core.UriBuilder fromPath(java.lang.String path)
|
||||
throws java.lang.IllegalArgumentException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static javax.ws.rs.core.UriBuilder fromResource(java.lang.Class<?> resource) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static javax.ws.rs.core.UriBuilder fromMethod(java.lang.Class<?> resource, java.lang.String method) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract javax.ws.rs.core.UriBuilder clone();
|
||||
|
||||
public abstract javax.ws.rs.core.UriBuilder uri(java.net.URI arg0);
|
||||
|
||||
public abstract javax.ws.rs.core.UriBuilder uri(java.lang.String arg0);
|
||||
|
||||
public abstract java.net.URI buildFromMap(java.util.Map<java.lang.String, ?> arg0);
|
||||
|
||||
public abstract java.net.URI buildFromMap(java.util.Map<java.lang.String, ?> arg0, boolean arg1)
|
||||
throws java.lang.IllegalArgumentException, javax.ws.rs.core.UriBuilderException;
|
||||
|
||||
public abstract java.net.URI buildFromEncodedMap(java.util.Map<java.lang.String, ?> arg0)
|
||||
throws java.lang.IllegalArgumentException, javax.ws.rs.core.UriBuilderException;
|
||||
|
||||
public abstract java.net.URI build(java.lang.Object... arg0)
|
||||
throws java.lang.IllegalArgumentException, javax.ws.rs.core.UriBuilderException;
|
||||
|
||||
public abstract java.net.URI build(java.lang.Object[] arg0, boolean arg1)
|
||||
throws java.lang.IllegalArgumentException, javax.ws.rs.core.UriBuilderException;
|
||||
|
||||
public abstract java.net.URI buildFromEncoded(java.lang.Object... arg0)
|
||||
throws java.lang.IllegalArgumentException, javax.ws.rs.core.UriBuilderException;
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package javax.ws.rs.core;
|
||||
|
||||
public class UriBuilderException extends java.lang.RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 956255913370721193L;
|
||||
|
||||
public UriBuilderException() {
|
||||
}
|
||||
|
||||
public UriBuilderException(java.lang.String msg) {
|
||||
}
|
||||
|
||||
public UriBuilderException(java.lang.String msg, java.lang.Throwable cause) {
|
||||
}
|
||||
|
||||
public UriBuilderException(java.lang.Throwable cause) {
|
||||
}
|
||||
}
|
||||
17
java/ql/test/library-tests/format-strings/Test.java
Normal file
17
java/ql/test/library-tests/format-strings/Test.java
Normal file
@@ -0,0 +1,17 @@
|
||||
public class Test {
|
||||
|
||||
public static void test () {
|
||||
String.format("%s", "", "");
|
||||
String.format("s", "");
|
||||
String.format("%2$s %2$s", "", "");
|
||||
String.format("%2$s %1$s", "", "");
|
||||
String.format("%2$s %s", "");
|
||||
String.format("%s%<s", "", "");
|
||||
String.format("%s%%%%%%%%s%n", "", "");
|
||||
String.format("%s%%%%%%%%s%n", "");
|
||||
String.format("%s%%%%%%%s%n", "", "");
|
||||
String.format("%s%%%%%%%s%n", "");
|
||||
String.format("%2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s", "", "");
|
||||
}
|
||||
|
||||
}
|
||||
22
java/ql/test/library-tests/format-strings/test.expected
Normal file
22
java/ql/test/library-tests/format-strings/test.expected
Normal file
@@ -0,0 +1,22 @@
|
||||
| %2$s %1$s | 1 | 5 |
|
||||
| %2$s %1$s | 2 | 0 |
|
||||
| %2$s %2$s | 2 | 0 |
|
||||
| %2$s %2$s | 2 | 5 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 11 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 16 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 20 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 23 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 27 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 38 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 1 | 43 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 2 | 0 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 2 | 31 |
|
||||
| %2$s %% %n %1$s %<s %s %<s %<s %s %<s %1$s %<s | 2 | 34 |
|
||||
| %2$s %s | 1 | 5 |
|
||||
| %2$s %s | 2 | 0 |
|
||||
| %s | 1 | 0 |
|
||||
| %s%%%%%%%%s%n | 1 | 0 |
|
||||
| %s%%%%%%%s%n | 1 | 0 |
|
||||
| %s%%%%%%%s%n | 2 | 8 |
|
||||
| %s%<s | 1 | 0 |
|
||||
| %s%<s | 1 | 2 |
|
||||
6
java/ql/test/library-tests/format-strings/test.ql
Normal file
6
java/ql/test/library-tests/format-strings/test.ql
Normal file
@@ -0,0 +1,6 @@
|
||||
import java
|
||||
import semmle.code.java.StringFormat
|
||||
|
||||
from FormatString f, int argNo, int offset
|
||||
where offset = f.getAnArgUsageOffset(argNo)
|
||||
select f, argNo, offset
|
||||
@@ -0,0 +1,64 @@
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpHead;
|
||||
import org.apache.http.client.methods.HttpOptions;
|
||||
import org.apache.http.client.methods.HttpTrace;
|
||||
import org.apache.http.client.methods.HttpPatch;
|
||||
import org.apache.http.client.methods.RequestBuilder;
|
||||
import org.apache.http.message.BasicHttpRequest;
|
||||
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
|
||||
import org.apache.http.message.BasicRequestLine;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class ApacheHttpSSRF extends HttpServlet {
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
|
||||
String sink = request.getParameter("uri");
|
||||
URI uri = new URI(sink);
|
||||
|
||||
HttpGet httpGet = new HttpGet(uri); // $ SSRF
|
||||
HttpGet httpGet2 = new HttpGet();
|
||||
httpGet2.setURI(uri); // $ SSRF
|
||||
|
||||
new HttpHead(uri); // $ SSRF
|
||||
new HttpPost(uri); // $ SSRF
|
||||
new HttpPut(uri); // $ SSRF
|
||||
new HttpDelete(uri); // $ SSRF
|
||||
new HttpOptions(uri); // $ SSRF
|
||||
new HttpTrace(uri); // $ SSRF
|
||||
new HttpPatch(uri); // $ SSRF
|
||||
|
||||
new BasicHttpRequest(new BasicRequestLine("GET", uri.toString(), null)); // $ SSRF
|
||||
new BasicHttpRequest("GET", uri.toString()); // $ SSRF
|
||||
new BasicHttpRequest("GET", uri.toString(), null); // $ SSRF
|
||||
|
||||
new BasicHttpEntityEnclosingRequest(new BasicRequestLine("GET", uri.toString(), null)); // $ SSRF
|
||||
new BasicHttpEntityEnclosingRequest("GET", uri.toString()); // $ SSRF
|
||||
new BasicHttpEntityEnclosingRequest("GET", uri.toString(), null); // $ SSRF
|
||||
|
||||
RequestBuilder.get(uri); // $ SSRF
|
||||
RequestBuilder.post(uri); // $ SSRF
|
||||
RequestBuilder.put(uri); // $ SSRF
|
||||
RequestBuilder.delete(uri); // $ SSRF
|
||||
RequestBuilder.options(uri); // $ SSRF
|
||||
RequestBuilder.head(uri); // $ SSRF
|
||||
RequestBuilder.trace(uri); // $ SSRF
|
||||
RequestBuilder.patch(uri); // $ SSRF
|
||||
RequestBuilder.get("").setUri(uri); // $ SSRF
|
||||
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
}
|
||||
}
|
||||
18
java/ql/test/query-tests/security/CWE-918/JakartaWsSSRF.java
Normal file
18
java/ql/test/query-tests/security/CWE-918/JakartaWsSSRF.java
Normal file
@@ -0,0 +1,18 @@
|
||||
import jakarta.ws.rs.client.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class JakartaWsSSRF extends HttpServlet {
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
Client client = ClientBuilder.newClient();
|
||||
String url = request.getParameter("url");
|
||||
client.target(url); // $ SSRF
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import java.io.IOException;
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.Proxy.Type;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class JavaNetHttpSSRF extends HttpServlet {
|
||||
private static final String VALID_URI = "http://lgtm.com";
|
||||
private HttpClient client = HttpClient.newHttpClient();
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
|
||||
String sink = request.getParameter("uri");
|
||||
URI uri = new URI(sink);
|
||||
URI uri2 = new URI("http", sink, "fragement");
|
||||
URL url1 = new URL(sink);
|
||||
|
||||
URLConnection c1 = url1.openConnection(); // $ SSRF
|
||||
SocketAddress sa = new SocketAddress() {
|
||||
};
|
||||
URLConnection c2 = url1.openConnection(new Proxy(Type.HTTP, sa)); // $ SSRF
|
||||
InputStream c3 = url1.openStream(); // $ SSRF
|
||||
|
||||
// java.net.http
|
||||
HttpClient client = HttpClient.newHttpClient();
|
||||
HttpRequest request2 = HttpRequest.newBuilder().uri(uri2).build(); // $ SSRF
|
||||
HttpRequest request3 = HttpRequest.newBuilder(uri).build(); // $ SSRF
|
||||
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,6 @@
|
||||
import javax.ws.rs.client.*;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.*;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.Proxy.Type;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -19,7 +12,7 @@ public class JaxWsSSRF extends HttpServlet {
|
||||
throws ServletException, IOException {
|
||||
Client client = ClientBuilder.newClient();
|
||||
String url = request.getParameter("url");
|
||||
client.target(url);
|
||||
client.target(url); // $ SSRF
|
||||
}
|
||||
|
||||
}
|
||||
18
java/ql/test/query-tests/security/CWE-918/RequestForgery.ql
Normal file
18
java/ql/test/query-tests/security/CWE-918/RequestForgery.ql
Normal file
@@ -0,0 +1,18 @@
|
||||
import java
|
||||
import semmle.code.java.security.RequestForgeryConfig
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class HasFlowTest extends InlineExpectationsTest {
|
||||
HasFlowTest() { this = "HasFlowTest" }
|
||||
|
||||
override string getARelevantTag() { result = "SSRF" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "SSRF" and
|
||||
exists(RequestForgeryConfiguration conf, DataFlow::Node sink | conf.hasFlowTo(sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
123
java/ql/test/query-tests/security/CWE-918/SanitizationTests.java
Normal file
123
java/ql/test/query-tests/security/CWE-918/SanitizationTests.java
Normal file
@@ -0,0 +1,123 @@
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class SanitizationTests extends HttpServlet {
|
||||
private static final String VALID_URI = "http://lgtm.com";
|
||||
private HttpClient client = HttpClient.newHttpClient();
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
try {
|
||||
|
||||
URI uri = new URI(request.getParameter("uri"));
|
||||
// BAD: a request parameter is incorporated without validation into a Http
|
||||
// request
|
||||
HttpRequest r = HttpRequest.newBuilder(uri).build(); // $ SSRF
|
||||
client.send(r, null);
|
||||
|
||||
// GOOD: sanitisation by concatenation with a prefix that prevents targeting an arbitrary host.
|
||||
// We test a few different ways of sanitisation: via string conctentation (perhaps nested),
|
||||
// via a stringbuilder (for which we consider appends done in the constructor, chained onto
|
||||
// the constructor and applied in subsequent statements) and via String.format.
|
||||
String safeUri3 = "https://example.com/" + request.getParameter("uri3");
|
||||
HttpRequest r3 = HttpRequest.newBuilder(new URI(safeUri3)).build();
|
||||
client.send(r3, null);
|
||||
|
||||
String safeUri4 = "https://example.com/" + ("someprefix" + request.getParameter("uri4"));
|
||||
HttpRequest r4 = HttpRequest.newBuilder(new URI(safeUri4)).build();
|
||||
client.send(r4, null);
|
||||
|
||||
StringBuilder safeUri5 = new StringBuilder();
|
||||
safeUri5.append("https://example.com/").append(request.getParameter("uri5"));
|
||||
HttpRequest r5 = HttpRequest.newBuilder(new URI(safeUri5.toString())).build();
|
||||
client.send(r5, null);
|
||||
|
||||
StringBuilder safeUri5a = new StringBuilder("https://example.com/");
|
||||
safeUri5a.append(request.getParameter("uri5a"));
|
||||
HttpRequest r5a = HttpRequest.newBuilder(new URI(safeUri5a.toString())).build();
|
||||
client.send(r5a, null);
|
||||
|
||||
StringBuilder safeUri5b = (new StringBuilder("https://example.com/")).append("dir/");
|
||||
safeUri5b.append(request.getParameter("uri5b"));
|
||||
HttpRequest r5b = HttpRequest.newBuilder(new URI(safeUri5b.toString())).build();
|
||||
client.send(r5b, null);
|
||||
|
||||
StringBuilder safeUri5c = (new StringBuilder("prefix")).append("https://example.com/dir/");
|
||||
safeUri5c.append(request.getParameter("uri5c"));
|
||||
HttpRequest r5c = HttpRequest.newBuilder(new URI(safeUri5c.toString())).build();
|
||||
client.send(r5c, null);
|
||||
|
||||
String safeUri6 = String.format("https://example.com/%s", request.getParameter("uri6"));
|
||||
HttpRequest r6 = HttpRequest.newBuilder(new URI(safeUri6)).build();
|
||||
client.send(r6, null);
|
||||
|
||||
String safeUri7 = String.format("%s/%s", "https://example.com", request.getParameter("uri7"));
|
||||
HttpRequest r7 = HttpRequest.newBuilder(new URI(safeUri7)).build();
|
||||
client.send(r7, null);
|
||||
|
||||
String safeUri8 = String.format("%s%s", "https://example.com/", request.getParameter("uri8"));
|
||||
HttpRequest r8 = HttpRequest.newBuilder(new URI(safeUri8)).build();
|
||||
client.send(r8, null);
|
||||
|
||||
String safeUri9 = String.format("http://%s", "myserver.com") + "/" + request.getParameter("uri9");
|
||||
HttpRequest r9 = HttpRequest.newBuilder(new URI(safeUri9)).build();
|
||||
client.send(r9, null);
|
||||
|
||||
// BAD: cases where a string that would sanitise is used, but occurs in the wrong
|
||||
// place to sanitise user input:
|
||||
String unsafeUri3 = request.getParameter("baduri3") + "https://example.com/";
|
||||
HttpRequest unsafer3 = HttpRequest.newBuilder(new URI(unsafeUri3)).build(); // $ SSRF
|
||||
client.send(unsafer3, null);
|
||||
|
||||
String unsafeUri4 = ("someprefix" + request.getParameter("baduri4")) + "https://example.com/";
|
||||
HttpRequest unsafer4 = HttpRequest.newBuilder(new URI(unsafeUri4)).build(); // $ SSRF
|
||||
client.send(unsafer4, null);
|
||||
|
||||
StringBuilder unsafeUri5 = new StringBuilder();
|
||||
unsafeUri5.append(request.getParameter("baduri5")).append("https://example.com/");
|
||||
HttpRequest unsafer5 = HttpRequest.newBuilder(new URI(unsafeUri5.toString())).build(); // $ SSRF
|
||||
client.send(unsafer5, null);
|
||||
|
||||
StringBuilder unafeUri5a = new StringBuilder(request.getParameter("uri5a"));
|
||||
unafeUri5a.append("https://example.com/");
|
||||
HttpRequest unsafer5a = HttpRequest.newBuilder(new URI(unafeUri5a.toString())).build(); // $ SSRF
|
||||
client.send(unsafer5a, null);
|
||||
|
||||
StringBuilder unsafeUri5b = (new StringBuilder(request.getParameter("uri5b"))).append("dir/");
|
||||
unsafeUri5b.append("https://example.com/");
|
||||
HttpRequest unsafer5b = HttpRequest.newBuilder(new URI(unsafeUri5b.toString())).build(); // $ SSRF
|
||||
client.send(unsafer5b, null);
|
||||
|
||||
StringBuilder unsafeUri5c = (new StringBuilder("https")).append(request.getParameter("uri5c"));
|
||||
unsafeUri5c.append("://example.com/dir/");
|
||||
HttpRequest unsafer5c = HttpRequest.newBuilder(new URI(unsafeUri5c.toString())).build(); // $ SSRF
|
||||
client.send(unsafer5c, null);
|
||||
|
||||
String unsafeUri6 = String.format("%shttps://example.com/", request.getParameter("baduri6"));
|
||||
HttpRequest unsafer6 = HttpRequest.newBuilder(new URI(unsafeUri6)).build(); // $ SSRF
|
||||
client.send(unsafer6, null);
|
||||
|
||||
String unsafeUri7 = String.format("%s/%s", request.getParameter("baduri7"), "https://example.com");
|
||||
HttpRequest unsafer7 = HttpRequest.newBuilder(new URI(unsafeUri7)).build(); // $ SSRF
|
||||
client.send(unsafer7, null);
|
||||
|
||||
String unsafeUri8 = String.format("%s%s", request.getParameter("baduri8"), "https://example.com/");
|
||||
HttpRequest unsafer8 = HttpRequest.newBuilder(new URI(unsafeUri8)).build(); // $ SSRF
|
||||
client.send(unsafer8, null);
|
||||
|
||||
String unsafeUri9 = request.getParameter("baduri9") + "/" + String.format("http://%s", "myserver.com");
|
||||
HttpRequest unsafer9 = HttpRequest.newBuilder(new URI(unsafeUri9)).build(); // $ SSRF
|
||||
client.send(unsafer9, null);
|
||||
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
}
|
||||
}
|
||||
70
java/ql/test/query-tests/security/CWE-918/SpringSSRF.java
Normal file
70
java/ql/test/query-tests/security/CWE-918/SpringSSRF.java
Normal file
@@ -0,0 +1,70 @@
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import java.net.URI;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.*;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.Proxy.Type;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class SpringSSRF extends HttpServlet {
|
||||
|
||||
protected void doGet(HttpServletRequest request2, HttpServletResponse response2)
|
||||
throws ServletException, IOException {
|
||||
String fooResourceUrl = request2.getParameter("uri");;
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
HttpEntity<String> request = new HttpEntity<>(new String("bar"));
|
||||
try {
|
||||
restTemplate.getForEntity(fooResourceUrl + "/1", String.class); // $ SSRF
|
||||
restTemplate.exchange(fooResourceUrl, HttpMethod.POST, request, String.class); // $ SSRF
|
||||
restTemplate.execute(fooResourceUrl, HttpMethod.POST, null, null, "test"); // $ SSRF
|
||||
restTemplate.getForObject(fooResourceUrl, String.class, "test"); // $ SSRF
|
||||
restTemplate.patchForObject(fooResourceUrl, new String("object"), String.class, "hi"); // $ SSRF
|
||||
restTemplate.postForEntity(new URI(fooResourceUrl), new String("object"), String.class); // $ SSRF
|
||||
restTemplate.postForLocation(fooResourceUrl, new String("object")); // $ SSRF
|
||||
restTemplate.postForObject(fooResourceUrl, new String("object"), String.class); // $ SSRF
|
||||
restTemplate.put(fooResourceUrl, new String("object")); // $ SSRF
|
||||
restTemplate.delete(fooResourceUrl); // $ SSRF
|
||||
restTemplate.headForHeaders(fooResourceUrl); // $ SSRF
|
||||
restTemplate.optionsForAllow(fooResourceUrl); // $ SSRF
|
||||
{
|
||||
String body = new String("body");
|
||||
URI uri = new URI(fooResourceUrl);
|
||||
RequestEntity<String> requestEntity =
|
||||
RequestEntity.post(uri).body(body); // $ SSRF
|
||||
ResponseEntity<String> response = restTemplate.exchange(requestEntity, String.class);
|
||||
RequestEntity.get(uri); // $ SSRF
|
||||
RequestEntity.put(uri); // $ SSRF
|
||||
RequestEntity.delete(uri); // $ SSRF
|
||||
RequestEntity.options(uri); // $ SSRF
|
||||
RequestEntity.patch(uri); // $ SSRF
|
||||
RequestEntity.head(uri); // $ SSRF
|
||||
RequestEntity.method(null, uri); // $ SSRF
|
||||
}
|
||||
{
|
||||
URI uri = new URI(fooResourceUrl);
|
||||
MultiValueMap<String, String> headers = null;
|
||||
java.lang.reflect.Type type = null;
|
||||
new RequestEntity<String>(null, uri); // $ SSRF
|
||||
new RequestEntity<String>(headers, null, uri); // $ SSRF
|
||||
new RequestEntity<String>("body", null, uri); // $ SSRF
|
||||
new RequestEntity<String>("body", headers, null, uri); // $ SSRF
|
||||
new RequestEntity<String>("body", null, uri, type); // $ SSRF
|
||||
new RequestEntity<String>("body", headers, null, uri, type); // $ SSRF
|
||||
}
|
||||
} catch (org.springframework.web.client.RestClientException | java.net.URISyntaxException e) {}
|
||||
}
|
||||
}
|
||||
1
java/ql/test/query-tests/security/CWE-918/options
Normal file
1
java/ql/test/query-tests/security/CWE-918/options
Normal file
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/springframework-5.2.3:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/servlet-api-2.4/
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.http.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* This annotation defines behavioral contract enforced at runtime by instances of annotated classes.
|
||||
*/
|
||||
@Documented
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
public @interface Contract {
|
||||
|
||||
ThreadingBehavior threading() default ThreadingBehavior.UNSAFE;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.apache.http.annotation.ThreadingBehavior;
|
||||
import org.apache.http.annotation.Contract;
|
||||
|
||||
/**
|
||||
* Holds all of the variables needed to describe an HTTP connection to a host.
|
||||
* This includes remote host name, port and scheme.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
@Contract(threading = ThreadingBehavior.IMMUTABLE)
|
||||
public final class HttpHost implements Cloneable, Serializable {
|
||||
|
||||
/** The default scheme is "http". */
|
||||
public static final String DEFAULT_SCHEME_NAME = "http";
|
||||
|
||||
/**
|
||||
* Creates {@code HttpHost} instance with the given scheme, hostname and port.
|
||||
*
|
||||
* @param hostname the hostname (IP or DNS name)
|
||||
* @param port the port number.
|
||||
* {@code -1} indicates the scheme default port.
|
||||
* @param scheme the name of the scheme.
|
||||
* {@code null} indicates the
|
||||
* {@link #DEFAULT_SCHEME_NAME default scheme}
|
||||
*/
|
||||
public HttpHost(final String hostname, final int port, final String scheme) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@code HttpHost} instance with the default scheme and the given hostname and port.
|
||||
*
|
||||
* @param hostname the hostname (IP or DNS name)
|
||||
* @param port the port number.
|
||||
* {@code -1} indicates the scheme default port.
|
||||
*/
|
||||
public HttpHost(final String hostname, final int port) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@code HttpHost} instance from string. Text may not contain any blanks.
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
public static HttpHost create(final String s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@code HttpHost} instance with the default scheme and port and the given hostname.
|
||||
*
|
||||
* @param hostname the hostname (IP or DNS name)
|
||||
*/
|
||||
public HttpHost(final String hostname) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@code HttpHost} instance with the given scheme, inet address and port.
|
||||
*
|
||||
* @param address the inet address.
|
||||
* @param port the port number.
|
||||
* {@code -1} indicates the scheme default port.
|
||||
* @param scheme the name of the scheme.
|
||||
* {@code null} indicates the
|
||||
* {@link #DEFAULT_SCHEME_NAME default scheme}
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
public HttpHost(final InetAddress address, final int port, final String scheme) {
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link HttpHost HttpHost}, specifying all values.
|
||||
* Constructor for HttpHost.
|
||||
*
|
||||
* @param address the inet address.
|
||||
* @param hostname the hostname (IP or DNS name)
|
||||
* @param port the port number.
|
||||
* {@code -1} indicates the scheme default port.
|
||||
* @param scheme the name of the scheme.
|
||||
* {@code null} indicates the
|
||||
* {@link #DEFAULT_SCHEME_NAME default scheme}
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
public HttpHost(final InetAddress address, final String hostname, final int port, final String scheme) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@code HttpHost} instance with the default scheme and the given inet address
|
||||
* and port.
|
||||
*
|
||||
* @param address the inet address.
|
||||
* @param port the port number.
|
||||
* {@code -1} indicates the scheme default port.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
public HttpHost(final InetAddress address, final int port) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@code HttpHost} instance with the default scheme and port and the given inet
|
||||
* address.
|
||||
*
|
||||
* @param address the inet address.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
public HttpHost(final InetAddress address) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor for {@link HttpHost HttpHost}.
|
||||
*
|
||||
* @param httphost the HTTP host to copy details from
|
||||
*/
|
||||
public HttpHost (final HttpHost httphost) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the host name.
|
||||
*
|
||||
* @return the host name (IP or DNS name)
|
||||
*/
|
||||
public String getHostName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the port.
|
||||
*
|
||||
* @return the host port, or {@code -1} if not set
|
||||
*/
|
||||
public int getPort() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scheme name.
|
||||
*
|
||||
* @return the scheme name
|
||||
*/
|
||||
public String getSchemeName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the inet address if explicitly set by a constructor,
|
||||
* {@code null} otherwise.
|
||||
* @return the inet address
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
public InetAddress getAddress() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the host URI, as a string.
|
||||
*
|
||||
* @return the host URI
|
||||
*/
|
||||
public String toURI() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtains the host string, without scheme prefix.
|
||||
*
|
||||
* @return the host string, for example {@code localhost:8080}
|
||||
*/
|
||||
public String toHostString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.http.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* This annotation defines behavioral contract enforced at runtime by instances of annotated classes.
|
||||
*/
|
||||
@Documented
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
public @interface Contract {
|
||||
|
||||
ThreadingBehavior threading() default ThreadingBehavior.UNSAFE;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.http.annotation;
|
||||
|
||||
/**
|
||||
Defines types of threading behavior enforced at runtime.
|
||||
*/
|
||||
public enum ThreadingBehavior {
|
||||
|
||||
/**
|
||||
* Instances of classes with the given contract are expected to be fully immutable
|
||||
* and thread-safe.
|
||||
*/
|
||||
IMMUTABLE,
|
||||
|
||||
/**
|
||||
* Instances of classes with the given contract are expected to be immutable if their
|
||||
* dependencies injected at construction time are immutable and are expected to be thread-safe
|
||||
* if their dependencies are thread-safe.
|
||||
*/
|
||||
IMMUTABLE_CONDITIONAL,
|
||||
|
||||
/**
|
||||
* Instances of classes with the given contract are expected to be fully thread-safe.
|
||||
*/
|
||||
SAFE,
|
||||
|
||||
/**
|
||||
* Instances of classes with the given contract are expected to be thread-safe if their
|
||||
* dependencies injected at construction time are thread-safe.
|
||||
*/
|
||||
SAFE_CONDITIONAL,
|
||||
|
||||
/**
|
||||
* Instances of classes with the given contract are expected to be non thread-safe.
|
||||
*/
|
||||
UNSAFE
|
||||
|
||||
}
|
||||
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.client.config;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.annotation.Contract;
|
||||
import org.apache.http.annotation.ThreadingBehavior;
|
||||
|
||||
/**
|
||||
* Immutable class encapsulating request configuration items.
|
||||
* The default setting for stale connection checking changed
|
||||
* to false, and the feature was deprecated starting with version 4.4.
|
||||
*/
|
||||
@Contract(threading = ThreadingBehavior.IMMUTABLE)
|
||||
public class RequestConfig implements Cloneable {
|
||||
|
||||
public static final RequestConfig DEFAULT = null;
|
||||
|
||||
/**
|
||||
* Intended for CDI compatibility
|
||||
*/
|
||||
protected RequestConfig() {
|
||||
}
|
||||
|
||||
RequestConfig(
|
||||
final boolean expectContinueEnabled,
|
||||
final HttpHost proxy,
|
||||
final InetAddress localAddress,
|
||||
final boolean staleConnectionCheckEnabled,
|
||||
final String cookieSpec,
|
||||
final boolean redirectsEnabled,
|
||||
final boolean relativeRedirectsAllowed,
|
||||
final boolean circularRedirectsAllowed,
|
||||
final int maxRedirects,
|
||||
final boolean authenticationEnabled,
|
||||
final Collection<String> targetPreferredAuthSchemes,
|
||||
final Collection<String> proxyPreferredAuthSchemes,
|
||||
final int connectionRequestTimeout,
|
||||
final int connectTimeout,
|
||||
final int socketTimeout,
|
||||
final boolean contentCompressionEnabled,
|
||||
final boolean normalizeUri) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the 'Expect: 100-Continue' handshake is enabled
|
||||
* for entity enclosing methods. The purpose of the 'Expect: 100-Continue'
|
||||
* handshake is to allow a client that is sending a request message with
|
||||
* a request body to determine if the origin server is willing to
|
||||
* accept the request (based on the request headers) before the client
|
||||
* sends the request body.
|
||||
* <p>
|
||||
* The use of the 'Expect: 100-continue' handshake can result in
|
||||
* a noticeable performance improvement for entity enclosing requests
|
||||
* (such as POST and PUT) that require the target server's
|
||||
* authentication.
|
||||
* </p>
|
||||
* <p>
|
||||
* 'Expect: 100-continue' handshake should be used with caution, as it
|
||||
* may cause problems with HTTP servers and proxies that do not support
|
||||
* HTTP/1.1 protocol.
|
||||
* </p>
|
||||
* <p>
|
||||
* Default: {@code false}
|
||||
* </p>
|
||||
*/
|
||||
public boolean isExpectContinueEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTTP proxy to be used for request execution.
|
||||
* <p>
|
||||
* Default: {@code null}
|
||||
* </p>
|
||||
*/
|
||||
public HttpHost getProxy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns local address to be used for request execution.
|
||||
* <p>
|
||||
* On machines with multiple network interfaces, this parameter
|
||||
* can be used to select the network interface from which the
|
||||
* connection originates.
|
||||
* </p>
|
||||
* <p>
|
||||
* Default: {@code null}
|
||||
* </p>
|
||||
*/
|
||||
public InetAddress getLocalAddress() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether stale connection check is to be used. The stale
|
||||
* connection check can cause up to 30 millisecond overhead per request and
|
||||
* should be used only when appropriate. For performance critical
|
||||
* operations this check should be disabled.
|
||||
* <p>
|
||||
* Default: {@code false} since 4.4
|
||||
* </p>
|
||||
*
|
||||
* @deprecated (4.4) Use {@link
|
||||
* org.apache.http.impl.conn.PoolingHttpClientConnectionManager#getValidateAfterInactivity()}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isStaleConnectionCheckEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the name of the cookie specification to be used for HTTP state
|
||||
* management.
|
||||
* <p>
|
||||
* Default: {@code null}
|
||||
* </p>
|
||||
*/
|
||||
public String getCookieSpec() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether redirects should be handled automatically.
|
||||
* <p>
|
||||
* Default: {@code true}
|
||||
* </p>
|
||||
*/
|
||||
public boolean isRedirectsEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether relative redirects should be rejected. HTTP specification
|
||||
* requires the location value be an absolute URI.
|
||||
* <p>
|
||||
* Default: {@code true}
|
||||
* </p>
|
||||
*/
|
||||
public boolean isRelativeRedirectsAllowed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether circular redirects (redirects to the same location) should
|
||||
* be allowed. The HTTP spec is not sufficiently clear whether circular redirects
|
||||
* are permitted, therefore optionally they can be enabled
|
||||
* <p>
|
||||
* Default: {@code false}
|
||||
* </p>
|
||||
*/
|
||||
public boolean isCircularRedirectsAllowed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of redirects to be followed. The limit on number
|
||||
* of redirects is intended to prevent infinite loops.
|
||||
* <p>
|
||||
* Default: {@code 50}
|
||||
* </p>
|
||||
*/
|
||||
public int getMaxRedirects() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether authentication should be handled automatically.
|
||||
* <p>
|
||||
* Default: {@code true}
|
||||
* </p>
|
||||
*/
|
||||
public boolean isAuthenticationEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the order of preference for supported authentication schemes
|
||||
* when authenticating with the target host.
|
||||
* <p>
|
||||
* Default: {@code null}
|
||||
* </p>
|
||||
*/
|
||||
public Collection<String> getTargetPreferredAuthSchemes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the order of preference for supported authentication schemes
|
||||
* when authenticating with the proxy host.
|
||||
* <p>
|
||||
* Default: {@code null}
|
||||
* </p>
|
||||
*/
|
||||
public Collection<String> getProxyPreferredAuthSchemes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timeout in milliseconds used when requesting a connection
|
||||
* from the connection manager.
|
||||
* <p>
|
||||
* A timeout value of zero is interpreted as an infinite timeout.
|
||||
* A negative value is interpreted as undefined (system default if applicable).
|
||||
* </p>
|
||||
* <p>
|
||||
* Default: {@code -1}
|
||||
* </p>
|
||||
*/
|
||||
public int getConnectionRequestTimeout() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the timeout in milliseconds until a connection is established.
|
||||
* <p>
|
||||
* A timeout value of zero is interpreted as an infinite timeout.
|
||||
* A negative value is interpreted as undefined (system default if applicable).
|
||||
* </p>
|
||||
* <p>
|
||||
* Default: {@code -1}
|
||||
* </p>
|
||||
*/
|
||||
public int getConnectTimeout() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the socket timeout ({@code SO_TIMEOUT}) in milliseconds,
|
||||
* which is the timeout for waiting for data or, put differently,
|
||||
* a maximum period inactivity between two consecutive data packets).
|
||||
* <p>
|
||||
* A timeout value of zero is interpreted as an infinite timeout.
|
||||
* A negative value is interpreted as undefined (system default if applicable).
|
||||
* </p>
|
||||
* <p>
|
||||
* Default: {@code -1}
|
||||
* </p>
|
||||
*/
|
||||
public int getSocketTimeout() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether compressed entities should be decompressed automatically.
|
||||
* <p>
|
||||
* Default: {@code true}
|
||||
* </p>
|
||||
*
|
||||
* @since 4.4
|
||||
* @deprecated (4.5) Use {@link #isContentCompressionEnabled()}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isDecompressionEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the target server is requested to compress content.
|
||||
* <p>
|
||||
* Default: {@code true}
|
||||
* </p>
|
||||
*
|
||||
* @since 4.5
|
||||
*/
|
||||
public boolean isContentCompressionEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether client should normalize URIs in requests or not.
|
||||
* <p>
|
||||
* Default: {@code true}
|
||||
* </p>
|
||||
*
|
||||
* @since 4.5.8
|
||||
*/
|
||||
public boolean isNormalizeUri() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RequestConfig clone() throws CloneNotSupportedException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RequestConfig.Builder custom() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static RequestConfig.Builder copy(final RequestConfig config) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
Builder() {
|
||||
}
|
||||
|
||||
public Builder setExpectContinueEnabled(final boolean expectContinueEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setProxy(final HttpHost proxy) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setLocalAddress(final InetAddress localAddress) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated (4.4) Use {@link
|
||||
* org.apache.http.impl.conn.PoolingHttpClientConnectionManager#setValidateAfterInactivity(int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder setStaleConnectionCheckEnabled(final boolean staleConnectionCheckEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setCookieSpec(final String cookieSpec) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setRedirectsEnabled(final boolean redirectsEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setRelativeRedirectsAllowed(final boolean relativeRedirectsAllowed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setCircularRedirectsAllowed(final boolean circularRedirectsAllowed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setMaxRedirects(final int maxRedirects) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setAuthenticationEnabled(final boolean authenticationEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setTargetPreferredAuthSchemes(final Collection<String> targetPreferredAuthSchemes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setProxyPreferredAuthSchemes(final Collection<String> proxyPreferredAuthSchemes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setConnectionRequestTimeout(final int connectionRequestTimeout) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setConnectTimeout(final int connectTimeout) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setSocketTimeout(final int socketTimeout) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated (4.5) Set {@link #setContentCompressionEnabled(boolean)} to {@code false} and
|
||||
* add the {@code Accept-Encoding} request header.
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder setDecompressionEnabled(final boolean decompressionEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setContentCompressionEnabled(final boolean contentCompressionEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Builder setNormalizeUri(final boolean normalizeUri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestConfig build() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.client.methods;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* HTTP DELETE method
|
||||
* <p>
|
||||
* The HTTP DELETE method is defined in section 9.7 of
|
||||
* <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>:
|
||||
* <blockquote>
|
||||
* The DELETE method requests that the origin server delete the resource
|
||||
* identified by the Request-URI. [...] The client cannot
|
||||
* be guaranteed that the operation has been carried out, even if the
|
||||
* status code returned from the origin server indicates that the action
|
||||
* has been completed successfully.
|
||||
* </blockquote>
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class HttpDelete extends HttpRequestBase {
|
||||
|
||||
public final static String METHOD_NAME = "DELETE";
|
||||
|
||||
|
||||
public HttpDelete() {
|
||||
}
|
||||
|
||||
public HttpDelete(final URI uri) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException if the uri is invalid.
|
||||
*/
|
||||
public HttpDelete(final String uri) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.client.methods;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* HTTP HEAD method.
|
||||
* <p>
|
||||
* The HTTP HEAD method is defined in section 9.4 of
|
||||
* <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>:
|
||||
* </p>
|
||||
* <blockquote>
|
||||
* The HEAD method is identical to GET except that the server MUST NOT
|
||||
* return a message-body in the response. The metainformation contained
|
||||
* in the HTTP headers in response to a HEAD request SHOULD be identical
|
||||
* to the information sent in response to a GET request. This method can
|
||||
* be used for obtaining metainformation about the entity implied by the
|
||||
* request without transferring the entity-body itself. This method is
|
||||
* often used for testing hypertext links for validity, accessibility,
|
||||
* and recent modification.
|
||||
* </blockquote>
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class HttpHead extends HttpRequestBase {
|
||||
|
||||
public final static String METHOD_NAME = "HEAD";
|
||||
|
||||
public HttpHead() {
|
||||
}
|
||||
|
||||
public HttpHead(final URI uri) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException if the uri is invalid.
|
||||
*/
|
||||
public HttpHead(final String uri) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.client.methods;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HeaderElement;
|
||||
import org.apache.http.HeaderIterator;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.util.Args;
|
||||
|
||||
/**
|
||||
* HTTP OPTIONS method.
|
||||
* <p>
|
||||
* The HTTP OPTIONS method is defined in section 9.2 of
|
||||
* <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>:
|
||||
* </p>
|
||||
* <blockquote>
|
||||
* The OPTIONS method represents a request for information about the
|
||||
* communication options available on the request/response chain
|
||||
* identified by the Request-URI. This method allows the client to
|
||||
* determine the options and/or requirements associated with a resource,
|
||||
* or the capabilities of a server, without implying a resource action
|
||||
* or initiating a resource retrieval.
|
||||
* </blockquote>
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class HttpOptions extends HttpRequestBase {
|
||||
|
||||
public final static String METHOD_NAME = "OPTIONS";
|
||||
|
||||
public HttpOptions() {
|
||||
}
|
||||
|
||||
public HttpOptions(final URI uri) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException if the uri is invalid.
|
||||
*/
|
||||
public HttpOptions(final String uri) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<String> getAllowedMethods(final HttpResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.client.methods;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* HTTP PATCH method.
|
||||
* <p>
|
||||
* The HTTP PATCH method is defined in <a
|
||||
* href="http://tools.ietf.org/html/rfc5789">RF5789</a>:
|
||||
* </p>
|
||||
* <blockquote> The PATCH
|
||||
* method requests that a set of changes described in the request entity be
|
||||
* applied to the resource identified by the Request- URI. Differs from the PUT
|
||||
* method in the way the server processes the enclosed entity to modify the
|
||||
* resource identified by the Request-URI. In a PUT request, the enclosed entity
|
||||
* origin server, and the client is requesting that the stored version be
|
||||
* replaced. With PATCH, however, the enclosed entity contains a set of
|
||||
* instructions describing how a resource currently residing on the origin
|
||||
* server should be modified to produce a new version.
|
||||
* </blockquote>
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public class HttpPatch extends HttpEntityEnclosingRequestBase {
|
||||
|
||||
public final static String METHOD_NAME = "PATCH";
|
||||
|
||||
public HttpPatch() {
|
||||
}
|
||||
|
||||
public HttpPatch(final URI uri) {
|
||||
}
|
||||
|
||||
public HttpPatch(final String uri) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.client.methods;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* HTTP TRACE method.
|
||||
* <p>
|
||||
* The HTTP TRACE method is defined in section 9.6 of
|
||||
* <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>:
|
||||
* </p>
|
||||
* <blockquote>
|
||||
* The TRACE method is used to invoke a remote, application-layer loop-
|
||||
* back of the request message. The final recipient of the request
|
||||
* SHOULD reflect the message received back to the client as the
|
||||
* entity-body of a 200 (OK) response. The final recipient is either the
|
||||
* origin server or the first proxy or gateway to receive a Max-Forwards
|
||||
* value of zero (0) in the request (see section 14.31). A TRACE request
|
||||
* MUST NOT include an entity.
|
||||
* </blockquote>
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class HttpTrace extends HttpRequestBase {
|
||||
|
||||
public final static String METHOD_NAME = "TRACE";
|
||||
|
||||
public HttpTrace() {
|
||||
}
|
||||
|
||||
public HttpTrace(final URI uri) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException if the uri is invalid.
|
||||
*/
|
||||
public HttpTrace(final String uri) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return METHOD_NAME;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.client.methods;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.http.HttpRequest;
|
||||
|
||||
/**
|
||||
* Extended version of the {@link HttpRequest} interface that provides
|
||||
* convenience methods to access request properties such as request URI
|
||||
* and method type.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public interface HttpUriRequest extends HttpRequest {
|
||||
|
||||
/**
|
||||
* Returns the HTTP method this request uses, such as {@code GET},
|
||||
* {@code PUT}, {@code POST}, or other.
|
||||
*/
|
||||
String getMethod();
|
||||
|
||||
/**
|
||||
* Returns the URI this request uses, such as
|
||||
* {@code http://example.org/path/to/file}.
|
||||
* <p>
|
||||
* Note that the URI may be absolute URI (as above) or may be a relative URI.
|
||||
* </p>
|
||||
* <p>
|
||||
* Implementations are encouraged to return
|
||||
* the URI that was initially requested.
|
||||
* </p>
|
||||
* <p>
|
||||
* To find the final URI after any redirects have been processed,
|
||||
* please see the section entitled
|
||||
* <a href="http://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html#d4e205">HTTP execution context</a>
|
||||
* in the
|
||||
* <a href="http://hc.apache.org/httpcomponents-client-ga/tutorial/html">HttpClient Tutorial</a>
|
||||
* </p>
|
||||
*/
|
||||
URI getURI();
|
||||
|
||||
/**
|
||||
* Aborts execution of the request.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the abort operation
|
||||
* is not supported / cannot be implemented.
|
||||
*/
|
||||
void abort() throws UnsupportedOperationException;
|
||||
|
||||
/**
|
||||
* Tests if the request execution has been aborted.
|
||||
*
|
||||
* @return {@code true} if the request execution has been aborted,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
boolean isAborted();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
*
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.http.client.methods;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
|
||||
/**
|
||||
* Builder for {@link HttpUriRequest} instances.
|
||||
* <p>
|
||||
* Please note that this class treats parameters differently depending on composition
|
||||
* of the request: if the request has a content entity explicitly set with
|
||||
* {@link #setEntity(org.apache.http.HttpEntity)} or it is not an entity enclosing method
|
||||
* (such as POST or PUT), parameters will be added to the query component of the request URI.
|
||||
* Otherwise, parameters will be added as a URL encoded {@link UrlEncodedFormEntity entity}.
|
||||
* </p>
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
public class RequestBuilder {
|
||||
|
||||
RequestBuilder(final String method) {
|
||||
}
|
||||
|
||||
RequestBuilder(final String method, final URI uri) {
|
||||
}
|
||||
|
||||
RequestBuilder(final String method, final String uri) {
|
||||
}
|
||||
|
||||
RequestBuilder() {
|
||||
}
|
||||
|
||||
public static RequestBuilder create(final String method) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RequestBuilder get() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder get(final URI uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder get(final String uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RequestBuilder head() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder head(final URI uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder head(final String uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder patch() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder patch(final URI uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder patch(final String uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RequestBuilder post() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder post(final URI uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder post(final String uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RequestBuilder put() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder put(final URI uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder put(final String uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RequestBuilder delete() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder delete(final URI uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder delete(final String uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RequestBuilder trace() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder trace(final URI uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder trace(final String uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RequestBuilder options() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder options(final URI uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public static RequestBuilder options(final String uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RequestBuilder copy(final HttpRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private RequestBuilder doCopy(final HttpRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public RequestBuilder setCharset(final Charset charset) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public Charset getCharset() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ProtocolVersion getVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder setVersion(final ProtocolVersion version) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public URI getUri() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder setUri(final URI uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder setUri(final String uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Header getFirstHeader(final String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Header getLastHeader(final String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Header[] getHeaders(final String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder addHeader(final Header header) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder addHeader(final String name, final String value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder removeHeader(final Header header) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder removeHeaders(final String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder setHeader(final Header header) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder setHeader(final String name, final String value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public HttpEntity getEntity() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder setEntity(final HttpEntity entity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<NameValuePair> getParameters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder addParameter(final NameValuePair nvp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder addParameter(final String name, final String value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder addParameters(final NameValuePair... nvps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestConfig getConfig() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RequestBuilder setConfig(final RequestConfig config) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public HttpUriRequest build() {
|
||||
return null;
|
||||
}
|
||||
|
||||
static class InternalRequest extends HttpRequestBase {
|
||||
|
||||
InternalRequest(final String method) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class InternalEntityEclosingRequest extends HttpEntityEnclosingRequestBase {
|
||||
|
||||
InternalEntityEclosingRequest(final String method) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,7 +43,7 @@ import org.apache.http.RequestLine;
|
||||
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
|
||||
*
|
||||
* @version $Revision: 618017 $
|
||||
*
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
|
||||
@@ -54,15 +54,15 @@ import org.apache.http.RequestLine;
|
||||
@Deprecated
|
||||
public class BasicHttpEntityEnclosingRequest extends BasicHttpRequest implements HttpEntityEnclosingRequest {
|
||||
public BasicHttpEntityEnclosingRequest(final String method, final String uri) {
|
||||
super(method, uri);
|
||||
super(null);
|
||||
}
|
||||
|
||||
public BasicHttpEntityEnclosingRequest(final String method, final String uri, final ProtocolVersion ver) {
|
||||
super(method, uri, ver);
|
||||
super(null);
|
||||
}
|
||||
|
||||
public BasicHttpEntityEnclosingRequest(final RequestLine requestline) {
|
||||
super(requestline);
|
||||
super(null);
|
||||
}
|
||||
|
||||
public HttpEntity getEntity() {
|
||||
|
||||
@@ -15,23 +15,23 @@
|
||||
*/
|
||||
|
||||
package javax.ws.rs.client;
|
||||
// import java.net.URI;
|
||||
import java.net.URI;
|
||||
import javax.ws.rs.core.Configurable;
|
||||
// import javax.ws.rs.core.Link;
|
||||
// import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.Link;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
// import javax.net.ssl.HostnameVerifier;
|
||||
// import javax.net.ssl.SSLContext;
|
||||
|
||||
public interface Client extends Configurable<Client> {
|
||||
public void close();
|
||||
|
||||
// public WebTarget target(String uri);
|
||||
public WebTarget target(String uri);
|
||||
|
||||
// public WebTarget target(URI uri);
|
||||
public WebTarget target(URI uri);
|
||||
|
||||
// public WebTarget target(UriBuilder uriBuilder);
|
||||
public WebTarget target(UriBuilder uriBuilder);
|
||||
|
||||
// public WebTarget target(Link link);
|
||||
public WebTarget target(Link link);
|
||||
|
||||
// public Invocation.Builder invocation(Link link);
|
||||
|
||||
|
||||
@@ -15,23 +15,23 @@
|
||||
*/
|
||||
|
||||
package jakarta.ws.rs.client;
|
||||
// import java.net.URI;
|
||||
import java.net.URI;
|
||||
// import javax.net.ssl.HostnameVerifier;
|
||||
// import javax.net.ssl.SSLContext;
|
||||
import jakarta.ws.rs.core.Configurable;
|
||||
// import jakarta.ws.rs.core.Link;
|
||||
// import jakarta.ws.rs.core.UriBuilder;
|
||||
import jakarta.ws.rs.core.Link;
|
||||
import jakarta.ws.rs.core.UriBuilder;
|
||||
|
||||
public interface Client extends Configurable<Client> {
|
||||
public void close();
|
||||
|
||||
// public WebTarget target(String uri);
|
||||
public WebTarget target(String uri);
|
||||
|
||||
// public WebTarget target(URI uri);
|
||||
public WebTarget target(URI uri);
|
||||
|
||||
// public WebTarget target(UriBuilder uriBuilder);
|
||||
public WebTarget target(UriBuilder uriBuilder);
|
||||
|
||||
// public WebTarget target(Link link);
|
||||
public WebTarget target(Link link);
|
||||
|
||||
// public Invocation.Builder invocation(Link link);
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package jakarta.ws.rs.client;
|
||||
|
||||
public abstract class ClientBuilder implements jakarta.ws.rs.core.Configurable {
|
||||
|
||||
protected ClientBuilder() {
|
||||
}
|
||||
|
||||
public static jakarta.ws.rs.client.ClientBuilder newBuilder() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static jakarta.ws.rs.client.Client newClient() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static jakarta.ws.rs.client.Client newClient(jakarta.ws.rs.core.Configuration configuration) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package jakarta.ws.rs.client;
|
||||
|
||||
public abstract interface WebTarget extends jakarta.ws.rs.core.Configurable {
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package jakarta.ws.rs.core;
|
||||
|
||||
public abstract interface Configuration {}
|
||||
Reference in New Issue
Block a user