java-topology/docs/tickets/openssl-0001-ssl-get-shared-ciphers-quadratic-find.md
russell@unturf.com 9934133dcf whitepaper: 312 sites / 151 ecosystems — wave2+3 defect tables and PDF rebuild
Add 88 new defect entries to HIGH and MEDIUM tables:
  HIGH: mysql-0001/0002, mariadb-0001, redis-0001/0002, valkey-0001/0002, openvpn-0001,
        vlc-0001, prometheus-0001, otel-collector-0001, cockroachdb-0001..0004,
        tidb-0001..0008, kubernetes-0001/0002, go-0001, kotlin-0002, scala-0001,
        allegro5-0001, sdl2-0001, grafana-0001, clickhouse-0001, duckdb-0001,
        mongodb-0001, envoy-0001, istio-0001, cilium-0001, linkerd2-0001,
        linux-0001/0002/0003, tor-0002/0003, curl-0001, julia-0001, lua-0001,
        perl5-0001, nats-0001, spring-0003/0004, tomcat-0001, onos-0002, odl-0002

  MEDIUM: helm-0001, mariadb-0002, openssl-0001/0002, memcached-0001,
          cassandra-0001..0004, flink-0001, storm-0001/0002, zookeeper-0001..0003,
          pip-0001, gradle-0001, nginx-0001, haproxy-0001, caddy-0001, varnish-0001,
          ffmpeg-0001, gstreamer-0001, raylib-0001, love2d-0001, php-0001/0002,
          r-source-0001, cpython-0002, ruby-0001, rabbitmq-0003/0004, activemq-0001,
          ovs-0001, onos-0003, odl-0002, jetty-0001

PDF: 976K
2026-03-27 15:23:43 -04:00

1.8 KiB
Raw Blame History

openssl-0001: SSL_get_shared_ciphers — O(n²) cipher intersection via unsorted sk_SSL_CIPHER_find

CWE: CWE-407 (Inefficient Algorithmic Complexity) Severity: MEDIUM Status: PATCHED File: ssl/ssl_lib.cSSL_get_shared_ciphers()

Defect

SSL_get_shared_ciphers() iterates all client cipher suites (outer loop, O(n)) and for each one calls sk_SSL_CIPHER_find(srvrsk, c) on the server cipher stack.

sk_SSL_CIPHER_findOPENSSL_sk_findinternal_find: when the stack has no comparator set or is not sorted, falls through to a linear scan (for i = 0; i < st->num).

The compare function is intentionally NOT set on srvrsk here — the comment in s3_lib.c (line 4808) says: "Do not set the compare functions, because this may lead to a reordering by 'id'. We want to keep the original ordering. We may pay a price in performance during sk_SSL_CIPHER_find()."

Result: O(n × m) where n = client cipher count, m = server cipher count. TLS 1.2 supports ~100 cipher suites; hostile clients can send 100 → 10,000 comparisons per SSL_get_shared_ciphers() call.

// ssl/ssl_lib.c:3618
for (i = 0; i < sk_SSL_CIPHER_num(clntsk); i++) {   // O(n)
    c = sk_SSL_CIPHER_value(clntsk, i);
    if (sk_SSL_CIPHER_find(srvrsk, c) < 0)           // O(m) — linear when unsorted
        continue;
    ...
}

Fix

Build a uint32_t bitset or LHASH/hash-set of server cipher IDs before the loop. Membership check becomes O(1); total complexity O(n + m).

See patch: defects/openssl/patch/openssl-0001.patch

Hot Path

Called by diagnostic/logging code and TLS session inspection. Not the negotiation fast path (ssl_choose_cipher uses a pre-sorted cipher_list_by_id) but still reachable per connection on servers that log shared cipher info.