venth/aws-adfs

Failed response from Duo

mrichnu opened this issue ยท 7 comments

Hello, using aws-adfs v 2.5.1 and testing the Duo universal prompt integration with AD FS (we have been using the traditional prompt for years with no issues, but the traditional prompt will be retired in March 2024).

Currently receiving responses from Duo that look like this:

$ aws-adfs login --adfs-host <adfs host> --duo-factor "Duo Push" --duo-device "phone1"
Sending request for authentication
Waiting for additional authentication
Triggering authentication method: 'Duo Push' with 'phone1'
Error: Cannot begin authentication process. The error response: {"stat": "FAIL", "message_enum": 7, "data": {}}

This authentication flow works fine in the browser, just isn't working with aws-adfs. Below is the final section of output from aws-adfs -v login and it looks nearly the same to me as when I watch the traffic using the browser's developer tools. I can provide more output from aws-adfs -v login if that's helpful:

Waiting for additional authentication
Triggering authentication method: 'Duo Push' with 'phone1'
send: b'POST /frame/v4/prompt HTTP/1.1\r\nHost: api-XXXXXXXX.duosecurity.com\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko\r\nAccept-Encoding: gzip, deflate\r\nAccept: text/plain, */*; q=0.01\r\nConnection: keep-alive\r\nAccept-Language: en\r\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\r\nCookie: _xsrf|509b3cce-d3f1-415a-a22d-cd6a98e5e7e6="MDM0NDQ2MDEwNGEwNDg3N2JjMzk3NDg2NzU1Njc1MTI=|165.124.167.3|1666717183|4fc9d6f53cf6b608ab7cc86651cc973d0a8d9a42"; sid|509b3cce-d3f1-415a-a22d-cd6a98e5e7e6="YWVjMjFmMTkxODE0NGFmYzk4ZTE2YzU4ZjYwMWU4ZTU=|165.124.167.3|1666717183|fa514621409e3279c9f5a512e7b6f60c72e70aa0"\r\nContent-Length: 80\r\n\r\n'
send: b'sid=frameless-509b3cce-d3f1-415a-a22d-cd6a98e5e7e6&factor=Duo+Push&device=phone1'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: Duo/1.0
header: Date: Tue, 25 Oct 2022 16:59:43 GMT
header: Content-Type: application/json
header: Content-Length: 47
header: Connection: keep-alive
header: Set-Cookie: sid|509b3cce-d3f1-415a-a22d-cd6a98e5e7e6=""; expires=Mon, 25 Oct 2021 16:59:43 GMT; Path=/
header: Strict-Transport-Security: max-age=31536000
header: Content-Security-Policy: default-src 'self'; frame-src 'self' ; img-src 'self'  ; connect-src 'self'
2022-10-25 11:59:43,781 [connectionpool connectionpool.py:_make_request] [17787-MainProcess] [140085502093120-MainThread] - DEBUG: https://api-XXXXXXXX.duosecurity.com:443 "POST /frame/v4/prompt HTTP/1.1" 200 47
2022-10-25 11:59:43,782 [helpers helpers.py:trace_http_request] [17787-MainProcess] [140085502093120-MainThread] - DEBUG: ================================================================================
Request:
* url: https://api-XXXXXXXX.duosecurity.com/frame/v4/prompt
* headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko', 'Accept-Encoding': 'gzip, deflate', 'Accept': 'text/plain, */*; q=0.01', 'Connection': 'keep-alive', 'Accept-Language': 'en', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Cookie': '_xsrf|509b3cce-d3f1-415a-a22d-cd6a98e5e7e6="MDM0NDQ2MDEwNGEwNDg3N2JjMzk3NDg2NzU1Njc1MTI=|165.124.167.3|1666717183|4fc9d6f53cf6b608ab7cc86651cc973d0a8d9a42"; sid|509b3cce-d3f1-415a-a22d-cd6a98e5e7e6="YWVjMjFmMTkxODE0NGFmYzk4ZTE2YzU4ZjYwMWU4ZTU=|165.124.167.3|1666717183|fa514621409e3279c9f5a512e7b6f60c72e70aa0"', 'Content-Length': '80'}
* body: sid=frameless-509b3cce-d3f1-415a-a22d-cd6a98e5e7e6&factor=Duo+Push&device=phone1
================================================================================
Response:
* status: 200
* headers: {'Server': 'Duo/1.0', 'Date': 'Tue, 25 Oct 2022 16:59:43 GMT', 'Content-Type': 'application/json', 'Content-Length': '47', 'Connection': 'keep-alive', 'Set-Cookie': 'sid|509b3cce-d3f1-415a-a22d-cd6a98e5e7e6=""; expires=Mon, 25 Oct 2021 16:59:43 GMT; Path=/', 'Strict-Transport-Security': 'max-age=31536000', 'Content-Security-Policy': "default-src 'self'; frame-src 'self' ; img-src 'self'  ; connect-src 'self'    "}
* body: {"stat": "FAIL", "message_enum": 7, "data": {}}

Hi, that's weird. You should rather get something like this:

Waiting for additional authentication
Triggering authentication method: 'Duo Push' with 'phone1'
send: b'POST /frame/v4/prompt HTTP/1.1\r\nHost: api-******.duosecurity.com\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko\r\nAccept-Encoding: gzip, deflate\r\nAccept: text/plain, */*; q=0.01\r\nConnection: keep-alive\r\nAccept-Language: en\r\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\r\nCookie: _xsrf|******="******=|******|1666793219|******"; sid|******="******=|******|1666793219|******"; trc|******|******=******\r\nContent-Length: 80\r\n\r\n'
send: b'sid=frameless-******&factor=Duo+Push&device=phone1'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: Duo/1.0
header: Date: Wed, 26 Oct 2022 14:06:59 GMT
header: Content-Type: application/json
header: Content-Length: 76
header: Connection: keep-alive
header: Strict-Transport-Security: max-age=31536000
header: Content-Security-Policy: default-src 'self'; frame-src 'self' ; img-src 'self'  ; connect-src 'self'
2022-10-26 16:06:59,819 [connectionpool connectionpool.py:_make_request] [51651-MainProcess] [139969757044736-MainThread] - DEBUG: https://api-******.duosecurity.com:443 "POST /frame/v4/prompt HTTP/1.1" 200 76
2022-10-26 16:06:59,820 [helpers helpers.py:trace_http_request] [51651-MainProcess] [139969757044736-MainThread] - DEBUG: ================================================================================
Request:
* url: https://api-******.duosecurity.com/frame/v4/prompt
* headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko', 'Accept-Encoding': 'gzip, deflate', 'Accept': 'text/plain, */*; q=0.01', 'Connection': 'keep-alive', 'Accept-Language': 'en', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Cookie': '_xsrf|******="******=|******|1666793219|******"; sid|******="******=|******|1666793219|******"; trc|******|******=******', 'Content-Length': '80'}
* body: sid=frameless-******&factor=Duo+Push&device=phone1
================================================================================
Response:
* status: 200
* headers: {'Server': 'Duo/1.0', 'Date': 'Wed, 26 Oct 2022 14:06:59 GMT', 'Content-Type': 'application/json', 'Content-Length': '76', 'Connection': 'keep-alive', 'Strict-Transport-Security': 'max-age=31536000', 'Content-Security-Policy': "default-src 'self'; frame-src 'self' ; img-src 'self'  ; connect-src 'self'    "}
* body: {"stat": "OK", "response": {"txid": "******"}}
================================================================================

According to Duo web UI source code, message_enum value 7 translates to AUTH_ACCESS_DENIED:

image

I noticed that aws-adfs is not sending two cookies in the POST request to /frame/v4/prompt, namely the sid and trc| cookies (both set a sid|<random looking string> cookie, but the browser is sending an additional sid cookie). Here's an example of the browser's request cookie header:

sid|5c16c5bd-059e-4182-97c1-960f18dc242a="ZDE5NzZkNGEzNjVhNGJlNTliZmM4ZGQ1OGQzNDdhZGY=|<my ip addr>|1666798570|125b30b3f5150964489789cb4ed0be7a856f17ad"; _xsrf|5c16c5bd-059e-4182-97c1-960f18dc242a="ZDI5M2M5ZmI1YWFjNGZiZWJlNmJmZGI3OTRlNGMwN2Q=|<my ip addr>|1666798570|cec7866a40873c964dd2e68d1a2cb7c77cc251bf"; sid="MWEyMzBmNThmY2RiNDc3MjljM2Q4NTA4YjE2ODY2Yzc=|<my ip addr>|1666798574|38f0c2db6cd6d8b6dcefc8ac5592e199655f93be"; trc|DUBX0UB6L9X2RF61DRKP|DA023DPT3ER6DUZANEH1=EPF24AFOOUW0XRQGC6OK

Additionally the following request headers are all being sent by the (successful) browser request but are missing from the aws-adfs request to the Duo endpoint:

Referer:
X-Xsrftoken:
Origin:
DNT:
Sec-Fetch-Dest:
Sec-Fetch-Mode:
Sec-Fetch-Site:

I wonder if it could be one of those missing headers causing the issue?

The sid and trc cookies are there in my log extract.
You do have an additional sid set by:

header: Set-Cookie: sid|509b3cce-d3f1-415a-a22d-cd6a98e5e7e6=""; expires=Mon, 25 Oct 2021 16:59:43 GMT; Path=/

Maybe try deleting your ~/.aws/adfs_cookies_* files.

Thanks for replying! I did already try deleting all adfs_cookies files, no change.

Our organization is experiencing the exact same issue as described by @mrichnu after our identity team updated the DUO connector for ADFS. Browser authentication works normally but via aws-adfs we receive the following error during the step where MFA prompts are requested:
Error: Cannot begin authentication process. The error response: {"stat": "FAIL", "message_enum": 7, "data": {}}

We can also confirm that the request to the DUO API is missing fields we do see within browser auth:

Referer:
X-Xsrftoken:
Origin:
DNT:
Sec-Fetch-Dest:
Sec-Fetch-Mode:
Sec-Fetch-Site:
pdecat commented

Hi, we started to face a similar issue.

Patching the User-Agent string to specify Linux instead of Windows works it around, but it will probably breaks some Windows features like SSPI/Kerberos.

pdecat commented

Resolved by #378