Skip to content

Commit 8769597

Browse files
committed
Merge pull request #1763 from sudhansu7/CLOUDSTACK-9594
CLOUDSTACK-9594: API "list templates templatefilter=all" reveals allAPI "list templates templatefilter=all" reveals all templates. Using a "list templates templatefilter=all" API call any domain admin can see all templates of all domains in ACS. Information returned includes the account and domain of the template's owner. The template data shows what that VM is using and any hints from the label. This would give an advantage in what attack vectors to use. The account and domain can possibly be used in brute force attack to guess the password and login information. Test Scenario: created two accounts in different domain. ``` mysql> select account_id,username,api_key from user where id in (4,5); +------------+-----------+----------------------------------------------------------------------------------------+ | account_id | username | api_key | +------------+-----------+----------------------------------------------------------------------------------------+ | 4 | sudadmin1 | 3qeSuWadNzUFZ_i6c6zbwafjM3Eo0TWpkHw3En9jNsg5Ditk2N18DnbbL2quBYQ7FsdXQ8rwxbyFlE8vyUTwEg | | 5 | sudadmin | N5uHVOrg1Ek1F1a_5OXTz4WpLG3ewHqcbPUSBjQ-2CTJdxmUe2go0S8fyqH4Np0scYiehYg2KqthZXCWEyKx1A | +------------+-----------+----------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec) mysql> select account_name,domain_id from account where id in (4,5); +--------------+-----------+ | account_name | domain_id | +--------------+-----------+ | sudadmin | 2 | | sudadmin1 | 3 | +--------------+-----------+ 2 rows in set (0.00 sec) ``` User sudadmin registered a private template named 'Debian'. http://10.147.59.107:8080/client/api?apikey=N5uHVOrg1Ek1F1a_5OXTz4WpLG3ewHqcbPUSBjQ-2CTJdxmUe2go0S8fyqH4Np0scYiehYg2KqthZXCWEyKx1A&command=listTemplates&templatefilter=self&signature=ODt7zEWCLL20z1FT%2FIkd1molRaM%3D listTemplate with "templatefilter=self", lists the newly registered template. ``` <listtemplatesresponse cloud-stack-version="4.8.0"> <count>1</count> <template> <id>51026d32-60ee-4e25-8ffd-3fa3c57fc14c</id> <name>Debian</name> <displaytext>Debian</displaytext> <ispublic>false</ispublic> <created>2016-11-10T17:18:00-0500</created> <isready>true</isready> <passwordenabled>false</passwordenabled> <format>VHD</format> <isfeatured>false</isfeatured> <crossZones>false</crossZones> <ostypeid>38c1fc84-a687-11e6-a8c8-06f654000053</ostypeid> <ostypename>Debian GNU/Linux 7(64-bit)</ostypename> <account>sudadmin</account> <zoneid>25fa5b74-d4c2-4bad-8e3a-ceffcd10985e</zoneid> <zonename>z1</zonename> <status>Download Complete</status> <size>2621440000</size> <templatetype>USER</templatetype> <hypervisor>XenServer</hypervisor> <domain>SUDDOMAIN</domain> <domainid>a350c00d-4048-4876-ae09-74ad4b7bb28c</domainid> <isextractable>false</isextractable> <checksum>e87a6d7291b999c92baa9623c9c3c207</checksum> <details>{hypervisortoolsversion=xenserver61}</details> <sshkeyenabled>false</sshkeyenabled> <isdynamicallyscalable>false</isdynamicallyscalable> </template> </listtemplatesresponse> ``` User: sudadmin1 listTemplate with "templatefilter=self" does not list any template. http://10.147.59.107:8080/client/api?apikey=3qeSuWadNzUFZ_i6c6zbwafjM3Eo0TWpkHw3En9jNsg5Ditk2N18DnbbL2quBYQ7FsdXQ8rwxbyFlE8vyUTwEg&command=listTemplates&templatefilter=self&signature=RfKsdg3RxDkqJotbTlHU2RdbdPA%3D `<listtemplatesresponse cloud-stack-version="4.8.0"/> ` NO TEMPLATES **listTemplate with "templatefilter=all" lists all templates** http://10.147.59.107:8080/client/api?apikey=3qeSuWadNzUFZ_i6c6zbwafjM3Eo0TWpkHw3En9jNsg5Ditk2N18DnbbL2quBYQ7FsdXQ8rwxbyFlE8vyUTwEg&command=listTemplates&templatefilter=all&signature=l5tubfyABT67d1jY702dvtZODbc%3D Result: ``` <listtemplatesresponse cloud-stack-version="4.8.0"> <count>3</count> <template> <id>38451a02-a687-11e6-a8c8-06f654000053</id> <name>CentOS 5.6(64-bit) no GUI (XenServer)</name> <displaytext>CentOS 5.6(64-bit) no GUI (XenServer)</displaytext> <ispublic>true</ispublic> .... </template> <template> <id>51026d32-60ee-4e25-8ffd-3fa3c57fc14c</id> <name>Debian</name> <displaytext>Debian</displaytext> <ispublic>false</ispublic> <created>2016-11-10T17:18:00-0500</created> <isready>true</isready> <passwordenabled>false</passwordenabled> <format>VHD</format> <isfeatured>false</isfeatured> <crossZones>false</crossZones> <ostypeid>38c1fc84-a687-11e6-a8c8-06f654000053</ostypeid> <ostypename>Debian GNU/Linux 7(64-bit)</ostypename> **<account>sudadmin</account>** <zoneid>25fa5b74-d4c2-4bad-8e3a-ceffcd10985e</zoneid> <zonename>z1</zonename> <size>2621440000</size> <templatetype>USER</templatetype> <hypervisor>XenServer</hypervisor> <domain>SUDDOMAIN</domain> <domainid>a350c00d-4048-4876-ae09-74ad4b7bb28c</domainid> <isextractable>false</isextractable> <checksum>e87a6d7291b999c92baa9623c9c3c207</checksum> <details>{hypervisortoolsversion=xenserver61}</details> <sshkeyenabled>false</sshkeyenabled> <isdynamicallyscalable>false</isdynamicallyscalable> </template> <template> <id>5f6af7bb-d965-4b9b-ab45-6d455b0d6bbe</id> <name>SystemVM Template (XenServer)</name> <displaytext>SystemVM Template (XenServer)</displaytext> <ispublic>false</ispublic> ..... </template> </listtemplatesresponse> ``` **After Fix:** http://10.147.59.107:8080/client/api?apikey=3qeSuWadNzUFZ_i6c6zbwafjM3Eo0TWpkHw3En9jNsg5Ditk2N18DnbbL2quBYQ7FsdXQ8rwxbyFlE8vyUTwEg&command=listTemplates&templatefilter=all&signature=l5tubfyABT67d1jY702dvtZODbc%3D ``` <listtemplatesresponse cloud-stack-version="4.8.0"> <count>1</count> <template> <id>38451a02-a687-11e6-a8c8-06f654000053</id> <name>CentOS 5.6(64-bit) no GUI (XenServer)</name> <displaytext>CentOS 5.6(64-bit) no GUI (XenServer)</displaytext> <ispublic>true</ispublic> <created>2016-11-10T09:32:44-0500</created> <isready>true</isready> <passwordenabled>false</passwordenabled> <format>VHD</format> <isfeatured>true</isfeatured> <crossZones>true</crossZones> <ostypeid>38a2bfd6-a687-11e6-a8c8-06f654000053</ostypeid> <ostypename>CentOS 5.6 (64-bit)</ostypename> <account>system</account> <zoneid>25fa5b74-d4c2-4bad-8e3a-ceffcd10985e</zoneid> <zonename>z1</zonename> <size>21474836480</size> <templatetype>BUILTIN</templatetype> <hypervisor>XenServer</hypervisor> <domain>ROOT</domain> <domainid>383e0ea6-a687-11e6-a8c8-06f654000053</domainid> <isextractable>true</isextractable> <checksum>905cec879afd9c9d22ecc8036131a180</checksum> <sshkeyenabled>false</sshkeyenabled> <isdynamicallyscalable>true</isdynamicallyscalable> </template> </listtemplatesresponse> ``` Bug has been fixed considering below points 1. templatefilter=all or isofilter=all is applicable only to admin and domain admin. 2. With templatefilter=all or isofilter=all below are the visiblity of templates in system. - admin should be able to see all templates/iso in system. - domain admin should be able to see all public template and templates under its domain tree (including sub domain). - domain admin in a project context should be able to see all public templates and templates registered as project account and templates which are shared(using updateTemplatePermission api) with project account. Also Modified "test/integration/component/test_escalation_listTemplateDomainAdmin.py" This marvin test was written for this scenario but for the second account "templatefilter=all" is not used. * pr/1763: CLOUDSTACK-9594: reverted changes introduced in CLOUDSTACK-9376 CLOUDSTACK-9594: API "list templates templatefilter=all" reveals all templates of all domains Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
2 parents 20aea27 + 7059f9e commit 8769597

3 files changed

Lines changed: 17 additions & 5 deletions

File tree

server/src/com/cloud/api/query/QueryManagerImpl.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3054,9 +3054,9 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(ListTempl
30543054

30553055
boolean listAll = false;
30563056
if (templateFilter != null && templateFilter == TemplateFilter.all) {
3057-
if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
3057+
if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
30583058
throw new InvalidParameterValueException("Filter " + TemplateFilter.all
3059-
+ " can be specified by root admin only");
3059+
+ " can be specified by admin only");
30603060
}
30613061
listAll = true;
30623062
}
@@ -3233,6 +3233,19 @@ private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long temp
32333233
scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
32343234
}
32353235
sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc);
3236+
}else if (templateFilter == TemplateFilter.all && caller.getType() != Account.ACCOUNT_TYPE_ADMIN ){
3237+
SearchCriteria<TemplateJoinVO> scc = _templateJoinDao.createSearchCriteria();
3238+
scc.addOr("publicTemplate", SearchCriteria.Op.EQ, true);
3239+
3240+
if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) {
3241+
scc.addOr("domainPath", SearchCriteria.Op.LIKE, _domainDao.findById(caller.getDomainId()).getPath() + "%");
3242+
} else {
3243+
if (!permittedAccounts.isEmpty()) {
3244+
scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
3245+
scc.addOr("sharedAccountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
3246+
}
3247+
}
3248+
sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc);
32363249
}
32373250

32383251
// add tags criteria

test/integration/component/test_escalation_listTemplateDomainAdmin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def test_listtemplate(self):
126126
hypervisor=self.hypervisor,
127127
account=self.account2.name,
128128
domainid=self.account2.domainid,
129-
templatefilter=self.testdata["templatefilter"]
129+
templatefilter="all"
130130

131131
)
132132

test/integration/component/test_templates.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,5 @@ def test_02_list_templates_with_templatefilter_all_domain_admin(self):
675675
DomainName=self.newdomain_account.domain)
676676
try:
677677
list_template_response = Template.list(self.domain_user_api_client, templatefilter='all')
678-
self.fail("Domain admin is able to use templatefilter='all' in listTemplates API call")
679678
except Exception as e:
680-
self.debug("ListTemplates API with templatefilter='all' is not permitted for domain admin user")
679+
self.fail("Domain admin should be able to use templatefilter='all' in listTemplates API call")

0 commit comments

Comments
 (0)