Skip to content
datahacks.dev
CSV

Sending a CSV by Email Safely and the Better Options

Email is a poor way to move a CSV of real data. Ranked alternatives, from not sending it to expiring links, plus how to encrypt a file you must attach.

6 min read
Summarize in AI
Flat illustration of a spreadsheet grid with a selected cell and a formula bar.

Email is where data goes to get lost. The attachment you send is copied into your sent folder, into the recipient's inbox, into their phone, into every backup of both mail systems and into the forward they send to a colleague without thinking. Nothing about that copy can be recalled or expired, and none of those places is encrypted in a way you control. For a CSV of customers, salaries, orders or logins, that is a lot of exposure for the convenience of one click. This article ranks the alternatives and says how to do the least bad version when email is the only channel. It continues the thread on files that leave your control from CSV security risks that catch teams out, and the legal angle is in handling CSV files full of customer data under GDPR.

Ask who needs the file

Start with the recipient's goal, because it often does not require a file. An analyst who wants "the numbers" may want a dashboard or a query. A colleague who asks for "the customer list" may need five rows of it. An auditor may need read access to a system and not a copy. Each of those removes the file from the picture, and with it the problem. The cheapest secure transfer is the one that does not happen.

When a file really is required, rank the channels like this, best first:

OptionWhyCost
Give access to the sourceNo copy leaves; access can be revokedAccounts and permissions
Shared location with named accountsOne copy, audit trail, revocableA drive or bucket you control
Expiring download linkSingle copy that disappearsA presign step or a transfer tool
SFTP or managed file transferAuthenticated, logged, encrypted in transitA server and keys
Encrypted file by emailData unreadable without a second secretRecipient must handle encryption
Plain attachmentConvenience onlyEverything above, in reverse

If your files live in object storage, a presigned URL gives time-limited access to one object without creating accounts. With the AWS CLI:

Shell
aws s3 presign s3://example-exports/plan-report.csv --expires-in 3600

The command prints a URL that works for one hour. After that the same URL returns an error. The recipient needs nothing but a browser, and the file never enters their mailbox as an attachment. Two cautions: anyone who gets the link can download during the window, so send it by a channel you trust and keep the window short, and the file stays in the bucket afterwards, so delete it or set a lifecycle rule. Other providers have the same feature under a different name (signed URLs, shared access signatures). The details of the AWS command are in the CLI reference, and the other end of the same bucket is covered in loading a CSV from S3 into a database.

For a file that must stay on your own infrastructure, SFTP with key-based accounts is the dependable old answer, and a managed file transfer service adds logging and expiry for teams that do this daily.

Reduce the file first

Whatever the channel, send less. Remove every column the recipient does not need, remove rows outside the scope they asked about and replace identifiers with tokens where they can work with those (stripping personal data from a CSV before sharing it, hashing or masking columns in a CSV safely). A 50 MB file of 40 columns shrinks to a 2 MB file of 6, which also fits through size limits that cause people to split files and send them in pieces by whatever route works.

Do one more check for files that will be opened in a spreadsheet: any user-typed text starting with =, +, - or @ should be escaped (escaping formula characters in a CSV export), because the recipient will double-click.

Encrypt the file if it must go by email

When there is no other channel, encrypt the file and send the secret separately. GnuPG's symmetric mode needs no keys and no setup beyond the program:

Shell
gpg --symmetric --cipher-algo AES256 orders.csv

It prompts for a passphrase twice and writes orders.csv.gpg. In the test run, a 28-byte CSV became a 108-byte encrypted file, and decrypting with the passphrase gave back the original two lines exactly:

Text
id,email
1,[email protected]

The recipient decrypts with gpg --decrypt orders.csv.gpg > orders.csv and the passphrase. Send the encrypted file by email, and the passphrase through a different channel: a phone call, a message in a different system, an in-person word. A passphrase in the same email as the file protects nothing, since whoever has one has both. Choose a long random passphrase, not a word.

I typed the passphrase at the prompt in the example. Scripts sometimes pass it as an argument (--passphrase), and on a shared machine other users can read the arguments of a running process, so use a prompt, a file descriptor (--passphrase-fd) or an agent for anything real. The GnuPG manual describes the options in its documentation.

The friction is real. A recipient who has never used GnuPG will find this painful, and a hard security control that people route around is worse than a softer one they use. Two alternatives lower the friction. An archive with AES encryption (7-Zip's -p with -mhe=on for the file names) opens in common tools with a passphrase. And a password-protected workbook is understood by everyone with Excel, but a CSV opened through a workbook is the damage described in opening CSV files in Excel and Sheets without damage. Avoid the classic zip password, which uses a weak legacy cipher in many tools and is broken by commodity software; check which cipher your archiver uses before relying on it.

After you send it

Sending is not the end of the file's life. Write down what you sent, to whom and when it should be gone (the register in the GDPR article is the place), delete the local copy and the sent-mail copy if your policy allows, and ask the recipient to delete theirs by a date. For a repeating transfer, move it to a managed channel the second time it happens. A file emailed every Monday is a process, and a process deserves a proper pipe.

If you realize you sent the wrong file or the wrong person, say so at once. Most mail systems let an administrator purge a message, which works only in the first hours; for personal data, a mis-sent file may count as a breach with its own reporting duties.

When email is the only channel

Sometimes a customer, a regulator or a vendor will accept nothing else, and the instruction is to email the file. Then the controls are the ones above, applied strictly: the smallest possible file, encrypted, with the passphrase delivered separately, to a named recipient whose address you have confirmed. Ask whether they can accept a portal upload or a link first; it costs one sentence, and many say yes.

Also be honest about what a given file is. A list of public product prices does not need ceremony, and treating every attachment as a secret leads people to ignore the rules. Classify the file: public, internal, confidential, personal. The first two can go by email without a second thought. The last two follow the ranking above. If you are unsure, assume the stricter one. The file format itself carries no protection: RFC 4180 defines plain text, and any protection must come from the channel or from encrypting the file.

Share

Keep reading

Get new articles by email

We send one email when a new article is published. No spam.

Unsubscribe in one click. No spam, ever.