A recent Wired article about the Parler data hack talked about how a hacker group was able to steal publicly available information from the Parler website using an Insecure Direct Object Reference (IDOR) or enumeration attack. This type of attack involves a hacker looking at the structure of the site and attempting to guess the next available resource by looking at the URL. Apparently, terabytes of Parler's data was downloaded by simply enumerating through the ID's of their publicly available posts.
For the last few years I have been tagging articles as I write them on this site. This tagging has largely been to tie posts together in an aggregated list of other posts tagged with that term. I recently wondered if I could use those tags to show related content below each article. I have struggled with this feature on client websites in the past and it either boils down to a manually curated list or some sort of complex content analysis and Solr search.
As it happens this is fairly easy to accomplish using Views, although took some working out to get the effect I wanted. I'm writing down these instructions to help me remember how I did it in the past and to allow you set up the same thing (if you wish).
Pushing data from Drupal into Solr is a really convenient way of creating a robust and extensible search solution. The Search API module has a number of different fields available that can be used to integrate with all sorts of fields, but what isn't included is computed fields or other data.
Thankfully, adding a custom field into the Search API system doesn't need a lot of code. A single class, with an optional hook, is all that's needed to het everything working.
I was recently looking at the node view count module that was being used to record what users viewed what nodes on a Drupal site. What was needed was a report page that had a bunch of data from different fields of a node, along with the node view count data. As this data wasn't immediately available to Solr I needed to find a way to inject the data into Solr using the mechanisms that Search API has.
Drupal's login forms are protected by a protection mechanism that prevents brute force attacks. This means that if an attacker attempts to repeatedly guess a user's password to gain entry to their account they will be blocked before being successful. This system has been a part of Drupal for many years and so is battle tested.
Like all systems in Drupal, the flood system can be adapted to be used on your own forms. Which means you can protect any form that you don't want to be used too much. This will help with authentication forms or any form that might need to process lots of information where you don't want users to submit the form too much.
Before using the flood system on a form you first need to inject it into the form. Here is a basic form setup with the flood service injected into it.
You've probably been there before. A Drupal View you are working on looks great and has all the data and fields you need, but when you look a little closer at the results you realise that something is off. After looking at the generated SQL query you see that there is a problem with one of the joins which causes your counts to be off a little. Ultimately, you need to remove this join, but you really need that data included in your results.
Creating a subquery can allow you to pull out data from a specific field without adding another join that would cause the results to be out.
Whilst Twig is a powerful tool in its own right there are occasions when you need to pull out data from Drupal or manipulate it in certain ways. I normally do this using preprocess steps, but I recently found that it was also possible to extend Twig within the Drupal framework to provide your own functions and filters. This can be useful if you have custom templates and need to perform special actions on data items to format them in different ways.
Before we can create Twig filters and functions in Drupal we need to tell Drupal that we have a class that contains them. This is done by creating an entry in the your module services file that contains the tag tag.extension. In a module called "custom_twig" the file would be called custom_twig.services.yml and would contain the following.
I recently needed to add functionality to the Password Policy module so I thought I would outline the steps I took in a blog post. The Password Policy module is used to enforce a stricter password policy on users on a Drupal site. This means that when a user creates or changes their password they must conform to certain rules like the password length, or if it contains upper and lower case characters. There are a set of rules to chose from and they can be fully customised by the site administrators. It's a good module, you should check it out.
One gotcha when importing configuration to a Drupal site can be a message that tells you that the configuration you are trying to import is from another site.
Here is the error that can be seen on the Configuration Synchronize page.
The staged configuration cannot be imported, because it originates from a different site than this site. You can only synchronize configuration between cloned instances of this site.
This error happens because the UUID of the site (in the database) is different to that in the configuration (in the code). The UUID in the code is stored in the configuration file system.site.yml. The reason for this check is to ensure that your don't destroy your Drupal site by installing configuration that was created from another site.
Installing a Drupal site from configuration is useful when running tests or if you don't have a copy of the database. You'll get a copy of the Drupal site without any content that will act in the same way as the live site. You can use modules like default content to add content into the mix so your newly installed site acts a little bit more like the live version.
Since there are some prerequisites to get this up and running I thought I would run through what is needed to get this working and how to run it.
A change that was snuck into Drupal version 8.8.0 and wasn't mentioned in the 8.8.0 change notes was a small change to the setting that controls the placement of the configuration directories. The alteration deprecated the $config_directories setting from the settings.php file and move the configuration into the $settings array. You can see the detail behind this change on the Drupal change record.
The fix for this is very easy and only needs a single line of code to change in your settings file.
$config_directories['sync'] = '../config/sync';