The Accidental Coder: Drupal 10 Sandbox in 10 Easy Steps
clemens-tolboom starred finepointcgi/godot-location-plugin
Android Location API implementation for Godot
Kotlin 6 Updated May 27
clemens-tolboom starred finepointcgi/godot-location-plugin
Android Location API implementation for Godot
Kotlin 6 Updated May 27
mcdruid.co.uk: Insecure Deserialisation and IDOR, oh my!
A few years ago I found quite an interesting vulnerability in a contributed Drupal module called tablefield.
The module allows Drupal entities to hold tabular data, and the vulnerability was a combination of Insecure Deserialisation and a type of Insecure Direct Object Reference (IDOR).
The fix was released over 4 years ago so sufficient time has passed for me to share some more details.
The module has a hook_menu page callback (Drupal 7's equivalent of a route) that looks like this:
( 'tablefield/export/%/%/%/%/%' => array( 'page callback' => 'tablefield_export_csv', 'page arguments' => array(2, 3, 4, 5, 6), 'title' => 'Export Table Data', 'access arguments' => array('export tablefield'), ),https://git.drupalcode.org/project/tablefield/-/blob/7.x-3.3/tablefield....
The callback function that would pass requests to looked like this:
/** * Menu callback to export a table as a CSV. * * @param string $entity_type * The type of entity, e.g. node. * @param string $entity_id * The id of the entity. * @param string $field_name * The machine name of the field to load. * @param string $langcode * The language code specified. * @param string $delta * The field delta to load. */ function tablefield_export_csv($entity_type, $entity_id, $field_name, $langcode, $delta) { $filename = sprintf('%s_%s_%s_%s_%s.csv', $entity_type, $entity_id, $field_name, $langcode, $delta); $uri = 'temporary://' . $filename; // Attempt to load the entity. $ids = array($entity_id); $entity = entity_load($entity_type, $ids); $entity = array_pop($entity); // Ensure that the data is available and that we can load a // temporary file to stream the data. if (isset($entity->{$field_name}[$langcode][$delta]['value']) && $fp = fopen($uri, 'w+')) { $table = unserialize($entity->{$field_name}[$langcode][$delta]['value']); ...snip...https://git.drupalcode.org/project/tablefield/-/blob/7.x-3.3/tablefield....
So this page callback takes several parameters from the URL and uses them to load the value of a specific field on a given entity.
It is assumed that this will be a tablefield, and that its content will be serialised tablular data.
The callback passes the value of the field to PHP's unserialize() in order to reconstruct the tabular data in order to export it to a CSV file.
Can you spot a problem here?
It's possible for an attacker to pass any combination of the parameters $entity_type, $entity_id, $field_name, $langcode, $delta in order to load an arbitrary field from the database, and the value stored in that field will be passed to unserialize(). Oops.
In order for this to be an exploitable vulnerability on a site, two conditions need to be met. The attacker must be able to:
- Store their payload in an entity's field.
- Access the "Export Table Data" callback (in other words they need to have the "export tablefield" permission).
It's good that the callback is protected by its own permission, but it seems likely that this permission may be granted to fairly low privileged or even anonymous users.
As for storing a payload in an entity field, this too is something that low privileged or even anonymous users are quite often able to do on Drupal sites.
If a user can post a comment, for example, that comment is stored as an entity field. A comment field could be passed to tablefield's callback with a URL like this:
$ curl http:// example.com /tablefield/export/comment/1/comment_body/und/0In my original report of this vulnerability I gave the following as an example payload:
O:11:"Archive_Tar":1:{s:13:"_temp_tarname";s:23:"/tmp/now_you_see_me.txt";}This is a serialised object of Drupal 7's Archive_Tar class, which is based on PEAR's Archive_Tar.
At the time of the report, the class destructor would "clean up" by calling unlink() on the value of _temp_tarname if it was set.
public function __destruct() { $this->_close(); // ----- Look for a local copy to delete if ($this->_temp_tarname != '') { @unlink($this->_temp_tarname); } }https://github.com/pear/Archive_Tar/blob/19bb8e95490d3e3ad92fcac95500ca8...
So when this example payload was stored in a comment, then loaded by the callback and passed to unserialize() the Archive_Tar object would briefly be reanimated, then the destructor would be called and the file specified in the payload would be deleted.
This could be used, for example, to delete a .htaccess file protecting a sensitive directory, or preventing PHP uploads from being executed. An attacker with an appetite for destruction might simply try to delete settings.php
Other gadget chains may be available on a given site, but Drupal 7 core does not have many classes that make good candidates for this.
Comments weren't the only viable vector, but they were probably the most likely entity field that an attacker might be able to write to.
After this report was submitted to the Drupal Security Team, the maintainers of the module responded almost immediately and were exemplary in the way they handled the issue and worked on releasing the fix. We also co-ordinated with the Backdrop Security team.
https://www.drupal.org/sa-contrib-2019-045 was rated as Critical 16/25. The fix we agreed on was simply that the callback should check that the given entity field was actually managed by tablefield before passing its value to unserialize():
// Ensure this is a tablefield. $field_info = field_info_field($field_name); if (!$field_info || $field_info['type'] != 'tablefield') { return drupal_not_found(); }https://git.drupalcode.org/project/tablefield/-/compare/7.x-3.4...7.x-3....
Since then, I got a PR merged upstream to harden the destructor in Archive_Tar which means the example payload would no longer delete any arbitrary file.
Tags: drupal-planetsecurityclemens-tolboom opened an issue in MicrosoftDocs/edge-developer
└── part1 ├── _manifest.json <====== has an underscore ├── icons │ ├── nasapod16x16.png │ ├── nasapod32x32.png │ ├── nasapod48x48.png │ └── nasapod…
clemens-tolboom created a branch clemens-main in clemens-tolboom/Godot-Open-AI-GPT-Integration
Updated Jun 16
clemens-tolboom created a tag V1.0.1 in clemens-tolboom/Godot-Open-AI-GPT-Integration
Updated Jun 16
clemens-tolboom created a tag 1.0 in clemens-tolboom/Godot-Open-AI-GPT-Integration
Updated Jun 16
clemens-tolboom opened a pull request in finepointcgi/Godot-Open-AI-GPT-Integration
Initial fix for HTTP response errors (like no more credit, too many requests) and json parsing, and json error errors. See ie https://platform.open…
+27 -6clemens-tolboom pushed to check-for-response-json-error in clemens-tolboom/Godot-Open-AI-GPT-Integration
clemens-tolboom created a branch check-for-response-json-error in clemens-tolboom/Godot-Open-AI-GPT-Integration
Updated Jun 16
clemens-tolboom commented on issue finepointcgi/Godot-Open-AI-GPT-Integration#3
Did you ran into more errors? PR #4 fixes one of yours.
clemens-tolboom opened a pull request in finepointcgi/Godot-Open-AI-GPT-Integration
Fixes error res://addons/GPTIntegration/GPTIntegration.gd:225 - Attempt to call function 'get_as_text' in base 'null instance' on a null instance. …
+11 -2clemens-tolboom pushed to fix-missing-json-file in clemens-tolboom/Godot-Open-AI-GPT-Integration
- f532660 Auto create settings.json.
clemens-tolboom created a branch fix-missing-json-file in clemens-tolboom/Godot-Open-AI-GPT-Integration
Updated Jun 16
clemens-tolboom forked clemens-tolboom/Godot-Open-AI-GPT-Integration from finepointcgi/Godot-Open-AI-GPT-Integration
GDScript 33 Updated Jun 16
clemens-tolboom commented on pull request MikeSchulze/gdUnit4#214
LGTM :-) I miss the direct linking to the steps but that is your call. Maybe mention your numbering convention on issue titles? And you project(s) …
clemens-tolboom commented on pull request MikeSchulze/gdUnit4#207
Can't this go into one of the PR steps? Step 5 maybe? Ensure your code follows GDScript or C# Coding Conventions
clemens-tolboom commented on pull request MikeSchulze/gdUnit4#207
I think this section can go way up :-)
clemens-tolboom commented on pull request MikeSchulze/gdUnit4#207
If you make the list below H3 or H4 you can direct link in the future to particular items giving better pointers to contributors IMHO