Let's talk
security

Any monitor could export every employee in the company

A manager who should see 33 people could reach 726 and export 15,452 rows. An empty team also meant no limit at all. How it was found and closed.

·

A laptop on an office desk by a window showing the attendance screen of the Sazinga Field portal that a manager exports from.

You give a manager a view of his own team’s field activity. He can pick a colleague from a list, see counts, and download an Excel file. You assume that everything he sees and downloads is limited to the people under him.

For this report at Aries Agro, a crop-nutrition manufacturer, it was not. The employee list, both count screens and the Excel download all took a person’s ID from the request and never checked whether that person was in the manager’s team. Any of the 26 live monitors could read and export any employee in the company.

The measurement was blunt. One monitor’s correct view was 33 employees and 589 rows in the download. Before the fix, the same person could reach 726 employees and 15,452 rows.

What was actually going on

The owner’s request was reasonable: anyone should be able to monitor anyone, and see that person’s whole team. Two things stood in the way. A picker only let an administrator choose a State Head as the person to watch, although nothing underneath required that. And the report did not apply the monitor’s limit anywhere.

There were two traps in the fix, and they are the useful part.

The first is a filter written in the wrong place. In the count queries the team condition was added to the part of a database join that decides how rows match, not the part that removes them. A condition there removes nothing. The code would have looked right and filtered no one.

The second is worse. When the team lookup found nobody, it returned an empty list, and every query builder in the system reads an empty list as no limit at all. A monitor with nobody under him would have seen everyone. Nothing in a normal test would have caught it, because a normal test uses a monitor who has a team.

What we changed

The team limit now applies to every read and to the Excel download, written so it works whatever the query has already started. An empty team now returns an empty answer, deliberately, not everything. The employee picker became a separate search limited to the monitor’s own team.

Before shipping we checked it against production data: the monitor with 33 employees saw 33 and exported 589 rows, nothing outside their team appeared, and asking for someone outside it was refused. A monitor anchored to a Region Head saw all 121 people under him. It went out as a hotfix, and we checked the files actually being served, not the exit code of the deploy.

What it did not fix

We do not know whether any monitor had already downloaded more than their own team. This was a missing check, and the record of earlier downloads was not part of the work.

The pattern, for anyone giving managers reports

Ask whether the limit applies to the list, the counts and the download, or only to the list. Then test a manager who has nobody under him. The result should be an empty screen, not the whole company.

Where this ends up

Sazinga Field limits a leader’s view to their own team, across the screen, the counts and the export, because those are three separate places to get it wrong.

This came out of building Sazinga Field

Orders, stock, dispatch and the people on the road, in one place. The problem above is one we met while building it, and what we did about it is in the product.

If you run something like this, there is one thing you can do without a call: send one day's order sheet.