Skip to main content
Back to Insights

Knowing what is in your website: dependency scanning and vulnerability monitoring

Valentin Zsigmond
Valentin ZsigmondOct 28, 20264 min read

A modern website is assembled from a great deal of software that nobody on your team wrote. Drupal core, dozens of contributed modules, the PHP libraries they depend on, the JavaScript packages behind the frontend, the web server, the database, the operating system inside the container. Each is maintained by someone else, on their own schedule, and each occasionally publishes a fix for a security problem. Knowing what is in your site, and knowing within hours when any part of it needs attention, is one of the least visible and most important jobs in running a website. This article is about how we do it.

Start with a complete list

You cannot watch what you have not listed. For every site we run, the exact versions of everything are recorded in lock files committed with the code: the Drupal modules and PHP libraries in one, the frontend packages in another. The container images that run the site are built from a manifest that pins the versions of PHP, the web server, the database client and every system package. Nothing is installed by hand on a server, ever, because a hand-installed package is one the list does not know about.

This discipline is also what makes a build reproducible: the same commit produces the same site, today or in a year, which matters both for deployments and for answering the question "what exactly were we running on that date?"

Compare the list against known problems, continuously

Public databases record every known vulnerability in every widely used package, with the affected versions and the version that fixes it. Drupal's security team publishes its own advisories for core and contributed modules. We compare our lists against these sources automatically, every day, at three levels.

  • Application dependencies. The PHP and JavaScript lock files are checked against the vulnerability databases and Drupal's advisory feed. A match produces a finding with the package, the installed version, the fixed version and the severity.
  • Container images. Every image we build is scanned for known vulnerabilities in its operating system packages and bundled binaries, before it is used and again on a schedule afterward, because new vulnerabilities are disclosed in old packages all the time.
  • Our own code. Static analysis runs on every change to our custom modules and components, looking for the categories of mistake that vulnerability databases cannot know about because the code is ours.

A finding at any level becomes a ticket with a severity and a target date, visible in the client portal. Highly critical findings are handled the same day.

The scan has to be trustworthy

A scanner that fails silently is worse than no scanner, because it produces confidence without information. We treat an unreadable or failed scan as a finding in its own right: if the dependency check did not run or could not read the lock file, that is raised as an incident until it is fixed. Every finding is also tracked to closure by re-scanning, not by someone marking it done. A vulnerability is resolved when two consecutive clean scans say so.

Fixing at the right layer

Most findings are resolved by updating the affected package, which for application dependencies is the same routine as any security release: update, test on staging, deploy. For container images, the fix is to rebuild the image with the patched package and roll it out, which happens across every site on the platform in one coordinated update rather than site by site. Occasionally a vulnerability has no fix yet, or the fix is in a version that is not compatible. Those cases get a documented decision: mitigate at another layer, such as a firewall rule, and record the reasoning and the date to revisit it. Nothing is filtered out of the report without a written reason.

Keeping the list small

The easiest vulnerability to manage is the one in a package you do not have. Part of dependency hygiene is regular pruning: modules that are installed but no longer used, libraries pulled in for a feature that was removed, frontend packages that duplicate something already present. Every module is evaluated before it is added, and the list is reviewed at each major upgrade. A smaller surface is a smaller job, every week, forever.

Why this is a platform job

None of the steps above are difficult. What makes them effective is that they run for every site, every day, without depending on anyone remembering. On our managed platform the scanning, the image rebuilds and the ticketing are properties of the infrastructure, so a site added on Monday is covered on Tuesday. It is one of the ways the platform delivers a layer of defense that an individual site, maintained by hand, rarely sustains.

It also produces something clients increasingly need: an answer. When a customer asks whether you were affected by a vulnerability that made the news, the answer is a lookup, not an investigation. Which versions we run, whether they were affected, when the fix was applied. That is the level of certainty we want every client to be able to give, and it comes from the boring work of keeping the list and checking it every day.

If you would like to know what is actually in your site and whether any of it needs attention, we can run the scan as part of a review. The list is usually longer than people expect, and the number of findings usually shorter.

Share this article
Valentin Zsigmond
Written by
Valentin Zsigmond
Founder & Lead Engineer

Full-stack Drupal architect with almost two decades of experience leading large teams in enterprise environments. Founded Tilizy Digital to bring senior-level expertise directly to the organizations that need it. Mentor to dozens of Drupal developers and creator of SDX — a Drupal extension for building modern frontends with React and Vue.

Enjoyed this article?

If this resonated, imagine what we could do working together on your Drupal site.