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

LibWeb: Implement OfflineAudioContext #224

Open
Lubrsi opened this issue Jun 20, 2024 · 1 comment
Open

LibWeb: Implement OfflineAudioContext #224

Lubrsi opened this issue Jun 20, 2024 · 1 comment
Labels
enhancement New feature or request reduction of web content Issue has a simplified reduction based on real-world web content. web compatibility

Comments

@Lubrsi
Copy link
Contributor

Lubrsi commented Jun 20, 2024

Required by Cloudflare Turnstile's fingerprinting. It checks for the existence of OfflineAudioContext and, if that doesn't exist, webkitOfflineAudioContext. If neither exist, it returns from the AudioContext fingerprinting test but fails to progress the challenge runner to the next test, causing it to indefinitely lock-up. (Side note, this seems to be a bug in the challenge runner, as it progresses the runner for other things not existing such as fetch, which arrived to the web platform after OfflineAudioContext)

Reduced from Turnstile:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="challenge-stage"></div>
<script>
    function sha256Hash(stringToHash) {
        const encodedString = new TextEncoder().encode(stringToHash);
        return crypto.subtle.digest("SHA-256", encodedString).then((value) => {
            const valueAsArray = Array.from(new Uint8Array(value));
            const arrayAsHex = valueAsArray.map(num => num.toString(16).padStart(2, '0'));
            return arrayAsHex.join("");
        });
    }

    const audioContext = new OfflineAudioContext(1, 5000, 44100);

    const oscillator = audioContext.createOscillator();
    oscillator.type = "triangle";
    oscillator.frequency.value = 9998.123456;

    const dynamicsCompressor = audioContext.createDynamicsCompressor();
    dynamicsCompressor.threshold.value = -52;
    dynamicsCompressor.knee.value = 40;
    dynamicsCompressor.ratio.value = 12;
    dynamicsCompressor.attack.value = 0.0001;
    dynamicsCompressor.release.value = 0.25;

    oscillator.connect(dynamicsCompressor);

    dynamicsCompressor.connect(audioContext.destination);

    oscillator.start();
    audioContext.oncomplete = function (ev) {
        const data = ev.renderedBuffer.getChannelData(0);
        if (data && data.length > 0) {
            const joinedValues = data.join("|");
            sha256Hash(joinedValues).then(fingerprint => {
                document.getElementById("challenge-stage").innerText = `AudioContext fingerprint: ${fingerprint}`
            });
        }
    };

    audioContext.startRendering();
</script>
</body>
</html>
@Lubrsi Lubrsi added enhancement New feature or request reduction of web content Issue has a simplified reduction based on real-world web content. web compatibility labels Jun 20, 2024
@carlosjeurissen
Copy link

In Safari Lockdown mode, both OfflineAudioContext and AudioContext are undefined. So if the Cloudflare Turnstile's fingerprinting works fine in Safari Lockdown mode, the issue seems not be caused by the OfflineAudioContext.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request reduction of web content Issue has a simplified reduction based on real-world web content. web compatibility
Projects
None yet
Development

No branches or pull requests

2 participants