Restrict uploads by real content: per-group file type rules in Nextcloud

A practical walkthrough of Allowed file types for Nextcloud: nine content kinds, per-group and public-link rules, presets, storage-level checks across web, clients and WebDAV, and clear refusals.

If you run a Nextcloud for a household, a club or a small team, you have probably had this conversation: someone drops a file into a shared folder and you only notice later that it was not what it claimed to be. Nextcloud's own extension-based blocking helps a little, but extensions are just a label on the file. Rename a program to photo.jpg and the label lies. The only reliable way to restrict file types in Nextcloud is to look at what the file actually contains.

That is what Allowed file types does. It is a Nextcloud plugin that lets you decide, per group, which kinds of files may be uploaded, judged by the bytes of the file (its magic numbers) and by its name together. Both have to be allowed: a program renamed to photo.jpg is still a program, and a picture named setup.exe is still refused. This tutorial walks through the setup, the nine kinds, per-group and public-link rules, and how to test before you roll anything out.

Prerequisites

  • Nextcloud 30 to 34 with PHP 8.1 or newer.
  • A MediaLab Works account with an active subscription, a lifetime license within its update window, or the free 30-day trial.
  • Shell access to the server (for the installation commands and the occ test command).
  • Nothing else: the app needs no external tools.

Step 1: Install and enable the app

Sign in to your MediaLab Works account, open Licenses and download the archive filetypes-x.y.z.tar.gz. Then extract it into your apps folder so you end up with apps/filetypes/, owned by the web-server user:

cd /var/www/nextcloud/apps
sudo tar -xzf ~/filetypes-x.y.z.tar.gz
sudo chown -R www-data:www-data filetypes

Enable it from the command line or from the Apps page:

sudo -u www-data php occ app:enable filetypes

Step 2: Activate the license

Open Administration settings → Allowed file types → License, paste your license key and save. The app contacts the license server, binds the key to this instance and shows the license as Active. The license is checked once a day; without internet the app keeps working for 7 days after the last successful check, then stops until it can check again. If the license lapses, nothing is deleted: uploads simply stop being checked and your rules apply again once the license is valid.

Step 3: Learn the nine kinds

Before you tick boxes, it helps to know how files are sorted. The app groups everything into nine kinds:

  • Images
  • Videos
  • Audio
  • Documents — plain text, rich text, office files, PDF, e-books, e-mail and similar
  • Archives
  • Code and web pages — HTML, JavaScript, scripts, SVG and similar
  • Programs and installers — Windows and Linux executables, APK, deb/rpm/AppImage, JAR and similar
  • Fonts
  • Anything else

Two of these deserve attention. SVG files count as Code and web pages, not images, because that is what they are. And a script saved as .txt is still a script, so it will not pass as a document. Keep both in mind when you design your rules.

Step 4: Set rules per group

Open Administration settings → Allowed file types. The page shows one row per group, one checkbox per kind, and a No restriction option per row. Tick what members of that group may upload.

A few points that are easy to miss:

  • Rules combine permissively. A person in several groups may upload whatever any of their groups may. If a restricted user can still upload everything, look for a second group with No restriction.
  • Administrators are not special. The admin group needs its own row (or No restriction) if you do not want admins limited.
  • Everyone else is a separate row for people who are in no group with a rule. It is unrestricted by default, which keeps the previous behavior for them.
  • Public links is its own row, covering uploads by people without an account — file drop and upload-enabled shares.

Step 5: Start from a preset

You do not have to tick every box by hand. Three presets give you a sensible starting point:

  • media only
  • media + documents
  • everything but code and programs

Pick one, adjust the rows for your groups, then Save. The rules apply from the next upload.

Step 6: Know where the check runs

The check runs at the storage level, so it is not tied to one interface. It covers the web interface, the desktop and mobile clients, WebDAV, public link uploads and files saved by other apps (Text, Office and similar). That matters in practice: a rule that only guarded the web upload form would be trivial to bypass with a sync client or a curl request over WebDAV. Here, the same rule follows the file wherever it arrives.

One deliberate exception: files written by occ commands and background jobs are not checked, because they are not somebody uploading.

Step 7: See what users see

When a file is refused, it is removed at once and the person is told why, in the client or on the web page. The message names the file, the kind it was detected as, and what is allowed, for example:

"setup.exe" is not accepted: it is Programs and installers, and you may only upload Images, Videos, Documents.

That kind of message saves you a support ticket. The user knows immediately whether they picked the wrong file or whether the rule is simply stricter than they assumed.

Step 8: Test before you roll out

There are two ways to check a file without touching your live rules.

Try it on the settings page: pick a file from your computer and see what it counts as (by its bytes and by its name) and which groups may upload it. Only its first 64 KB are sent, and nothing is stored.

From a terminal, for a file already on the server:

sudo -u www-data php occ filetypes:test <file> [name]

This tells you what the local file counts as and who may upload it. Run it against a few of the files your users actually handle — an office export, a scanned PDF, an SVG logo — before you tighten a group's rules.

Tips and troubleshooting

A file is refused although its extension is allowed. Its bytes say something else. A script saved as .txt, or an SVG, will be classified as Code and web pages. Check it with Try it or occ filetypes:test.

Files that were already in the cloud are still there. That is by design. The rules apply to new uploads, moves and copies; existing files are not touched. If you need a clean baseline, review old content separately.

A user in a restricted group can still upload anything. They are also in another group with No restriction, and the most permissive group wins. Audit group memberships first, then the rules.

Public links are still open. Remember that Public links has its own row. Tightening group rules does nothing for anonymous file drop until you edit that row too.

Privacy. Only the first 64 KB of a file are read to tell what it is, and the app stores nothing about the file.

Conclusion

Extension-based blocking is a sign on the door; content-based rules are the lock. Allowed file types gives you nine understandable kinds, per-group rules, a separate row for everyone else and one for public links, and enforcement at the storage level across web, clients and WebDAV — with refusal messages that explain themselves. Start from a preset, test a handful of real files with Try it or occ filetypes:test, and tighten one group at a time.

For the full walkthrough, see the user guide; for release notes, the changelog. More self-hosting material lives in our knowledge base, and if something behaves unexpectedly, check the FAQ or contact us.

This post was written with AI assistance from our product documentation or the sources listed and checked automatically before publication.

Read next

Running Emby, Jellyfin or Nextcloud?

Our plugins and apps add Live TV, subtitles, sign-up and security to your own server, with a free trial.