Security in Drupal: what can go wrong?

Benji Fisher

March 21, 2024 - MidCamp

Introduction

About me

Yellow Pig 

Usability group, Migration subsystem, Security team

Follow along

QR code for https://slides.benjifisher.info 

Outline

  • Introduction
  • What is the OWASP Top Ten?
  • What is Drupal?
  • A01:2021-Broken Access Control
  • A02:2021-Cryptographic Failures
  • A03:2021-Injection
  • A04:2021-Insecure Design
  • A05:2021-Security Misconfiguration

Outline (continued)

  • A06:2021-Vulnerable and Outdated Components
  • A07:2021-Identification and Authentication Failures
  • A08:2021-Software and Data Integrity Failures
  • A09:2021-Security Logging and Monitoring Failures
  • A10:2021-Server-Side Request Forgery
  • Conclusion

Attribution

These slides borrow from some of Peter Wolanin’s “Cracking Drupal” presentations and from https://owasp.org/. According to the standard footer,

Unless otherwise specified, all content on the site is Creative Commons Attribution-ShareAlike v4.0 and provided without warranty of service or accuracy.

All of my slide decks have a similar license.

What is the OWASP Top Ten?

Open Web Application Security Project® (OWASP)

The Open Web Application Security Project® (OWASP) is a nonprofit foundation that works to improve the security of software.

source: https://owasp.org/

OWASP is not Drupal-specific. Let’s “get off the island”!

OWASP Top Ten

The OWASP Top 10 is a standard awareness document for developers and web application security. It represents a broad consensus about the most critical security risks to web applications.

source: https://owasp.org/www-project-top-ten/

The list is updated every few years. The most recent version is from 2021.

What is Drupal?

Drupal: a content management system

Drupal is a web-based content management system (CMS):

Enter data in my forms. I will save it to the database, then generate web pages.

Hacker:

Sounds great. Let’s get started!

Drupal: exploits of a Mom

Hacker:

Then

$sql = "INSERT INTO Students (name) VALUES('$name')";

will become

$sql = "INSERT INTO Students (name) VALUES('Robert');
        DROP TABLE Students; --')";

xkcd 327 (Exploits of a Mom)

xkcd cartoon suggesting “Robert’); DROP TABLE Students; –” as a name 

source: https://xkcd.com/327/

Drupal: an active, international OSS project

The Drupal community is one of the largest open source communities in the world. We’re more than 1,000,000 passionate developers, designers, trainers, strategists, coordinators, editors, and sponsors working together.

source: https://www.drupal.org/about

Drupal: take security seriously

The security team is an all-volunteer group of individuals who work to improve the security of the Drupal project. Members of the team come from countries across 4 continents … The team was formalized in 2005 with a mailing list and has had 3 team leads in that time period.

source: https://security.drupal.org/team-members

A01:2021-Broken Access Control

Types of vulnerability

  1. Information disclosure
  2. Edit/Delete by unauthorized user
  3. Cross-Site Request Forgery (CSRF)
  4. … and more

Horror stories (custom modules)

One site had custom access control for /user/1/edit. The access function left off a “not” and granted access to anyone except User 1.

Q: How to protect yourself?

Custom modules

How do you avoid horror stories?

  • Code review
  • Automated tests for every custom page/custom access
  • Avoid custom code!

If customers knew the true cost of custom code, they would ask for less of it.

Cross-Site Request Forgery (CSRF)

  • mysite.com: <img src="https://example.com/node/123/delete">
  • admin for example.com visits mysite.com

Questions:

  • Why does this attack not work?
  • What incorrect assumptions expose a similar vulnerability?

How to avoid CSRF

  • Use confirmation forms.
  • Expect users to tweak URLs: .../edit, .../delete, and more.
  • Do not assume form requests come from the form you created.
  • Use CSRF tokens: CSRF access checking
  • Remember: forms are hard! Web CMS is a terrible idea.

CSRF in Drupal

SA-CORE-2021-006:

  • Project: Drupal core
  • Date: 2021-September-15
  • Security risk: Moderately critical 10∕25 AC:Basic/A:User/CI:None/II:Some/E:Theoretical/TD:Default
  • Vulnerability: Cross Site Request Forgery
  • CVE IDs: CVE-2020-13673

SA-CORE-2021-006 (continued)

The Drupal core Media module allows embedding internal and external media in content fields. In certain circumstances, the filter could allow an unprivileged user to inject HTML into a page when it is accessed by a trusted user with permission to embed media. In some cases, this could lead to cross-site scripting.

SA-CORE-2021-006 (fix)

Solution: upgrade to Drupal 9.2.6, 9.1.13, or 8.9.19.

Commit b230624e5b:

  • When editing a WYSIWYG field with a Media embed, add a CSRF token to the header of the jQuery request.
  • Validate the token in the code that responds to that request.

A02:2021-Cryptographic Failures

Cryptography: what goes wrong?

  • data transmitted in clear text
  • old or weak cryptographic algorithms or protocols
  • encryption not enforced
  • deprecated hash functions such as MD5 or SHA1

source: A02:2021 - Cryptographic Failures

Keep it simple

Unless you are a cryptography maven, do not try to do it yourself. Know when to call for an expert!

Q: What data need protection?

What to protect?

  • Passwords
  • API keys
  • Personally identifiable information (PII)
  • Business secrets

PII includes Social Security numbers, credit cards, health information.

HTTP and HTTPS

  • Do not manage your own servers unless that is your business.
  • HTTPS provides encryption and authentication.
  • Enforce HTTPS: Strict-Transport-Security header (HSTS).
  • SSL is insecure. Use TLS 1.2+

SSL Labs

For example, drupal.org SSL Labs report

screenshot of drupal.org SSL Labs report

Drupal update information

… not to be confused with Automatic Updates/Project Browser initiative

In Drupal\update\UpdateFetcher:

  /**
   * URL to check for updates, if a given project doesn't define its own.
   */
  const UPDATE_DEFAULT_URL = 'https://updates.drupal.org/release-history';

We did not fix that until Issue #1538118 2020-11-05. Drupal 7 was fixed 2023-06-06.

API keys

  • Use API keys for external services: SMTP, translation, …
  • Like long passwords
  • Do not commit to your repository.
    • If you do, look up BFG Git (Big Friendly Giant).
  • Securing Authentication Credentials in the “Security in Drupal” guide
    • Use environment variables.
    • Add settings.php value from external file.
    • Use contributed modules for key management.

Passwords in Drupal

  • User management is one of Drupal’s strengths. Do not “roll your own”.
  • Rule #1 (of many): do not store passwords in the database (nor the file system).
    • Store hashed (or encrypted) passwords.
  • Rule #2: Make it secure even with the hashed passwords.
    • Add “salt” before hashing.
    • Use an expensive hash function.

Passwords in Drupal 10.0

In core.services.yml:

  # The argument to the hashing service defined in services.yml,
  # to the constructor of PhpassHashedPassword is the log2
  # number of iterations for password stretching.
  # @todo increase by 1 every Drupal version in order to
  # counteract increases in the speed and power of computers
  # available to crack the hashes. The current password hashing
  # method was introduced in Drupal 7 with a log2 count of 15.
  password:
    class: Drupal\Core\Password\PhpassHashedPassword
    arguments: [16]

Passwords in Drupal 10.1+

In core.services.yml:

  password:
    class: Drupal\Core\Password\PhpPassword

A03:2021-Injection

Injection: what goes wrong

  • User-supplied data is not validated, filtered, or sanitized by the application.
  • Dynamic queries … are used directly in the interpreter.
  • Hostile data is used within … search parameters to extract additional, sensitive records.
  • Hostile data is directly used or concatenated. …

source: A03:2021 - Injection

Injection in Drupal: SA-CORE-2014-005

Drupal 7 includes a database abstraction API to ensure that queries executed against the database are sanitized to prevent SQL injection attacks.

A vulnerability in this API allows an attacker to send specially crafted requests resulting in arbitrary SQL execution. … this can lead to privilege escalation, arbitrary PHP execution, or other attacks.

This … can be exploited by anonymous users.

source: SA-CORE-2014-005

Injection: my response

Because of the severity of the vulnerability and the simplicity of the update, we tested … and updated the site today.

source: my e-mail to boss and site owner (paraphrase)

Injection: the update

Vulnerable code

      foreach ($data as $i => $value) {
        $new_keys[$key . '_' . $i] = $value;
      }

Fixed code

      foreach (array_values($data) as $i => $value) {
        $new_keys[$key . '_' . $i] = $value;
      }

(comment snipped from both)

Injection: the next step

      // Update the query with the new placeholders.
      // preg_replace is necessary to ensure the replacement does not affect
      // placeholders that start with the same exact text. For example, if the
      // query contains the placeholders :foo and :foobar, and :foo has an
      // array of values, using str_replace would affect both placeholders,
      // but using the following preg_replace would only affect :foo because
      // it is followed by a non-word character.
      $query = preg_replace(
        '#' . $key . '\b#',
        implode(', ', array_keys($new_keys)),
        $query
      );

(line breaks added)

A04:2021-Insecure Design

A05:2021-Security Misconfiguration

A06:2021-Vulnerable and Outdated Components

The best kept secret in web security

The secret:

The most important thing is to do all the boring stuff you already know.

It is a lot like …

Click bait?

How to live a longer, healthier life!

It takes just 4 minutes a day!

Does that seem too good to be true?

Brush your teeth!

  • Two minutes, two times a day.
  • Best advice you will get today.
  • Also floss.
  • You really will live a longer, healthier life.

Web security hygiene

  • Use good passwords. Have a policy.
  • Keep your software up to date.
  • Unless hosting is your core business, do not run your own servers.

Drupal: know the schedule

  • Security release windows: Wednesdays 12-5 ET
  • Drupal core updates (patch versions): third Wednesdays
  • Drupal core updates (minor versions): June and December
  • Minor versions are supported for one year.

Drupal: know the channels

Unofficial: @drupalsecurity on X, Mastodon

Drupal: know the difference

  • Major version (Drupal 10 to Drupal 11): disruptive
  • Minor version (10.2 to 10.3): less disruptive, new features
  • Patch version (10.2.3 to 10.2.4): should not be disruptive, bug fixes
  • Security release (10.2.1 to 10.2.2): not disruptive (best effort)

Drupal: trust the security team

Two choices:

  1. Read the SA, decide whether it impacts your site. If so, update.
  2. Update your site.

Either way, you are trusting the security team:

  1. They anticipated all the possible exploits.
  2. The update is not disruptive.

Drupal and Symfony

Q: Why was Drupal 9 EOL scheduled for Nov. 2023?

A: Drupal 9 used Symfony 4, which was EOL in Nov. 2023.

A07:2021-Identification and Authentication Failures

A08:2021-Software and Data Integrity Failures

A09:2021-Security Logging and Monitoring Failures

A10:2021-Server-Side Request Forgery

Conclusion

Summary

  • Introduction
  • What is the OWASP Top Ten?
  • What is Drupal?
  • A01:2021-Broken Access Control
  • A02:2021-Cryptographic Failures
  • A03:2021-Injection
  • A04:2021-Insecure Design
  • A05:2021-Security Misconfiguration

Summary (continued)

  • A06:2021-Vulnerable and Outdated Components
  • A07:2021-Identification and Authentication Failures
  • A08:2021-Software and Data Integrity Failures
  • A09:2021-Security Logging and Monitoring Failures
  • A10:2021-Server-Side Request Forgery
  • Conclusion

References

Contrib modules

Questions

Copyleft

Creative Commons License
This slide deck by Benji Fisher is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Based on a work at https://gitlab.com/benjifisher/slide-decks.