LadybirdBrowser/ladybird

LibWeb: Cloudflare Turnstile differences between us and other engines

Lubrsi opened this issue · 0 comments

NOTE: This is a living document, it does not contain every difference currently and will be added to.

Neat site for checking the connection side of things (not sure of trustworthiness, take it with a grain of salt): https://cloudflare.manfredi.io/en/tools/connection/

  • navigator.plugins is empty (presumably because we report no PDF support, see navigator.pdfViewerEnabled)
  • navigator.mimeTypes is empty (presumably because we report no PDF support, see navigator.pdfViewerEnabled)
  • Missing first-input performance entry type
  • Missing paint performance entry type (including first-paint and first-contentful-paint)
  • Missing navigation performance entry type
  • Missing resource performance entry type (definitely needs implementing, disabling dom.enable_resource_timing in Firefox makes it never pass)
  • Missing visibility-state performance entry type
  • Missing long-animation-frame performance entry type
  • Missing WEBGL_debug_renderer_info extension for unmasked vendor/renderer info
  • Blob URLs for workers don't work, reporting DedicatedWorkerHost: Unable to fetch script blob:https://localhost:8080/c838e9e6-b238-4210-a349-9c909821d0a5 because script was null
  • navigator.hardwareConcurrency always reports 1
  • window.outerWidth and window.outerHeight report 0 (used in zoom calculation if it thinks we're chromium: Math.round((window.outerWidth / window.innerWidth) * 100) / 100)
  • Thinks we're Firefox due to missing window.chrome and window.webkitRequestAnimationFrame, which makes it resort to probing min--moz-device-pixel-ratio via window.matchMedia for zoom calculation, and reporting "ff" in the same test
  • typeof document.all is not "undefined"
  • Missing screen.availTop
  • Missing screen.availLeft
  • Missing screen.orientation (angle, onchange, lock, unlock, type, inherits EventTarget)
  • Missing screen.onchange
  • Missing screen.isExtended
  • Screen does not inherit EventTarget
  • Missing OfflineAudioContext (random fingerprint challenge, see #224)
  • This spec issue for WWW-Authenticate needs resolving:
    // 1. Needs testing: multiple `WWW-Authenticate` headers, missing, parsing issues.
    // (Red box in the spec, no-op)
  • This spin in execute_script causes the SubtleCrypto::digest task to run out of order in the layout fingerprint challenge, effectively causing an assertion failure in the Turnstile VM:
    if (!m_document->ready_to_run_scripts())
    main_thread_event_loop().spin_until([&] { return m_document->ready_to_run_scripts(); });
  • SerenityOS/serenity#23836
  • Canvas issues in fingerprinting: #225
  • Assuming it scans all HTTP headers sent, we likely need to implement this:
    // FIXME: 13. Append the Fetch metadata headers for httpRequest.
  • Additionally, the priority header, shipped in Firefox and Safari and soon for Chrome: https://chromestatus.com/feature/5109106573049856
  • SerenityOS/serenity#22869
  • Missing HTMLScriptElement#async (7f0920b)
  • Missing Document#lastModified
  • Missing navigator.maxTouchPoints
  • Missing AnalyserNode#getFloatTimeDomainData
  • Missing AudioBuffer#copyFromChannel
  • Missing HTMLCanvasElement#captureStream
  • Missing AnalyserNode#maxDecibels
  • Missing AnalyserNode#getByteTimeDomainData
  • Missing CanvasRenderingContext2D#getLineDash
  • Missing BiquadFilterNode#getFrequencyResponse
  • Missing SVGTextContentElement#getExtentOfChar
  • Missing OffscreenCanvasRenderingContext2D#isPointInStroke
  • Missing Window.closed
  • UIEvent.detail always reports 0 instead of the current click count
  • MouseEvent.movementX and MouseEvent.movementY always reports 0
  • Missing MouseEvent.relatedTarget
  • Missing MouseEvent.layerX and MouseEvent.layerY
  • click event doesn't dispatch a PointerEvent, but instead a MouseEvent, including synthetic clicks via Element#click (likely an issue for other events too)
  • Missing PointerEvent and all of it's attributes and functions
  • We don't set Event#timestamp, defaulted to 0 (at least for click event)
  • <link rel="preload" as="..."> doesn't follow the spec at all, using ResourceLoader directly (missing fetch headers, missing window load event delay, etc.)
  • Missing console.dirxml
  • Missing console.table
  • JSON.stringify(window.getComputedStyle(document.body)) returns {} instead of the serialization of all the properties and their values
  • Missing WebGLRenderingContextBase.getParameter
  • Missing WebGLRenderingContext2#bufferData()
  • Missing WebGLRenderingContext2#readPixels()

CSS and serialization via cssText:

  • url() function serialize with the base URL of the origin, when it shouldn't, e.g. hosted on https://localhost:8080, this:
.OwaTZc4{background-image:url('/cdn-cgi/challenge-platform/h/b/cmg/1/hV7fTYrIy7e%2FC5FuCgYHr5Utjf5x6tY32TUpCSZd1P8%3D'); background-position: -1px -1px; background-repeat:no-repeat;}

Serializes as:

.OwaTZc4 { background-image: url(\"https://localhost:8080/cdn-cgi/challenge-platform/h/b/cmg/1/hV7fTYrIy7e%2FC5FuCgYHr5Utjf5x6tY32TUpCSZd1P8%3D\"); background-position: left -1px top -1px; background-repeat: no-repeat no-repeat; }
  • Combined percentages in @keyframe are serialized separately instead of together, e.g.:
@keyframes scale {
    0%, 100% {
        transform: none;
    }
    50% {
	transform: scale3d(1, 1, 1);
    }
}

Should serialize as:

@keyframes scale { 
  0%, 100% { transform: none; }
  50% { transform: scale3d(1, 1, 1); }
}

But we serialize it as:

@keyframes "scale" {
    0% {
        transform: none;
    }

    100% {
        transform: none;
    }

    50% {
        transform: scale3d(1, 1, 1);
    }
}
  • Fail to parse and serialize multiple animations declared in one animation property, e.g. animation: fillfail 0.4s ease-in-out 0.4s forwards, scale 0.3s ease-in-out 0.9s both;

  • Some properties are serialized as full form when they shouldn't:

    • text-decoration: underline; -> text-decoration: underline auto solid currentcolor;
    • border-radius: 50%; -> border-radius: 50% 50% 50% 50% / 50% 50% 50% 50%;
    • animation: scale-up-center 0.6s cubic-bezier(0.55, 0.085, 0.68, 0.53) both; -> animation: cubic-bezier(0.55, 0.085, 0.68, 0.53) normal scale-up-center running 0s 0.6s both 1; (note that this is also serialized out of order)
    • background: #fff; -> background: rgb(255, 255, 255) none left 0% top 0% auto auto repeat repeat scroll padding-box border-box;
    • Weird one: flex-flow: column nowrap; (as specified in the actual style sheet) should serialize as flex-flow: column, but we keep it as is
    • Same with flex-flow: row nowrap; and flex-flow: row-reverse nowrap;
  • Missing stroke-dashoffset and it's serialization

  • Missing stroke-linecap and it's serialization

  • Missing stroke-miterlimit and it's serialization

  • Missing stroke-dasharray and it's serialization

  • Missing stroke-linejoin and it's serialization

  • This:

margin: 0;
margin-top: 6px;
margin-left: 16px;

Should serialize as:

margin: 6px 0px 0px 16px;
  • This:
background-color: white;

Should stay as is, but we serialize it as:

background-color: rgb(255, 255, 255);