So you can randomise the ID in the request packet to help protect against cache poisoning. And also so you can apply 0x20 bit (x) encoding to the qname for further protection.
the c-ares init (which reads /dev/urandom) inside curl init happens even when DNS isn't used at all (even when making a request to 127.0.0.1), so it's pretty hard to avoid as long as curl is built with c-ares. The only way to mitigate is to remove c-ares or limit calls to curl init.
Ah... I've worked a lot w/ libcurl, and a bit w/ c-ares, but don't fully know how c-ares works w/i curl. Thanks for the rundown.
Re: "limit calls to curl init" -- do you mean curl_easy_init() ? In that case, reusing handles (eg:
CURL *handle
) would mitigate that, no?
Edit: This doesn't make sense. c-ares relationship must be in curl_easy_perform(). Now I'm curious:
1) Am I correct re: c-ares / curl_easy_perform()
2) Can one reuse CURL *handle and not invoke c-ares and /dev/urandom if one reuses the same domain name (but not necessarily the same URL) within a handle.
"If you did not already call curl_global_init(3), curl_easy_init(3) does it automatically. This may be lethal in multi-threaded cases, since curl_global_init(3) is not thread-safe, and it may result in resource problems because there is no corresponding cleanup."
I can imagine that only curl_global_init reads from urandom? Your application should do curl_global_init only once, then do other fetches each time using just curl_easy_init and cleanup.
We're using libcurl via PHP (I know, I know) which doesn't expose curl_global_init at all.
Here's the stacktrace for the /dev/urandom read -- it's happening in curl_easy_init.
Catchpoint 1 (call to syscall 'ioctl'), 0x0000003a74ecc4ba in tcgetattr () from /lib64/libc.so.6
(gdb) backtrace
#0 0x0000003a74ecc4ba in tcgetattr () from /lib64/libc.so.6
#1 0x0000003a74ec7a1c in isatty () from /lib64/libc.so.6
#2 0x0000003a74e60d51 in _IO_file_doallocate_internal () from /lib64/libc.so.6
#3 0x0000003a74e6d6dc in _IO_doallocbuf_internal () from /lib64/libc.so.6
#4 0x0000003a74e6ba7c in _IO_file_xsgetn_internal () from /lib64/libc.so.6
#5 0x0000003a74e61dd2 in fread () from /lib64/libc.so.6
#6 0x0000003341606414 in ares_init_options () from /usr/lib64/libcares.so.2
#7 0x0000003d3404f0c9 in ?? () from /usr/lib64/libcurl.so.4
#8 0x0000003d340242a5 in ?? () from /usr/lib64/libcurl.so.4
#9 0x0000003d3402f9a6 in curl_easy_init () from /usr/lib64/libcurl.so.4
#10 0x00002b35e0304fb0 in ?? () from /usr/lib64/php/modules/curl.so
#11 0x0000000000606da9 in ?? ()
#12 0x00000000006456b8 in execute_ex ()
#13 0x00000000005d2bba in zend_execute_scripts ()
#14 0x00000000005769ee in php_execute_script ()
#15 0x000000000067e44d in ?? ()
#16 0x000000000067ede8 in ?? ()
#17 0x0000003a74e1d994 in __libc_start_main () from /lib64/libc.so.6
#18 0x0000000000422b09 in _start ()
(gdb)
I just guess, but maybe the things missing in the stack trace (marked with ?? -- maybe you miss some debug symbols?) do what is described in the manual entry I've quoted (calling global init which calls ares?).
And why curl at all? PHP has built in HTTPRequest?
curl_global_init() really ought to be called on module load, before any (eg) set handle = curl::new is presented to a module user. And ea. curl::new call out to curl_easy_init(), will bypass global init again w/ this first line of code:
(x) http://courses.isi.jhu.edu/netsec/papers/increased_dns_resis...