Skip to content

Proposal: Test JA4 fingerprints in Test::Nginx using curlu #59

Description

@lynch1981

Background / The Problem

Test::Nginx relies on Perl sockets by default, which limits our ability to customize low-level TLS ClientHello attributes (ciphersuite ordering, extensions, ALPN configurations, etc.) required for thorough JA4 fingerprint testing.

Solution

While Test::Nginx doesn't support custom TLS handshakes out of the box, it does support delegating HTTP/HTTPS requests to an external curl binary via --- curl_options.

To leverage this, I built curlu—a curl-compatible CLI tool backed by uTLS that allows simulating specific ClientHello signatures.

By prepending curlu to PATH (aliased or binary-named as curl), Test::Nginx transparently executes curlu under the hood without requiring any modifications to Test::Nginx itself.

Workflow & Test Example

1. Setup Environment

export PATH=/home/ubuntu/curlu:$PATH
prove -v test/tls-ja4-variables.t

2. Test Case Definition

=== TEST 1: firefox_55_ja4
# HelloFirefox_55: TLS 1.2, client ALPN h2.
# Note: Extension count in the 'a' section may vary with PADDING,
# but cipher/extension hashes remain deterministic.
--- config
    location /t {
        default_type text/plain;
        return 200 "ja4=$http_ssl_ja4\n";
    }
--- curl_protocol: https
--- curl_options: --utls-hello HelloFirefox_55
--- request
GET /t
--- response_body_like chomp
^ja4=t12i15[0-9]{2}h2_073e58a039a6_e70312a1ce2c$
--- no_error_log
[error]

@vlvkobal

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions