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 #22902

Open
Lubrsi opened this issue Jan 22, 2024 · 0 comments
Open

LibWeb: Implement OfflineAudioContext #22902

Lubrsi opened this issue Jan 22, 2024 · 0 comments
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
Member

Lubrsi commented Jan 22, 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>
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
No open projects
Status: No status
Development

No branches or pull requests

1 participant