Skip to main content

Introduction

Drupal's transition to GitLab has brought about a sea change in how patches are managed. While the move offers new possibilities, it also presents challenges that every Drupal developer should be aware of. This blog post aims to shed light on the current state of patch management in Drupal, focusing on the challenges, community responses, and best practices.

The Shift to GitLab

Drupal's migration from its previous system to GitLab in March 2019 has had a significant impact on patch management. GitLab offers a robust platform for code collaboration but introduces complexities when it comes to generating and applying patches.

The Problem Space

Interconnected Challenges

The shift to GitLab has introduced a primary challenge that subsequently leads to a security concern:

  1. Instability of Diff URLs: GitLab's Merge Request (MR) URLs are not static, making it difficult to generate stable patch files.
    • Resulting Security Risk: This instability poses a security risk, as dynamic URLs can be susceptible to malicious code injection by anyone with commit access.

Proposed Solutions & Workarounds

The community has proposed several solutions:

  • Checksums: To enhance security, especially for remote patches.
  • Static Patch Files: As a workaround, use a static patch file at a given point in time and apply it using composer-patches.

Recommended Approach - Adding a Patch to Drupal Core using Composer

Here i'll walk you through the process of applying a patch to Drupal core using Composer. This is particularly useful when you want to fix a bug or add a feature that hasn't yet been committed to the Drupal core repository.

Prerequisites

  • A Drupal website set up with Composer
  • Lando for local development
  • Git installed and configured

Step 1: Navigate to Your Project Directory

Open your terminal and navigate to your Drupal project directory.

cd /path/to/your/drupal/project

Step 2: Create a 'patches' Directory

First, check if a patches directory exists. If not, create one.

mkdir -p patches

Step 3: Find a Patch

Browse the Drupal.org issue queue to find a patch that you want to apply. Download the patch file.

Step 4: Move the Patch to 'patches' Directory

Move the downloaded patch to the patches directory.

mv /path/to/downloaded/patch patches/

Step 5: Update composer.json

Open your composer.json file and add the patch definition under the extra section.

"extra": {
  "patches": {
    "drupal/core": {
      "Description of patch (URL of issue) (URL of original patch download location)": "patches/your-patch-file.patch"
    }
  }
}

Step 6: Apply the Patch using Lando and Composer

Run the following command to apply the patch.

lando composer install

Step 7: Add the Patch and composer.json to Git

Add the patch file and the updated composer.json to your Git repository.

git add patches/your-patch-file.patch composer.json

Step 8: Commit the Changes

Commit the changes with a suitable message.

git commit -m "Applied patch to Drupal core to fix [issue description]"

And there you have it! You've successfully applied a patch to Drupal core using Composer and Lando.

Community Responses

Here's a rundown of the community's take on these issues:

Drupal.org Issue: GitLab Merge Requests Unable to Generate Incremental Patch Files

Status: Active.

Details: The issue revolves around the challenges of working with Drupal patches in GitLab's Merge Request (MR) environment. The core problem is that the diff URL in GitLab's MR isn't stable, especially when multiple commits are pushed to an MR. This makes it difficult to generate a patch file that includes only specific changes.

The issue outlines a scenario where multiple contributors push commits to an MR, and the resulting patch file includes all these changes. This makes it difficult to test individual commits. While GitLab can provide patch files for specific commits or the entire MR, it doesn't support generating a patch file for a subset of commits.

Proposed Solutions:

GitLab could allow generating patch files between two specified commits. Use a static patch file at a given point in time and apply it using composer-patches. Community Consensus:

There's a general agreement to avoid solutions that complicate the architecture, like generating patch files that get posted back to the Drupal issue queue.

GitHub Issue: Patches from Drupal.org Merge Request URLs are Dangerous

Status: Closed.

Details: The issue discusses the security risks of using Drupal.org's GitLab-based merge request URLs in composer-patches. It points out that these URLs are mutable, meaning they can be changed by anyone with commit access, which poses a risk of malicious code injection.

Why Closed: The issue has been closed because a related Pull Request (#388) has been merged. This PR aims to address the security concerns by introducing hash-based protection for remote patches.

Current State: The PR introduces an opt-in feature for hash-based protection, which has sparked a debate. The community is discussing whether this security feature should be opt-in or enabled by default. The conversation also delves into how this feature interacts with local vs. remote patches and the role of composer.lock in storing these hashes.

Recommended Workaround: Given the ongoing discussions and the opt-in nature of the new feature, the safest approach for now is to download the patch and commit it to your repository. It's unclear whether Composer 2 will automatically checksum these committed patches.

Proposed Solutions:

A warning should be issued for people using such URLs. GitLab might need a feature to pin a merge request URL to a specific commit. Storing SHA-256 hashes of all patches in the lock file to detect changes. Community Consensus:

There's a strong focus on security, with several contributors emphasizing the need for checksums and static URLs. Some suggest downloading patches and storing them in version control as a workaround.

GitHub Pull Request: Add Support for Patch Checksums

Status: Closed, not merged.

Details: This pull request aimed to add checksum support but was closed in favor of issue #447, which seems to have incorporated these changes.

Why Closed: Superseded by another merged issue (#447).

Closed with a note that it is resolved in GitHub Issue #447

This pull request aims to add checksum support to composer-patches, specifically targeting version 1.x. The idea is to provide a security layer by hashing the patches, especially those coming from remote sources. The PR suggests using SHA-256 as the hashing algorithm.

This pull request aims to add checksum support to composer-patches, specifically targeting version 1.x. The idea is to provide a security layer by hashing the patches, especially those coming from remote sources. The PR suggests using SHA-256 as the hashing algorithm.

Proposed Solutions:

Implement hash-based protection by default for remote patches. Autogenerate hashes for new remote patches and store them in composer.lock. Limit the scope to support only SHA-256 checksums. Community Consensus:

There's a strong push for implementing this feature to enhance security. Some contributors suggest that supporting only local patches could be the safest option.

GitHub Pull Request: Add Support for Patch Checksums

Status: Merged into the master branch.

Details: This pull request seems to be a significant update, including a lot of commits. It's a bit hard to tell if it directly addresses the checksum issue, but it was merged, indicating that the changes are now part of the main codebase.

Why Closed: Merged, indicating that the changes proposed are now part of the main project.

This pull request aims to add checksum support to composer-patches, specifically targeting version 1.x. The idea is to provide a security layer by hashing the patches, especially those coming from remote sources. The PR suggests using SHA-256 as the hashing algorithm.

Proposed Solutions:

Implement hash-based protection by default for remote patches. Autogenerate hashes for new remote patches and store them in composer.lock. Limit the scope to support only SHA-256 checksums. Community Consensus:

There's a strong push for implementing this feature to enhance security. Some contributors suggest that supporting only local patches could be the safest option.

Thought-Provoking Questions:

How can the Drupal community work with GitLab to implement a more stable patching system?

How can the security risks be mitigated while still maintaining the convenience of dynamic patching?

Is pinning a merge request to a specific commit a viable solution?

What are the implications for enterprise-level projects that have strict security requirements?

Is checksum support sufficient to mitigate the security risks associated with remote patches?

How would hash-based protection impact the workflow for Drupal developers?

What are the trade-offs between security and convenience when implementing checksums?