WWW.DUMAIS.IO
ARTICLES
OVERLAY NETWORKS WITH MY SDN CONTROLLERSIMPLE LEARNING SWITCH WITH OPENFLOWINSTALLING KUBERNETES MANUALLYWRITING A HYPERVISOR WITH INTEL VT-X CREATING YOUR OWN LINUX CONTAINERSVIRTIO DRIVER IMPLEMENTATIONNETWORKING IN MY OSESP8266 BASED IRRIGATION CONTROLLERLED STRIP CONTROLLER USING ESP8266.OPENVSWITCH ON SLACKWARESHA256 ASSEMBLY IMPLEMENTATIONPROCESS CONTEXT ID AND THE TLBTHREAD MANAGEMENT IN MY HOBBY OSENABLING MULTI-PROCESSORS IN MY HOBBY OSNEW HOME AUTOMATION SYSTEMINSTALLING AND USING DOCKER ON SLACKWARESYSTEM ON A CHIP EMULATORUSING JSSIP AND ASTERISK TO MAKE A WEBPHONEC++ WEBSOCKET SERVERSIP ATTACK BANNINGBLOCK CACHING AND WRITEBACKBEAGLEBONE BLACK BARE METAL DEVELOPEMENTARM BARE METAL DEVELOPMENTUSING EPOLLMEMORY PAGINGIMPLEMENTING HTTP DIGEST AUTHENTICATIONSTACK FRAME AND THE RED ZONE (X86_64)AVX/SSE AND CONTEXT SWITCHINGHOW TO ANSWER A QUESTION THE SMART WAY.REALTEK 8139 NETWORK CARD DRIVERREST INTERFACE ENGINECISCO 1760 AS AN FXS GATEWAYHOME AUTOMATION SYSTEMEZFLORA IRRIGATION SYSTEMSUMP PUMP MONITORINGBUILDING A HOSTED MAILSERVER SERVICEI AM NOW HOSTING MY OWN DNS AND MAIL SERVERS ON AMAZON EC2DEPLOYING A LAYER3 SWITCH ON MY NETWORKACD SERVER WITH RESIPROCATEC++ JSON LIBRARYIMPLEMENTING YOUR OWN MUTEX WITH CMPXCHGWAKEUPCALL SERVER USING RESIPROCATEFFT ON AMD64CLONING A HARD DRIVECONFIGURING AND USING KVM-QEMUUSING COUCHDBINSTALLING COUCHDB ON SLACKWARENGW100 MY OS AND EDXS/LSENGW100 - MY OSASTERISK FILTER APPLICATIONCISCO ROUTER CONFIGURATIONAASTRA 411 XML APPLICATIONSPA941 PHONEBOOKSPEEDTOUCH 780 DOCUMENTATIONAASTRA CONTACT LIST XML APPLICATIONAVR32 OS FOR NGW100ASTERISK SOUND INJECTION APPLICATIONNGW100 - DIFFERENT PROBLEMS AND SOLUTIONSAASTRA PRIME RATE XML APPLICATIONSPEEDTOUCH 780 CONFIGURATIONUSING COUCHDB WITH PHPAVR32 ASSEMBLY TIPAP7000 AND NGW100 ARCHITECTUREAASTRA WEATHER XML APPLICATIONNGW100 - GETTING STARTEDAASTRA ALI XML APPLICATION

IMPLEMENTING HTTP DIGEST AUTHENTICATION

2014-08-15

Recently, I was trying to add HTTP digest authentication on my Home automation device. The device exposes a REST interface trough a proxy server. My web server is setup like this

Now since my API is exposed to the world by proxying it like that, I wanted to add security by implementing HTTP digest authentication. Whether or not Digest authentication with MD5 is secure or not is a completely different story, but let's assume it is good enough for now. I have a restricted access webpage that I go on to control my home automation device. This web page makes requests to DHAS using javascript. Since I've implemented digest authentication, I now need to put the credentials in the javascript so that the calls made with XMLHttpRequest can succeed. Even though that javascript code will only be served to me, while I am authenticated on the website, I felt uncomfortable to leave a hardcoded username and password in the JS source. So this is what I came up with:

Note that messages sent from JS to DHAS are being proxied by Apache. Therefore, DHAS receives a GET for /insteon/listmodules and not for /dhas/insteon/listmodules

  • use XMLHttpRequest to make a request to DHAS (through the proxy)
  • add a header "X-NeedAuthenticationHack" in the request
  • receive a 401
  • get the "X-WWW-Authenticate" header from the 401 response
  • Make a XMLHttpRequest to the server and send it the "X-WWW-Authenticate" data
  • Server side php script with hardcoded username/password for DHAS solves the challenge and returns the resonse
  • use XMLHttpRequest to make a request to DHAS (through the proxy) and append the response in a "Authorization" header

So basically, I just intercepted the 401 and instead of letting the browser prompt for a username password, I created the response myself. And instead of doing in the JS, I did it on the server, limiting the exposition of the username/password. You may notice my two special X headers. This is because if the server returns a 401 with WWW-Authenticate, the browser will prompt for your credentials. Event if I have a handler defined to get the 401. So when I send my initial request, I set the X-NeedAuthenticationHack header to tell the server: "Hey, don't send me a WWW-Authenticate, send a X-WWW-Authenticate instead so I can deal with it".

By the way, even if the information is easy to find, this is how the digest authentication is done:

  • Client makes request to http://webserver.com/url1/index.html
  • Server sends a "WWW-Authenticate: realm="testrealm", nonce="testnonce"
  • ha1 = md5("username:testrealm:password")
  • ha2 = md5("GET:/url1/index.html")
  • ha3 = md5(ha1+":testnonce:"+ha2)
  • Client sends: "Authorization: Digest username="username", realm="testrealm", nonce="testnonce", response=""+ha3+"", uri="/url1/index.html"