Lifetime of sessions in `net/http-easy`

Hi, Racket Discourse.

I encountered an API (specifically ThreatFox), which requires an SSL context for the session when making requests; I am using net/http-easy.

Easy enough, after I figured that part out, but now I am wondering how long-lived such a session value should be: Do you make a new session each time you are making a spate of requests, or is it fine to define one session and use this throughout the code's lifetime?

Looking at @bogdan's source code, it seems like the default session is such a long-lived value, but I would still like to confirm whether I am taking the correct approach, considering this is mostly fire-and-forget at this point.

An example of my current approach (using the latter method):

(define ssl-session (make-session #:ssl-context (ssl-make-client-context)))

 ...

(define (search-ioc-info ioc)
  (define api-token (config:get-section 'api 'threatfox 'api-token))
  (define endpoint  (threatfox:post-any))
  (define request   (request/threatfox
                     api-token (hasheq 'query "search_ioc"
                                       'search_term ioc)))
  (parameterize ([current-session ssl-session])
    (response-json (request endpoint))))

Sessions are intended to be long-lived. The main benefits of long lived sessions are connection pooling and a shared cookie jar (if provided when the session is created). They can also be short lived; it really depends on your use case. In this case, it seems like it would be fine to use the same session for the lifetime of your program. That said, the default session already comes with a secure SSL client context. Calling ssl-make-client-context with no arguments like in your example returns an insecure context (i.e. one that doesn’t validate certs), so that might not be what you want.

1 Like

That makes sense, thank you @bogdan.

I have never had the occasion to make use of one until now, thank you for pointing that out!

Interestingly, using 'secure causes a similar failure to the initial head-scratcher, but the 'tls13 and 'tls12 seem to work fine.

Neither the docs for the API nor the response headers mention it specifically, so I guess I'd have to run an nmap or similar to confirm the ciphers being used.

Which is exactly what you said, lol :roll_eyes:

You might give 'auto a try in that case. The 'secure protocol avoids weak ciphers, but it sounds like the remote is using one of those.

Looks like I can't edit this post, so:

Actually, it looks like 'auto does not verify certificates (and, probably, neither do the other protocol symbols). So, you would have to do something like the following to construct a secure context that allows weak ciphers:

(define ctx (ssl-make-client-context 'auto))
(ssl-load-default-verify-sources! ctx)
(ssl-set-verify! ctx #t)
(ssl-set-verify-hostname! ctx #t)
(ssl-seal-context! ctx) ;; optional
(define session (make-session #:ssl-context ctx))

Very interesting. Seems like the example from the openssl docs showing the equivalent construction for ssl-secure-client-context, if I am parsing this correctly, except for the ssl-set-ciphers! being omitted?

But unfortunately, no dice. If use the session from the above, I am left with:

[error]
... ssl-connect: connect failed (error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed)

Yep.

Sounds like you're missing a root certificate in that case in your local store in that case. I just tried making a(n invalid) request to that API with a secure context and everything works fine.

1 Like

I'll have to check that out, then. Could be any one of the many network-related "security" softwares running on this poor machine.

Thank you so much for taking the time to troubleshoot that, it is greatly appreciated.