Dev.to Security 🔐 Cybersecurity 👁 0 📖 1 min read

Your CSV export might include the columns your UI hides

I keep running into the same bug. The app hides salary, cost, or internal notes from some roles. The frontend leaves the column out and the detail API strips the field for those users. Then someone adds "Export to CSV",

I keep running into the same bug. The app hides salary, cost, or internal notes from some roles. The frontend leaves the column out and the detail API strips the field for those users. Then someone adds "Export to CSV", and the export builds rows straight from the ORM model. Every column lands in the file for anyone who can click the button.

The field rules usually live in the serializer for one endpoint. The export is a separate code path written later, often by someone else, and often as a background job that writes a file, so it never goes through that serializer.

What has worked for me:

  • Put the decision "which fields can this user see on this record type" in one function, and have both the API serializer and the export call it. The export asks for the allowed columns before it writes the header row.
  • Run the export as the user who asked for it. If it runs as a job, pass the requesting user's id and check again when the job actually runs, since their role may have changed while it sat in the queue.
  • Reuse the list endpoint's row filter so the export only pulls records the user could already see in the list.
  • Add a test per role that exports a fixture and asserts the header row. It's cheap, and it catches the next column someone adds to the model.

Scheduled reports and "email me this view" links have the same problem. Anything that turns records into a file tends to skip the response layer where the field rules were written.

How do you handle it? Do you have one field-permission function, or does each output format carry its own rules?

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.