Skip to content

Commit 3a48171

Browse files
John Burwellyadvr
authored andcommitted
CLOUDSTACK-8566: Strips the username and password credentials from host details
... map returned by the following API calls by filtering these fields from the details attribute in the HostResponse class: * listHosts * addHost * cancelHostMaintenance * listHosts * prepareHostForMaintenance * reconnectHost * updateHost This fix addresses CVE 2015-3251. Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
1 parent 17366f2 commit 3a48171

2 files changed

Lines changed: 109 additions & 10 deletions

File tree

api/src/org/apache/cloudstack/api/response/HostResponse.java

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,19 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.response;
1818

19-
import java.util.Date;
20-
import java.util.List;
21-
import java.util.Map;
22-
19+
import com.cloud.host.Host;
20+
import com.cloud.host.Status;
21+
import com.cloud.hypervisor.Hypervisor.HypervisorType;
22+
import com.cloud.serializer.Param;
2323
import com.google.gson.annotations.SerializedName;
24-
2524
import org.apache.cloudstack.api.ApiConstants;
2625
import org.apache.cloudstack.api.BaseResponse;
2726
import org.apache.cloudstack.api.EntityReference;
2827

29-
import com.cloud.host.Host;
30-
import com.cloud.host.Status;
31-
import com.cloud.hypervisor.Hypervisor.HypervisorType;
32-
import com.cloud.serializer.Param;
28+
import java.util.Date;
29+
import java.util.HashMap;
30+
import java.util.List;
31+
import java.util.Map;
3332

3433
@EntityReference(value = Host.class)
3534
public class HostResponse extends BaseResponse {
@@ -217,6 +216,12 @@ public class HostResponse extends BaseResponse {
217216
@Param(description = "Host details in key/value pairs.", since = "4.5")
218217
private Map details;
219218

219+
220+
// Default visibility to support accessing the details from unit tests
221+
Map getDetails() {
222+
return details;
223+
}
224+
220225
@Override
221226
public String getObjectId() {
222227
return this.getId();
@@ -423,7 +428,21 @@ public void setHaHost(Boolean haHost) {
423428
}
424429

425430
public void setDetails(Map details) {
426-
this.details = details;
431+
432+
if (details == null) {
433+
return;
434+
}
435+
436+
final Map detailsCopy = new HashMap(details);
437+
438+
// Fix for CVE ID 2015-3251
439+
// Remove sensitive host credential information from
440+
// the details to prevent leakage through API calls
441+
detailsCopy.remove("username");
442+
detailsCopy.remove("password");
443+
444+
this.details = detailsCopy;
445+
427446
}
428447

429448
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.api.response;
18+
19+
import junit.framework.TestCase;
20+
import org.apache.commons.collections.map.HashedMap;
21+
import org.junit.Test;
22+
23+
import java.util.HashMap;
24+
import java.util.Map;
25+
26+
public final class HostResponseTest extends TestCase {
27+
28+
private static final String VALID_KEY = "validkey";
29+
private static final String VALID_VALUE = "validvalue";
30+
31+
@Test
32+
public void testSetDetailsNull() {
33+
34+
final HostResponse hostResponse = new HostResponse();
35+
hostResponse.setDetails(null);
36+
37+
assertEquals(null, hostResponse.getDetails());
38+
39+
}
40+
41+
@Test
42+
public void testSetDetailsWithRootCredentials() {
43+
44+
final HostResponse hostResponse = new HostResponse();
45+
final Map details = new HashMap<>();
46+
47+
details.put(VALID_KEY, VALID_VALUE);
48+
details.put("username", "test");
49+
details.put("password", "password");
50+
51+
final Map expectedDetails = new HashedMap();
52+
expectedDetails.put(VALID_KEY, VALID_VALUE);
53+
54+
hostResponse.setDetails(details);
55+
final Map actualDetails = hostResponse.getDetails();
56+
57+
assertTrue(details != actualDetails);
58+
assertEquals(expectedDetails, actualDetails);
59+
60+
}
61+
62+
@Test
63+
public void testSetDetailsWithoutRootCredentials() {
64+
65+
final HostResponse hostResponse = new HostResponse();
66+
final Map details = new HashMap<>();
67+
68+
details.put(VALID_KEY, VALID_VALUE);
69+
70+
final Map expectedDetails = new HashedMap();
71+
expectedDetails.put(VALID_KEY, VALID_VALUE);
72+
73+
hostResponse.setDetails(details);
74+
final Map actualDetails = hostResponse.getDetails();
75+
76+
assertTrue(details != actualDetails);
77+
assertEquals(expectedDetails, actualDetails);
78+
79+
}
80+
}

0 commit comments

Comments
 (0)