Skip to content

Commit 463153f

Browse files
authored
Merge pull request #200 from tencentyun/dev/update_demo
check get obj path & fix xxe
2 parents b8cc2ea + f2dca03 commit 463153f

File tree

8 files changed

+89
-5
lines changed

8 files changed

+89
-5
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>com.qcloud</groupId>
66
<artifactId>cos_api</artifactId>
7-
<version>5.6.211</version>
7+
<version>5.6.212</version>
88
<packaging>jar</packaging>
99
<name>cos-java-sdk</name>
1010
<description>java sdk for qcloud cos</description>

src/main/java/com/qcloud/cos/COSClient.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,11 @@ public COSObject getObject(GetObjectRequest getObjectRequest)
10701070
rejectNull(clientConfig.getRegion(),
10711071
"region is null, region in clientConfig must be specified when requesting an object");
10721072

1073+
if (clientConfig.isCheckRequestPath()) {
1074+
if (StringUtils.isRequestPathInvalid(getObjectRequest.getKey())) {
1075+
throw new IllegalArgumentException("The key you specified is invalid");
1076+
}
1077+
}
10731078

10741079
CosHttpRequest<GetObjectRequest> request = createRequest(getObjectRequest.getBucketName(),
10751080
getObjectRequest.getKey(), getObjectRequest, HttpMethodName.GET);

src/main/java/com/qcloud/cos/ClientConfig.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ public class ClientConfig {
111111

112112
private boolean isPrintShutdownStackTrace = true;
113113

114+
private boolean isCheckRequestPath = true;
115+
116+
private int timeout_client_thread_size = 0;
117+
118+
private int error_log_status_code_thresh = 500;
119+
114120
// 不传入region 用于后续调用List Buckets(获取所有的bucket信息)
115121
public ClientConfig() {
116122
super();
@@ -379,4 +385,28 @@ public boolean isPrintShutdownStackTrace() {
379385
public void setPrintShutdownStackTrace(boolean printShutdownStackTrace) {
380386
isPrintShutdownStackTrace = printShutdownStackTrace;
381387
}
388+
389+
public void setCheckRequestPath(boolean isCheck) {
390+
isCheckRequestPath = isCheck;
391+
}
392+
393+
public boolean isCheckRequestPath() {
394+
return isCheckRequestPath;
395+
}
396+
397+
public int getTimeoutClientThreadSize() {
398+
return timeout_client_thread_size;
399+
}
400+
401+
public void setTimeoutClientThreadSize(int pool_size) {
402+
timeout_client_thread_size = pool_size;
403+
}
404+
405+
public void setErrorLogStatusCodeThresh(int status_code) {
406+
error_log_status_code_thresh = status_code;
407+
}
408+
409+
public int getErrorLogStatusCodeThresh() {
410+
return error_log_status_code_thresh;
411+
}
382412
}

src/main/java/com/qcloud/cos/http/DefaultCosHttpClient.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,11 @@ public <X, Y extends CosServiceRequest> X exeute(CosHttpRequest<Y> request,
517517
retryIndex, maxErrorRetry);
518518
request.addLogDetails(new ExceptionLogDetail(cse, errorMsg));
519519
if (!shouldRetry(request, httpResponse, cse, retryIndex, retryPolicy)) {
520-
if (cse.getStatusCode() >= 400) {
520+
int status_code_thresh = clientConfig.getErrorLogStatusCodeThresh();
521+
if (status_code_thresh < 0) {
522+
status_code_thresh = 500;
523+
}
524+
if (cse.getStatusCode() >= status_code_thresh) {
521525
handleLog(request);
522526
}
523527
throw cse;

src/main/java/com/qcloud/cos/http/TimeOutCosHttpClient.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ public class TimeOutCosHttpClient extends DefaultCosHttpClient{
1919

2020
public TimeOutCosHttpClient(ClientConfig clientConfig) {
2121
super(clientConfig);
22-
threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 5);
22+
int pool_size = clientConfig.getTimeoutClientThreadSize();
23+
if (pool_size <= 0) {
24+
pool_size = Runtime.getRuntime().availableProcessors() * 5;
25+
}
26+
threadPool = Executors.newFixedThreadPool(pool_size);
2327
}
2428

2529
@Override

src/main/java/com/qcloud/cos/internal/CosErrorResponseHandler.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,15 @@ public class CosErrorResponseHandler implements HttpResponseHandler<CosServiceEx
4646
private static final Logger log = LoggerFactory.getLogger(CosErrorResponseHandler.class);
4747

4848
/** Shared factory for creating XML event readers */
49-
private static final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
49+
private static final XMLInputFactory xmlInputFactory = createXMLInputFactory();
50+
51+
private static XMLInputFactory createXMLInputFactory() {
52+
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
53+
inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
54+
inputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
55+
56+
return inputFactory;
57+
}
5058

5159
private static enum COSErrorTags {
5260
Error, Code, Message, Resource, RequestId, TraceId;

src/main/java/com/qcloud/cos/internal/XmlResponsesSaxParser.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ public XmlResponsesSaxParser() throws CosClientException {
237237
// Ensure we can load the XML Reader.
238238
try {
239239
xr = XMLReaderFactory.createXMLReader();
240+
xr.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
241+
xr.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
242+
xr.setFeature("http://xml.org/sax/features/external-general-entities", false);
243+
xr.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
240244
} catch (SAXException e) {
241245
throw new CosClientException("Couldn't initialize a SAX driver to create an XMLReader",
242246
e);

src/main/java/com/qcloud/cos/utils/StringUtils.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020

2121
import java.math.BigDecimal;
2222
import java.math.BigInteger;
23-
import java.nio.ByteBuffer;
2423
import java.nio.charset.Charset;
24+
import java.util.ArrayDeque;
2525
import java.util.Date;
26+
import java.util.Deque;
2627
import java.util.List;
28+
import java.util.Objects;
2729

2830
/**
2931
* Utilities for converting objects to strings.
@@ -223,4 +225,31 @@ public static String join(List<String> strings) {
223225
public static boolean beginsWithIgnoreCase(final String data, final String seq) {
224226
return data.regionMatches(true, 0, seq, 0, seq.length());
225227
}
228+
229+
public static boolean isRequestPathInvalid(String path) {
230+
String[] pathElements = path.split("/");
231+
Deque<String> stack = new ArrayDeque<>();
232+
233+
for (String pathElement : pathElements) {
234+
if (Objects.equals(pathElement, "..")) {
235+
if (!stack.isEmpty()) {
236+
stack.pollLast();
237+
}
238+
} else if (pathElement.length() > 0 && !Objects.equals(pathElement, ".")) {
239+
stack.offerLast(pathElement);
240+
}
241+
}
242+
243+
StringBuffer simplifyPath = new StringBuffer();
244+
if (stack.isEmpty()) {
245+
simplifyPath.append('/');
246+
} else {
247+
while (!stack.isEmpty()) {
248+
simplifyPath.append('/');
249+
simplifyPath.append(stack.pollFirst());
250+
}
251+
}
252+
253+
return Objects.equals(simplifyPath.toString(), "/");
254+
}
226255
}

0 commit comments

Comments
 (0)