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>
(cherry picked from commit 3a48171bd8a70c6012afce32c7636afffc1d2f7d)
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
John Burwell 2015-07-21 15:36:01 -04:00 committed by Rohit Yadav
parent ff66175f55
commit ef44c7d305
2 changed files with 110 additions and 11 deletions

View File

@ -16,20 +16,19 @@
// under the License.
package org.apache.cloudstack.api.response;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import com.cloud.host.Host;
import com.cloud.host.Status;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@EntityReference(value = Host.class)
public class HostResponse extends BaseResponse {
@ -217,6 +216,12 @@ public class HostResponse extends BaseResponse {
@Param(description = "Host details in key/value pairs.", since = "4.5")
private Map details;
// Default visibility to support accessing the details from unit tests
Map getDetails() {
return details;
}
@Override
public String getObjectId() {
return this.getId();
@ -423,7 +428,21 @@ public class HostResponse extends BaseResponse {
}
public void setDetails(Map details) {
this.details = details;
if (details == null) {
return;
}
final Map detailsCopy = new HashMap(details);
// Fix for CVE ID 2015-3251
// Remove sensitive host credential information from
// the details to prevent leakage through API calls
detailsCopy.remove("username");
detailsCopy.remove("password");
this.details = detailsCopy;
}
}

View File

@ -0,0 +1,80 @@
// 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.
package org.apache.cloudstack.api.response;
import junit.framework.TestCase;
import org.apache.commons.collections.map.HashedMap;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
public final class HostResponseTest extends TestCase {
private static final String VALID_KEY = "validkey";
private static final String VALID_VALUE = "validvalue";
@Test
public void testSetDetailsNull() {
final HostResponse hostResponse = new HostResponse();
hostResponse.setDetails(null);
assertEquals(null, hostResponse.getDetails());
}
@Test
public void testSetDetailsWithRootCredentials() {
final HostResponse hostResponse = new HostResponse();
final Map details = new HashMap<>();
details.put(VALID_KEY, VALID_VALUE);
details.put("username", "test");
details.put("password", "password");
final Map expectedDetails = new HashedMap();
expectedDetails.put(VALID_KEY, VALID_VALUE);
hostResponse.setDetails(details);
final Map actualDetails = hostResponse.getDetails();
assertTrue(details != actualDetails);
assertEquals(expectedDetails, actualDetails);
}
@Test
public void testSetDetailsWithoutRootCredentials() {
final HostResponse hostResponse = new HostResponse();
final Map details = new HashMap<>();
details.put(VALID_KEY, VALID_VALUE);
final Map expectedDetails = new HashedMap();
expectedDetails.put(VALID_KEY, VALID_VALUE);
hostResponse.setDetails(details);
final Map actualDetails = hostResponse.getDetails();
assertTrue(details != actualDetails);
assertEquals(expectedDetails, actualDetails);
}
}