Is rest/users path protected by role scope

We have a stand alone n8n instance, now we create multiple users one is the owner with global role (1, global and owner) all the rest are members (global role 2 (member, global).

Now. i executed an api request to rest/users to fetch all users with n8n-auth cookie of member user. than i got all users in the instance.

does it make sense? not only the owner should have the ability to fetch all users?

Information on your n8n setup

  • **n8n version:1.25.0
  • **Database (default: SQLite):postgres
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • **Running n8n via (Docker, npm, n8n cloud, desktop app):Docker
  • Operating system:

Hi
Anyone can assist with that? i am not sure what i am doing wrong. since this is a serious security issue i encountered, i would like to tackle it ASAP.

hello @mtubul

I’m not able to fetch all users from the user account

Please, update to the latest version and check if the issue persists

And check if the API key, that you are using in the user account, hasn’t been created in the root account

2 Likes

I am not speaking about the api/v1/user path but on rest/users request which automaticlly trigger after a successful login
see the image attached, when i looked on the response the data contain users which not related to the member scope. does it make sense?
in addtion i found that member users has the following permissions

export const memberPermissions: Scope[] = [
	'eventBusEvent:list',
	'eventBusEvent:read',
	'eventBusDestination:list',
	'eventBusDestination:test',
	'tag:create',
	'tag:read',
	'tag:update',
	'tag:list',
	'user:list',
	'variable:list',
	'variable:read',
];

not this is the controller which wrap with the scop user:list scope permissions.

@Get('/', { middlewares: listQueryMiddleware })
	@RequireGlobalScope('user:list')
	async listUsers(req: ListQuery.Request) {
		const { listQueryOptions } = req;

		const globalOwner = await this.roleService.findGlobalOwnerRole();

		const findManyOptions = await this.userRepository.toFindManyOptions(
			listQueryOptions,
			globalOwner.id,
		);

		const users = await this.userRepository.find(findManyOptions);

		const publicUsers: Array<Partial<PublicUser>> = await Promise.all(
			users.map(
				async (u) =>
					await this.userService.toPublic(u, { withInviteUrl: true, inviterId: req.user.id }),
			),
		);

		return listQueryOptions
			? this.removeSupplementaryFields(publicUsers, listQueryOptions)
			: publicUsers;
	}```

so i am not sure where the validation is occur regarding which users the member can fetch?

![image|690x214](upload://A38WVWLq1Pt2zFSnU3PbULczLFW.png)

Ah, I see. Yes, it’s possible to see other users in that way. So it might be a bug

should i open a bug for that?

I will give this a test on Monday morning.

1 Like

thanks, waiting for your insights.

Have given it a test and reproduced internally, I suspect this endpoint is used as part of the sharing feature to load the users so you can select who are you sharing with so I don’t believe this to be a “serious security issue” although we do return some metadata that isn’t needed.

I have flagged this internally to clean up the data so we only return the names and emails which are used in the list.

there is a way to exclude this request or change the scope of the request?

Hey @mtubul,

As it is linked to a core feature of n8n there isn’t a way to turn it off as it is needed. Out of interest what would you change it to, Keeping in mind that this is used for the below.

The extra data though will be removed soon as we only need to display the name and email for the search.

but how it working in multi-tenant instance? or there is no any scenario? e.g n8n-cloud is a multi-tenant instance or each customer has its own instance? how you make sure the user is not getting a user which is not related to the same owner?

I bet on each instance for each customer (so it doesn’t have an MSP inline model). Otherwise, it will be easy to ruin the whole instance with some simple stuff like infinite loops

n8n doesn’t have a multi tenant option, on Cloud every instance is standalone so your instance wouldn’t be able to access any data from my instance.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.