Skip to header Skip to main navigation Skip to main content Skip to footer
Drupal Maintenance and Developments in Austin TX
Drupal Care

Main navigation

  • Home
  • Why Drupal Care?
  • What’s Included
  • About
  • Our Approach
  • Prices & Plans
  • Portfolio (opens in new tab)
  • Blog
  • Videos
  • Contact
  • Site Evaluation

Drupal Security Services: Permissions, Custom Code Audits, and Update Discipline

Alaa Haddad, professional Drupal developer based in Austin, TX   Drupal Care
  1:53 PM CDT, Tue September 15, 2026
Share

Drupal has a better security record than its reputation suggests. It has a dedicated security team, a disclosure process that has worked for two decades, and a core codebase with defences built into the layers developers use every day.

What that record does not protect against is the ordinary way Drupal sites are actually compromised: an update nobody applied, a permission granted to the wrong role, or a hundred lines of custom code that skipped a check the rest of the system would have made.

This page covers the security work that belongs to a Drupal site owner, what genuinely matters against what merely sounds serious, and how to tell whether your site needs a review.

The Update Problem Is the Security Problem

The large majority of compromised Drupal sites were running a version with a known, published, patched vulnerability. Not an unknown flaw — a fixed one that had not been applied.

This is uncomfortable because it is unglamorous. There is no clever defence to buy. The single highest-value security measure available to a Drupal site is applying security releases promptly, and it is the one most often deferred because it competes with visible work.

The window matters. Once an advisory is published, the fix is public, and so is the description of what it fixed. Automated scanning for newly announced Drupal vulnerabilities begins within hours. "We'll do it next sprint" is a decision to be exposed for the length of that sprint.

Contributed Modules and the Coverage Question

Not every contributed module is covered by the Drupal Security Team. Coverage applies to stable releases of projects that have opted in and met the requirements; development releases and many smaller projects are not covered, and their project pages say so.

This does not make an uncovered module unsafe. It means that if a vulnerability is found, there is no team obligated to coordinate a fix, and no advisory will be issued. You would need to notice yourself.

Worth knowing, for each module you depend on: is it security-covered, is it actively maintained, and how many sites use it. A module with three sites and no commits in four years is a different risk from one with fifty thousand installs and a responsive maintainer — even when both work equally well today.

Permissions Are Where Sites Leak

The most common real-world exposure is not an exploit. It is a permission granted to a role that should not have it, usually while solving an unrelated problem in a hurry.

A few carry far more weight than they appear to. Administer permissions lets a role grant itself anything, which makes it equivalent to full administrative access. Administer users allows changing other accounts, including elevating them. Use the PHP filter, where such a thing is installed, is arbitrary code execution by design. Bypass content access control does exactly what it says. Administer views and similar can be used to build a page exposing data the role could not otherwise reach.

Auditing this is neither difficult nor common: read the permissions page role by role and ask, for each grant, why it is there. On most sites this exercise finds at least one grant nobody can justify.

Custom Code Is Where the Vulnerabilities Live

Core and popular contributed modules have been read by a great many people. The module written for one site three years ago has been read by its author.

Drupal's APIs are safe by default, and vulnerabilities in custom code almost always come from stepping outside them. An entity query without an access check returns content the user should not see. A database query built by string concatenation is an injection risk that the placeholder API would have prevented. Output marked as safe to silence an escaping warning is a cross-site scripting vector.

// Injection risk: the value is concatenated into the query.
$result = $connection->query("SELECT nid FROM node_field_data WHERE title = '$title'");

// Safe: the value is passed as a parameter, never as SQL.
$result = $connection->query(
  'SELECT nid FROM node_field_data WHERE title = :title',
  [':title' => $title]
);

The pattern to watch for in a review is any place the code decided to do something itself that Drupal offers an API for.

Trusting the Wrong Layer

A recurring class of bug: an access decision made where it cannot be enforced.

Hiding a field in the display settings does not protect it — the data is still on the entity, and still reachable through a view, through JSON:API if enabled, or through a different display mode. A template that only prints something for administrators has already loaded the value, and other paths to that value remain open.

Access control belongs at the data layer: entity access, field access, and route requirements. The presentation layer should reflect those decisions, never make them.

File Uploads and Private Files

Anywhere users can upload files deserves attention. Restrict extensions to what is genuinely needed, and be specific — an over-broad list is how executable content ends up in a public directory.

Drupal distinguishes public files, served directly by the web server, from private files, served through Drupal so access can be checked. If a document should only be visible to certain users, it must be in the private filesystem. A public file with an unguessable URL is not protected; it is unlisted, which is not the same thing.

The web server matters here too: the files directory should not execute PHP. Drupal ships protections for this, but they can be lost when a site is moved between hosts or when a server configuration is rewritten.

Authentication and Account Hygiene

Accounts accumulate. The developer who left, the agency that built the site, the contractor hired for one project — all frequently still have working logins years later.

Worth doing periodically: list every account with elevated permissions and confirm each still needs it. Block rather than delete when someone leaves, so their content authorship stays intact. Enforce reasonable password requirements, add two-factor authentication for administrative accounts, and ensure the account named admin is not sharing a password with anything else.

Flood control — Drupal's built-in limiting of repeated failed logins — should be left enabled. It is occasionally disabled during development to stop it interfering with testing, and occasionally never re-enabled.

If you are not sure whether your own permissions and custom code would pass these checks, a security review answers it with findings ranked by risk. Request a quote and say whether the site handles personal data or payments.

The Server Side

Some of what determines a Drupal site's security is not Drupal at all: the PHP version and whether it still receives security patches, TLS configuration, database access limited to the application, and whether settings.php and the private files directory are readable from the web.

One specific item worth checking, because it is a frequent finding: whether /core/install.php, /update.php and similar administrative endpoints are reachable and what they do when they are. Another: whether the site is served over HTTPS with HTTP redirected, and whether that redirect covers every hostname the site answers on.

Hardening the Admin Surface

Reducing what is reachable reduces what can be attacked. Uninstall modules that are not used rather than leaving them disabled. Remove development tools — database query loggers, devel utilities, one-off debugging modules — from production entirely rather than switching them off.

Turn off verbose error display in production. Detailed errors are valuable in development and are a reconnaissance gift on a live site, because they disclose paths, versions and query structure.

If administrative access is only ever needed from known locations, restricting it at the web server layer is a meaningful reduction in exposure for very little effort.

Logging, and Knowing Something Happened

Detection is the part most sites have not thought about. Drupal logs failed logins, permission denials and PHP errors, and on most sites nobody reads them until something has already gone wrong.

The valuable signals are changes in shape rather than individual events: a rise in failed logins for one account, permission-denied entries for paths that should never be requested, or errors appearing at a time when nobody was deploying.

Logs also need to survive. A log stored only in the site's database is available to anyone who reaches the database, which in a compromise is precisely the wrong property.

If You Think You Have Been Compromised

The instinct is to clean up quickly. That instinct destroys the evidence needed to establish what happened and whether it is over.

A better order: take a snapshot of the current state before changing anything; work out how they got in, because restoring a backup without closing the entry point simply resets the clock; then restore from a backup predating the compromise, apply the missing updates, and rotate every credential the site holds — database, API keys, and administrative accounts.

Credential rotation is the step most often skipped, and it is the reason sites get re-compromised a fortnight later. Anything the attacker could read must be assumed read.

Common Security Mistakes

  • Security updates deferred because the site "seems fine" — by far the largest real risk.
  • Permissions granted to fix something urgent and never reviewed afterwards.
  • Entity queries without access checks in custom code.
  • Private documents in the public filesystem, protected only by an unguessable URL.
  • Old accounts left active long after the people are gone.
  • Verbose errors enabled in production, disclosing internals to anyone who triggers one.
  • Development modules left installed on a live site.

When a Security Review Is Worth It

A review earns its cost when the site handles personal data or payments; when it carries custom code written by people no longer available; when it has been running for years without an audit; when it is subject to a compliance obligation; or after any incident, to establish what was reachable.

It is also worth doing before a launch that will raise the site's profile. Attention brings scanning, and the cheapest time to fix a permission model is before anyone is depending on it.

A useful review produces a written list of findings ordered by real risk, each with a specific fix — not a scanner report with two hundred low-severity notes and no judgement applied.

Third-Party Code and the Supply Chain

A modern Drupal site is not only Drupal. Composer pulls in PHP libraries, the theme may load fonts or scripts from external services, and analytics or marketing tags often run on every page. Each is code you did not write, executing in your context.

For PHP dependencies, the practical measures are keeping composer.lock in version control so builds are reproducible, running a dependency audit as part of normal work, and treating an unmaintained library the same way you would treat an unmaintained module.

composer audit

Front-end third parties deserve more scepticism than they usually get. A script loaded from an external domain can read the page, including anything a user has typed into a form. That is fine for a service you have assessed and chosen; it is a genuine risk for a tag added years ago by someone who has left, still loading on every page, from a company that may since have been acquired.

Worth doing once a year: list every external domain the site loads code from, and confirm each is still wanted. On most sites this list is longer than anyone expects, and at least one entry is a surprise.

The same logic applies to anything with write access to the site — deployment keys, integrations, and API tokens held by services that no longer need them. Access granted for a project that finished two years ago is still access. The broader engineering practices around this are covered on the Drupal developer page.

Next Steps

Three checks cost almost nothing and find most of what matters: confirm whether any security updates are outstanding, read the permissions page role by role and justify each grant, and list every account with administrative access and confirm each still needs it.

If you would rather have it done properly, a Drupal security review covers permissions and roles, custom code, file handling, account hygiene, exposed endpoints and update status, and delivers findings ranked by actual risk with a remediation plan. Ongoing maintenance then keeps the update window short, which is the part that matters most.

I have worked in web development since 2005 and I am the author of Drupal modules and themes — public code you can read on my drupal.org profile.

Request a quote describing your site, whether it handles personal data or payments, and when it was last reviewed — or get in touch if you would rather talk first. If you believe you are compromised right now, say so in the first line so it can be treated accordingly.

Drupal Services
Drupal Security

Footer menu

  • About
  • Privacy Policy
  • Terms & Conditions
  • Flash Web Center, LLC (opens in new tab)
  • Web Designer In Austin (opens in new tab)
  • Log in
  • Contact
  • Sitemap

Copyright © 2026 Flash Web Center, LLC | All rights reserved

Developed & Designed by Alaa Haddad