Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google Chrome 115.0.5790.102 produces incorrect SHA-256 hashes #40

Closed
randombit opened this issue Aug 3, 2023 · 21 comments
Closed

Google Chrome 115.0.5790.102 produces incorrect SHA-256 hashes #40

randombit opened this issue Aug 3, 2023 · 21 comments

Comments

@randombit
Copy link

I don't think this is a bug in this code but opening this issue to maybe help out someone else trying to debug this in the future:

When this library is used with Google Chrome 115.0.5790.102 (released on July 20 2023), it will produce correct hashes for a while and then after a certain number of hashes are computed, all future hash outputs will be incorrect.

This was seen on x86 and ARM machines running Linux and macOS.

Presumably this is a JIT bug in this particular version of Chrome. It is apparently fixed in 115.0.5790.110 which was released to stable channel 5 days later.

@partical
Copy link

I have a similar problem with Google Chrome 116.0.0.0, it will produce incorrect hashes for a while and then after a certain number of hashes are computed, all future hash outputs will be correct.

@emn178
Copy link
Owner

emn178 commented Aug 21, 2023

Can you give a sample code?

@slisson
Copy link

slisson commented Aug 24, 2023

I can reproduce it in Chrome 116.0.5845.110 using this code:

<html>
<body>
<pre id="output"></pre>
<script src="https://cdn.jsdelivr.net/gh/emn178/js-sha256/build/sha256.min.js"></script>
<script>
    for (let i = 0; i < 100; i++) {
        document.getElementById("output").innerText += i + ": " + sha256.hex("a") + "\n"
    }
</script>
</body>
</html>

After 33 iterations it starts returning a different value.

@slisson
Copy link

slisson commented Aug 24, 2023

An input of "b" is even more interesting. Then it produces more than two different values.

@0tt0sson
Copy link

We're experiencing slowly increasing error rate based some Chrome version rollout.

For now, we changed to @aws-crypto/sha256-js

import { Sha256 } from '@aws-crypto/sha256-js';

export const sha256 = (s: string): string => {
  const hash = new Sha256();
  hash.update(s);
  const hashUint8Array = hash.digestSync();

  return Buffer.from(hashUint8Array).toString('hex');
};

slisson added a commit to modelix/modelix.core that referenced this issue Aug 25, 2023
Replaced it js-sha256 with @aws-crypto/sha256-js.
Also added consistency checks on server and client side to ensure
both side compute the same hash value.

see emn178/js-sha256#40
slisson added a commit to modelix/modelix.core that referenced this issue Aug 25, 2023
Replaced it js-sha256 with @aws-crypto/sha256-js.
Also added consistency checks on server and client side to ensure
both side compute the same hash value.

see emn178/js-sha256#40
@emn178
Copy link
Owner

emn178 commented Aug 25, 2023

I can't reproduce in my Chrome 116.0.5845.110 (arm64)

@ggzzyy112233
Copy link

ggzzyy112233 commented Aug 26, 2023

I had the same problem and needed to open a traceless browser to solve it.my Chrome 116.0.5845.96

@NicolasFlamel1
Copy link

I'm having the same issue with Chrome 116.0.5845.110 on x86-64 Linux. The JIT is doing some weird optimizations to the a variable in the Sha256.prototype.hash function which causes its value to be inconsistent.

As a workaround, using the a variable immediately after setting it in each pass seems to fix this. I accomplish this by passing it to an empty unnamed function here.

@djouf007
Copy link

Same problem, could you help how to fixe that in angular 16 pls, do i need to go to the file js-sha256? is it possible to explain how we do it

thanks

@hanzheliva
Copy link

We've replaced this library with @aws-crypto/sha256-browser as a solution

@emn178
Copy link
Owner

emn178 commented Aug 29, 2023

I use @slisson 's sample code and tried on many versions and devices. I still can't reproduce this issue. Can you guys reproduce by the sample code?

@hanzheliva
Copy link

hanzheliva commented Aug 29, 2023

https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Mac/1160321/

The link is located using https://www.chromium.org/getting-involved/download-chromium/

If you run this Chromium 116.0.5845.96 on Macbook x86 version, you will get a different hash after 132 tries.

Screenshot 2023-08-29 at 11 54 39 AM

And this behavior is not stable if you run the sample code another time
Screenshot 2023-08-29 at 12 03 14 PM

@emn178

@phoenixeliot
Copy link

My coworker and I narrowed at least part of it down to this i++ operation acting very strangely — if you hover over it and then other expressions on this line repeatedly in the debugger, it causes i to increment just by previewing that value, which is extremely not-correct behavior. At this state in the debugger i simultaneously has a value of 0, and 2 depending on which part of the devtools you ask, and it seems that the incremented value is the one used in the calculation.

Sharing in case this is helpful in updating this library's code to work around this problem. Perhaps not inlining the combined var and ++ parts might help? In particular it's weird that i is declared much higher up than where it's used in this loop.

Screenshot 2023-08-22 at 23 54 51

@phoenixeliot
Copy link

phoenixeliot commented Aug 29, 2023

FWIW, even though the above debugger behavior was reproducible on my computer, the simple repro case above does not repro for me, but does repro for my coworker consistently. I haven't run into this general problem happening in production, but he does very consistently. IIRC we use the same model of computer (m1 pro macbook pro 16")

@emn178
Copy link
Owner

emn178 commented Aug 30, 2023

@hanzheliva I can reproduce by download old version. And I use @NicolasFlamel1 's workaround but change to an assignment

{
  //...
  e = a + t1 << 0;
  a = t1 + t2 << 0;
  this.chromeBugWorkAround = true;
}

This seems work and won't lose performance too much. I will use this change to fix this issue in next version.

But I can't sign in my npm account to publish. still working on it...

emn178 added a commit that referenced this issue Aug 30, 2023
### Fixed
- Chrome bug by workaround. #40
- deprecated `new Buffer`, replace with `Buffer.from`. #34
- dependencies and security issues. #32, #36

### Changed
- TypeScript interface, secretKey can be bytes like message. #23, #25
- remove `eval` and use `require` directly. #18, #26
@emn178
Copy link
Owner

emn178 commented Aug 30, 2023

workaround in v0.10.0. Please check if it fixed.

@djouf007
Copy link

djouf007 commented Aug 30, 2023

Thanks Sir but i have this erros with npm install js-sha256@0.10.0

./node_modules/js-sha256/src/sha256.js:68:17-34 - Error: Module not found: Error: Can't resolve 'crypto' in '/var/www/produits/neoshop/neoV16/node_modules/js-sha256/src'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
        - add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
        - install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "crypto": false }

How do i can fixe this

Thanks again

@emn178
Copy link
Owner

emn178 commented Aug 31, 2023

This version remove eval, so webpack detects "require" and causes this. Please check
https://stackoverflow.com/questions/54162297/module-not-found-error-cant-resolve-crypto

@emn178
Copy link
Owner

emn178 commented Aug 31, 2023

@djouf007 I found that I can disable polyfills in my package. use v0.10.1 should work.

@djouf007
Copy link

Thank you so much; it's all working perfectly @emn178

@dskloetd
Copy link

dskloetd commented Sep 5, 2023

Has anyone opened an issue on crbug.com for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests