Severity: high (7.4)
Type: Cryptographic Failures
Source: http.lua:37-40
The HTTPS path defaults to accepting any certificate and contains no post-handshake hostname check. The exact defaults at src/copas/http.lua:37-40 are:
_M.SSLPROTOCOL = "tlsv1_2"
_M.SSLOPTIONS = "all"
_M.SSLVERIFY = "none"
_M.SSLSNISTRICT = false
getcreatefunc then installs that insecure default at lines 368-374:
ssl_params.wrap.protocol = ssl_params.wrap.protocol or _M.SSLPROTOCOL
ssl_params.wrap.options = ssl_params.wrap.options or _M.SSLOPTIONS
if ssl_params.wrap.verify == nil then
ssl_params.wrap.verify = _M.SSLVERIFY
end
ssl_params.wrap.mode = "client"
For an HTTPS request, lines 394-398 only configure SNI and wrap the socket:
if (reqt.scheme or u.scheme) == "https" then
ssl_params.sni.names = ssl_params.sni.names or u.host
local conn = copas.wrap(socket.tcp(), ssl_params)
SNI selects a virtual host; it does not authenticate the certificate name. There is no peer-certificate/hostname comparison anywhere in this module, so even a caller who changes verify to peer only requests CA-chain verification and can still accept a CA-valid certificate for the wrong hostname.
Exploit scenario: a service sends bearer tokens or private data through copas.http.request("https://api.example/..."). A network-positioned attacker presents a self-signed certificate; because verify="none", the handshake succeeds and the attacker reads and modifies all traffic. If a caller enables chain verification but not an external hostname check, a valid certificate for an attacker-owned name can likewise be accepted for api.example.
Full report: https://console.zeroquarry.com/reports/071a2dbf-cfcf-4f85-9730-5b201c9f96e1/findings/1d779282-5f73-417e-bbdf-9161ecc1bb3b
Severity: high (7.4)
Type: Cryptographic Failures
Source: http.lua:37-40
The HTTPS path defaults to accepting any certificate and contains no post-handshake hostname check. The exact defaults at
src/copas/http.lua:37-40are:getcreatefuncthen installs that insecure default at lines 368-374:For an HTTPS request, lines 394-398 only configure SNI and wrap the socket:
SNI selects a virtual host; it does not authenticate the certificate name. There is no peer-certificate/hostname comparison anywhere in this module, so even a caller who changes
verifytopeeronly requests CA-chain verification and can still accept a CA-valid certificate for the wrong hostname.Exploit scenario: a service sends bearer tokens or private data through
copas.http.request("https://api.example/..."). A network-positioned attacker presents a self-signed certificate; becauseverify="none", the handshake succeeds and the attacker reads and modifies all traffic. If a caller enables chain verification but not an external hostname check, a valid certificate for an attacker-owned name can likewise be accepted forapi.example.Full report: https://console.zeroquarry.com/reports/071a2dbf-cfcf-4f85-9730-5b201c9f96e1/findings/1d779282-5f73-417e-bbdf-9161ecc1bb3b