question

Steffan avatar image
Steffan asked

Concerned about Entity security

Hello!

I've been using the Classic Playfab API's for a few years now and they have served me perfectly fine, but now I want to dip my toes into Entities and Groups for a new use case that I cannot solve with the classic api's alone.

In my game I make use of the Friendlist system so people can add each other as friends. I used to do this on a title player account level, but recently I've implemented Characters so that players can have multiple characters per account.

Since the Friendlist system doesn't operate on a Character level, I've taken to using Entity Groups to make my own friendlist system, but after tinkering around with Entities for a bit I have some security concerns.

Below is my cloudscript function for creating a player's first character which also creates the Friend group on that character at the same time:

var CreateCharacter = function (args: any, context: IPlayFabContext): PlayFabServerModels.GrantCharacterToUserResult {
	let characterResult = server.GrantCharacterToUser({
		PlayFabId: currentPlayerId,
		CharacterName: args.username,
		CharacterType: "Character"
	});
	let entityKey = {
		"Id": characterResult.CharacterId,
		"Type": "character"
	};
	let apiResult = entity.CreateGroup({
		Entity: entityKey,
		GroupName: "Friends"
	});
	return characterResult;
}
handlers["CreateCharacter"] = CreateCharacter;

This works fine. The character gets created and it has a Friends group. Now if my understanding is correct, for any future Entity cloudscript calls, I will use "ExecuteEntityCloudScript" from within my C# client code, and I will need to pass the player's CharacterId as the EntityId for that call, like so:

PlayFab.CloudScriptModels.EntityKey entity = new PlayFab.CloudScriptModels.EntityKey();
entity.Id = MyCharacter.CharacterId;
entity.Type = "character";

PlayFabCloudScriptAPI.ExecuteEntityCloudScript(new PlayFab.CloudScriptModels.ExecuteEntityCloudScriptRequest() {
	FunctionName = "InvitePlayerToFriendGroup",
	FunctionParameter = new { OtherPlayerId = "SomePlayerId" },
	Entity = entity
},
result => { },
error => { });

It seems to me that if all you need is a character id and an entity key (which is always "character" in this case,) anyone can access any character entity if they know the right id. Players with malicious intent could easily exploit this to wreak havoc on other people's character data. Is there some kind of authentication step I'm not aware of?

If I am understanding this wrong, please help me implement it in the proper manner!

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
Seth Du avatar image
Seth Du answered

To avoid abusive use, you may add additional verification steps to your Cloud Script function. Please note that by default, Cloud Script has a title-level entity token in the running environment, which is as powerful as Server API, hence it is able to apply any data changes to entities under a title.

The key point is to verify the caller. If a function is executed by ExecuteEntityCloudScript API, the “context” parameter contains additional information, including caller profile, is it triggered by Rule or Tasks. All this information can be used for verification.

Moreover, the Entity Data model supports customized policy. If you have a specific requirement, you may change the access policy of an Entity. Feel free to let me know if you have questions on Policy editing.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.