Problem/Motivation

catch/dawehner pointed out that SHA1 is overkill for placeholder tokens, since they don't need to be cryptographically secure.

Proposed resolution

Use CRC32 instead of SHA1.

Remaining tasks

None.

User interface changes

None.

API changes

None.

Data model changes

None.

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Task because just an improvement.
Issue priority Normal because we can easily ship without this.
Prioritized changes The main goal of this issue is consistency/DX: SHA1 is overkill for this use case, and core should set the right example.
Disruption Zero disruption.

Comments

dawehner’s picture

There are also quite a lot of Crypt:: placeholders floating around.

Status: Needs review » Needs work

The last submitted patch, crc32-placeholder.patch, failed testing.

RavindraSingh’s picture

Status: Needs work » Needs review
Issue tags: +Needs tests
StatusFileSize
new1.31 KB

Updated with Crypt::hashBase64(serialize($placeholder_render_array));

Needs tests also.

dawehner’s picture

Updated with Crypt::hashBase64(serialize($placeholder_render_array));

IMHO we better want to switch to a different way than crypt in order to make it clear, that we don't deal about something security related here.

Status: Needs review » Needs work

The last submitted patch, 3: 2542830-2-placeholder.patch, failed testing.

borisson_’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new1.66 KB
new2.5 KB

Fixes the failures introduced in the initial patch.

RavindraSingh’s picture

Status: Needs review » Reviewed & tested by the community

#6 Looks good. manually reviewed the patch.

+++ b/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php
@@ -61,7 +61,7 @@ public function providerPlaceholders() {
+      $token = crc32(serialize($token_render_array));

Verified - Crc32 is being used correctly. making it RTBC.

dawehner’s picture

Alright, we we don't want to convert Crypt::hashBase64 over here, does someone mind opening up a follow up for that?

wim leers’s picture

Component: cache system » render system

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 6: change_placeholder-2542830-6.patch, failed testing.

Status: Needs work » Needs review
borisson_’s picture

Status: Needs review » Reviewed & tested by the community

Back to rtbc, the failure is unrelated to this patch.

copy(/var/lib/drupaltestbot/sites/default/files/checkout/sites/simpletest/419716/settings.php): failed to open stream: No such file or directorycopy('/var/lib/drupaltestbot/sites/default/files/checkout/sites/default/default.settings.php', '/var/lib/drupaltestbot/sites/default/files/checkout/sites/simpletest/419716/settings.php') Drupal\simpletest\WebTestBase->prepareSettings() Drupal\simpletest\WebTestBase->setUp() Drupal\simpletest\TestBase->run(Array) simpletest_script_run_one_test('2', 'Drupal\action\Tests\ActionUninstallTest')	
wim leers’s picture

Status: Reviewed & tested by the community » Needs work

We should use hash('crc32b') instead, see #2546680: Use hash('crc32b') not crc32().

pieterjanput’s picture

Status: Needs work » Needs review
StatusFileSize
new2.39 KB
new3.93 KB
wim leers’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll
+++ b/core/lib/Drupal/Core/Render/Renderer.php
@@ -669,7 +669,7 @@
-    $attributes['token'] = crc32(serialize($placeholder_render_array));
+    $attributes['token'] = hash('sha1', serialize($placeholder_render_array));

+++ b/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php
@@ -61,14 +61,14 @@
-      $token = crc32(serialize($token_render_array));
+      $token = hash('sha1', serialize($token_render_array));

@@ -275,7 +275,7 @@
-    $token = crc32(serialize($expected_placeholder_render_array));
+    $token = hash('sha1', serialize($expected_placeholder_render_array));

Oops — these re-introduce SHA1. :)

pieterjanput’s picture

Status: Needs work » Needs review
StatusFileSize
new2.39 KB
wim leers’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs reroll
catch’s picture

Title: Change placeholder token generation from using sha1 to csc32 » Change placeholder token generation from using sha1 to crc32b

This is a case where we might want to be concerned about hash collisions. I'm not sure if that's a real issue, but compared to any other usage it's more likely to be a problem.

catch’s picture

Status: Reviewed & tested by the community » Needs review
olli’s picture

+++ b/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php
@@ -68,7 +68,7 @@ public function providerPlaceholders() {
-      $token = hash('sha1', serialize($token_render_array));
+      $token = hash('crc32', serialize($token_render_array));

Issue title says to switch from sha1 to crc32b, not crc32.

#18: Would md5 or another algorithm be better here?

borisson_’s picture

Status: Needs review » Needs work
wim leers’s picture

This is a case where we might want to be concerned about hash collisions. I'm not sure if that's a real issue, but compared to any other usage it's more likely to be a problem.

Awesome point!

I think that if the placeholders were using solely the CRC32 check, that we could indeed have a problem. There are 2^32 (>4 billion) possible hashes. But, more importantly, the hash here is only a subset of the placeholder. We always also list the callback and arguments. This was originally done not to avoid collisions, but to improve debuggability. But now, it effectively helps to avoid collisions.


#20: indeed. I missed that.

borisson_’s picture

Status: Needs work » Needs review
StatusFileSize
new2.39 KB
new2.39 KB

Resolved #20 by using crc32b.

@Wim Leers explained why crc32b is enough in #22 so #18 shouldn't be a problem anymore.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community

This is going to conflict with #2543334: Auto-placeholdering for #lazy_builder with bubbling of contexts and tags, but that's easy enough to resolve.

alexpott’s picture

So do we need to force a cache clear or something because placeholders are changing - is there an upgrade path implication here?

wim leers’s picture

No, because:

  • any placeholder works, even foobar can be used as a placeholder.
  • the placeholders in #markup have the associated #attached[placeholders] already, so there is always guaranteed to be a 1:1 mapping
wim leers’s picture

In other words: any cached render array is fully internally consistent. It doesn't matter if the outside world changes.

catch’s picture

I don't think so since update.php does a drupal_flush_all_caches() whether or not there are updates to run:

https://api.drupal.org/api/drupal/core%21modules%21system%21src%21Contro...

https://api.drupal.org/api/drupal/core%21modules%21system%21src%21Contro...

wim leers’s picture

Issue summary: View changes

Rewrote IS and added beta evaluation.

dawehner’s picture

Catch is certainly right here, I ran into that, while working on #2540416: Move update.php back to a front controller

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 9f12768 and pushed to 8.0.x. Thanks!

Thanks for adding the beta evaluation to the issue summary.

  • alexpott committed 9f12768 on 8.0.x
    Issue #2542830 by borisson_, PieterJanPut, RavindraSingh, Wim Leers,...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.