arlo icon indicating copy to clipboard operation
arlo copied to clipboard

2FA support

Open alexeyvasilyev opened this issue 4 years ago • 58 comments

Got Arlo's that said "Two-step verification is an added layer of account security to verify that it's really you, even if someone knows your password. By the end of the year, Arlo will require all users to enable two-step verification. We strongly encourage you to enable this feature now for added security"

At the moment 2FA is not working for these Arlo python scripts.

What version of Python are you using (python -V)?

Python 3.7.6

What operating system and processor architecture are you using (python -c 'import platform; print(platform.uname());')?

uname_result(system='Darwin', node='PC', release='19.3.0', version='Darwin Kernel Version 19.3.0: Thu Jan  9 20:58:23 PST 2020; root:xnu-6153.81.5~1/RELEASE_X86_64', machine='x86_64', processor='i386')

Which Python packages do you have installed (run the pip freeze or pip3 freeze command and paste output)?

arlo==1.2.33
certifi==2019.9.11
chardet==3.0.4
idna==2.8
monotonic==1.5
PySocks==1.7.1
requests==2.23.0
six==1.12.0
sseclient==0.0.22
urllib3==1.25.6
virtualenv==16.7.8

Which version of ffmpeg are you using (ffmpeg -version)?

ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
built with Apple clang version 11.0.0 (clang-1100.0.33.16)
configuration: --extra-cflags=-fno-stack-check
libavutil      56. 31.100 / 56. 31.100
libavcodec     58. 54.100 / 58. 54.100
libavformat    58. 29.100 / 58. 29.100
libavdevice    58.  8.100 / 58.  8.100
libavfilter     7. 57.100 /  7. 57.100
libswscale      5.  5.100 /  5.  5.100
libswresample   3.  5.100 /  3.  5.100

Which Arlo hardware do you have (camera types - [Arlo, Pro, Q, etc.], basestation model, etc.)?

Arlo Camera, Arlo Base Station

What did you do?

Enabled 2FA support on Arlo app (Settings - Profile - Login Settings - Two-Step Verification - Enable=true).

What did you expect to see?

python arlo-streamingvideo.py
ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
  built with Apple clang version 11.0.0 (clang-1100.0.33.16)
  configuration: --extra-cflags=-fno-stack-check
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
Input #0, rtsp, from 'rtsps://vzwow42-z1-prod.ar.arlo.com:443/vzmodulelive/5EM28975A2C12_1583845297713?egressToken=d0ca19d6_ade1_4852_aaf3_5235fe5c9266&userAgent=iOS&cameraId=5EM28975A2C12_1583845297713':
  Metadata:
    title           : 5EM28975A2C12_1583845297713
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Audio: aac (LC), 16000 Hz, mono, fltp
    Stream #0:1: Video: h264 (High), yuv420p(progressive), 1264x704, 24 fps, 100 tbr, 90k tbn, 48 tbc

What did you see instead?

$python arlo-streamingvideo.py
401 Client Error: Unauthorized for url: https://my.arlo.com/hmsweb/login/v2

Does this issue reproduce with the latest release?

Yes

alexeyvasilyev avatar Mar 10 '20 13:03 alexeyvasilyev

I don't really think there's going to be a solution to this.

jeffreydwalter avatar Mar 10 '20 16:03 jeffreydwalter

I just enrolled in 2FA and the only possible solution I see is to configured 2FA to use email, then write some code that gets the 2FA code from your email and sends it to the Arlo API. Of course, this library does not support that currently.

jeffreydwalter avatar Mar 10 '20 16:03 jeffreydwalter

This is really a very bad decision by Arlo as it will break all kind of external automation together with the Arlo cams. We really should send them many mails and comment in the forums so that they at least will either make it not mandatory or provide a kind of application passwords as it is done with other providers.

m0urs avatar Mar 10 '20 17:03 m0urs

Yep, unfortunately, that's our only recourse.

jeffreydwalter avatar Mar 10 '20 18:03 jeffreydwalter

So, let's tell them ... https://community.arlo.com/t5/Arlo/Mandatory-Two-Step-Authentication-Verification-a-Bad-Idea/m-p/1760890#M4454

m0urs avatar Mar 10 '20 20:03 m0urs

Jeffrey, I tried to play with the 2FA and Python as I do have the possibility to receive SMS with my Raspberry where my Home Automation system is running and thought, maybe I would be able to read that SMS and use it for login via Python.

The 401 error which is currently thrown is because the Login call tells us:

{'error': '1900', 'message': 'To access your account, please download our new Arlo app or disable two-step verification.', 'reason': 'Please update to the latest version of this app, or deactivate Two-Step Authentication on your account, to login on this device.'}

So for me it seems that the API calls have changed to a somehow newer version which supports both 2FA and non-2FA.

How did you get all the the information about which GET/POST requests are used by Arlo? The calls made by the web browser seems to be totally different from the requests made by the Python script.

So I am bit lost now. Maybe you can help me a bit so that I can continue playing. Thanks!

m0urs avatar Mar 12 '20 17:03 m0urs

@m0urs I use the Network tab in Chrome's developer tools. image

They have new auth endpoints, which this library isn't updated to use yet: General:

Request URL: https://ocapi-app.arlo.com/api/auth
Request Method: POST
Status Code: 200 
Remote Address: 104.18.30.98:443
Referrer Policy: no-referrer-when-downgrade

Request Headers:

:authority: ocapi-app.arlo.com
:method: POST
:path: /api/auth
:scheme: https
accept: application/json, text/plain, */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
auth-version: 2
content-length: 125
content-type: application/json; charset=UTF-8
cookie: __cfduid=XXXXXXX; __cfruid=XXXXXXX-XXX; 
dnt: 1
origin: https://my.arlo.com
referer: https://my.arlo.com/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-site
source: arloCamWeb
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36

Request Body:

{email: "[email protected]", password: "XXXXXXXXXXXX",…}
email: "[email protected]"
password: "XXXXXXXXXXXX"
language: "en"
EnvSource: "prod"

Response Headers:

access-control-allow-credentials: true
access-control-allow-origin: https://my.arlo.com
cf-cache-status: DYNAMIC
cf-ray: 572f685e38e37ada-MCI
content-encoding: gzip
content-type: application/json; charset=utf-8
date: Thu, 12 Mar 2020 17:59:12 GMT
etag: W/"25a-ic0uE7Ob0UwLOmICOdCpZMQlp4Y"
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
status: 200
strict-transport-security: max-age=15552000; includeSubDomains
vary: Origin, Accept-Encoding
x-content-type-options: nosniff
x-dns-prefetch-control: off
x-download-options: noopen
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block

Response Body:

{"meta":{"code":200},"data":{"_type":"AccessTokenV2","token":"XXXXXXX-XXXXXXX-XXXXXX-XXXXXXX-XXXXXX-XXXXXXX","userId":"XXX-XXXXXXX","authenticated":1584035951,"issued":1584035951,"expiresIn":1585331951,"mfa":false,"authCompleted":true,"type":"USER","MFA_State":"ENABLED"},"domain":"ocapi-app.arlo.com"}

jeffreydwalter avatar Mar 12 '20 18:03 jeffreydwalter

Thanks, so I was on the right way ... Guess I need to some try and error now ;-)

m0urs avatar Mar 12 '20 18:03 m0urs

After that there is a "GET https://ocapi-app.arlo.com/api/validateAccessToken?data = XXXXX' where "XXXXX' is the value from the field 'authenticated' from the request above.

This requests fails :

Request (GET https://ocapi-app.arlo.com/api/validateAccessToken?data%20=%20XXXXX) failed: {'meta': {'message': 'Access token is invalid', 'code': 400, 'error': 9022}}

I guess because I am missing the correct value for the "Authorization" header variable. It seems that this is NOT the value from 'token' (starting with "2_") which we get from the first request but something which looks totally different and starting with "Ml9":

Authorization: Ml9vaG13NnJ6SDZBOTBTbW9V......lFdzllZWdS

I have currently no idea where this value comes from or how to calculate it from other fields. Maybe it is some kind of hash of the token.

Maybe someone from the community can do also some tests here and give me a hint from where this "Authorization" header is coming.

The password for the new API is also somehow hashed (but this would not be such a big problem).

m0urs avatar Mar 13 '20 14:03 m0urs

@jeffreydwalter Are there any plans to update the library with the new endpoints? This hasn't worked for me for a while, and I'm honestly not sure where to begin with doing it myself and doing a pull request.

death2all110 avatar Mar 16 '20 19:03 death2all110

I am currently playing around with it a bit. However, I cannot promise that this will lead to a positive result ;-) - and I cannot tell you about a time frame.

m0urs avatar Mar 16 '20 21:03 m0urs

Maybe Arlo will not set 2FA mandatory as they had communicated up to now. If I understand that support chat correctly we still would be able to choose:

https://community.arlo.com/t5/Arlo/Mandatory-Two-Step-Authentication-Verification-a-Bad-Idea/m-p/1762753#M74989

However: Since 2 days I am unable to use the old authentication mechanism even without 2FA enabled with my accounts :-( I tried to re-write the code so that it is using the new API but I am not yet successful. Seems that we now also need to consider the cookies in all requests. Still trying to get it working, however it is try & error as I am not really a Python programmer ;-)

m0urs avatar Mar 22 '20 12:03 m0urs

Is there OAuth implementation support without 2FA? Looks like they've removed the v2 API ahead of requiring 2FA support.

katzenbaer avatar Mar 23 '20 02:03 katzenbaer

Is there OAuth implementation support without 2FA? Looks like they've removed the v2 API ahead of requiring 2FA support.

It seems they are now only using the new API which can be used with and without 2FA. I am currently trying to implement the new API without 2FA so that I can use my scripts again. However, as I said before, I am not a programmer and I cannot promise if I am successful ;-)

m0urs avatar Mar 23 '20 08:03 m0urs

Bad news :-(

As part of our efforts to continually evolve and further strengthen our privacy and security practices, Arlo announced it will now require all users to use two-factor authentication when logging into their Arlo account. The new security mandate will go into effect for new users in Q2 of 2020, and will require existing Arlo users to enable the feature on their current Arlo accounts by end of year. While Arlo has strongly encouraged its users to enable two-factor authentication since its introduction, Arlo believes requiring this added layer of security is yet another measure we can take to help our users safeguard their accounts and their data.

Arlo Team

m0urs avatar Mar 23 '20 17:03 m0urs

Well this really sucks, but I predicted it. I registered my displeasure on the Arlo forum. It would have been nice to get some notice. Now I am scrambling to find an alternative hardware/software solution. Thanks, everyone, for your efforts to try and work around this.

apsteinmetz avatar Mar 23 '20 20:03 apsteinmetz

well seems there are some fixes out. Hope we can use it for this lib.

https://github.com/twrecked/pyaarlo

nst2020 avatar Mar 24 '20 11:03 nst2020

@nst2020 they are just logging into your mailbox and polling for the 2FA email to get the token. That is the approach I am also planning on. Have been busy, was hoping someone in the community would take some initiative and make a PR. If not, I'll probably have time in the next week or two.

jeffreydwalter avatar Mar 24 '20 16:03 jeffreydwalter

As I said, I am currently working on changing the script to use the new API as even without 2FA it is no longer working for me for some days ... I also do have some code for 2FA in it, but currently only for playing (I need to put in the second factor manually, just to see how it works). I was planning to get the second factor via SMS as I do have another machine which can receive SMS.

Nevertheless, if you would be able to make "real" code even better ;-) Let me know before you start so maybe I can give you at least what I already have. Maybe you can re-use something ...

m0urs avatar Mar 24 '20 16:03 m0urs

I adapted the code so that it now uses the new Authentication API and added also some proof of concept code for using 2FA.

However, currently you need to put in the second factor sent by SMS manually. It needs more work now to automate that.

At least I can now use my script again 8without 2FA) as Arlo seems to have stopped authentication with the older API a few days ago.

You find my code here. Maybe you can use parts for your own.

https://github.com/m0urs/arlo-cl

m0urs avatar Mar 26 '20 11:03 m0urs

@m0urs

Thank you for this. I'm trying to implement the changes you made so I can run my download script again, and it seems to authenticate, but every time it runs it just passes 'success' and doesn't do anything else. Any chance you can help with that?


PS E:\Arlo> python .\arlo-download.py
[DEBUG] (MainThread) Starting new HTTPS connection (1): ocapi-app.arlo.com:443
[DEBUG] (MainThread) https://ocapi-app.arlo.com:443 "POST /api/auth HTTP/1.1" 200 None
'success'
PS E:\Arlo>

death2all110 avatar Mar 26 '20 15:03 death2all110

@death2all110 I can have a look if you provide me with your full script which you are using. If you like you can mail me directly as this does not really fit to the 2FA issue here ... Mail address see my Github profile.

m0urs avatar Mar 26 '20 15:03 m0urs

@m0urs Thanks a lot for your pre-work implementing the new api-endpoints! I was wondering why my scripts weren´t working with my home automation as i noticed that arlo now enters the passwods base64 and also new endpoints are targeted. I just implemented your changes and it works like a charm!!!

@death2all110 Please notice that @m0urs changed also requests.py and eventstream.py! If you are running your own scripts with Arlo.py, dont forget to encode the password.

from Arlo import Arlo

from datetime import timedelta, date
import datetime
import sys
import base64

pw = 'plainPW'
USERNAME = 'you@mail'
PASSWORD = str(base64.b64encode(pw.encode("utf-8")), "utf-8")

try:
    arlo = Arlo(USERNAME, PASSWORD)
    basestations = arlo.GetDevices('basestation')   
    modes = arlo.GetModes(basestations[0])
   

huberda avatar Mar 26 '20 22:03 huberda

@m0urs are you planning on making a PR for your changes? It would be greatly appreciated by everyone that uses the library.

jeffreydwalter avatar Mar 27 '20 00:03 jeffreydwalter

@jeffreydwalter As I did only adapt some of the functions in Arlo.py yet, I would not yet like to create a PR. I am currently working with @death2all110 who is using some more functions and will adapt my version of Arlo.py accordingly. But that will not include all functions. Do you think it make sense to merge my changes even if they are not yet complete? Maybe, because currently the whole script seems no longer work at all. What do you think?

m0urs avatar Mar 27 '20 07:03 m0urs

Thanks for updating this! Is there a lag in the package deployment becuase I don't seem to be updating?

>pip install arlo
 Requirement already satisfied: arlo in c:\users\arthur\appdata\local\programs\python\python38\lib\site-packages (1.2.33)

apsteinmetz avatar Mar 30 '20 18:03 apsteinmetz

Try upgrading: pip install arlo --upgrade

$ pip install arlo --upgrade
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Collecting arlo
  Downloading https://files.pythonhosted.org/packages/81/43/694016dcd05a02762bf05b19ed09bd22780b9f8d578cf82cd0e2c82e87ec/arlo-1.2.35-py2.py3-none-any.whl
Requirement already satisfied, skipping upgrade: requests in /usr/local/lib/python2.7/site-packages (from arlo) (2.22.0)
Requirement already satisfied, skipping upgrade: PySocks in /usr/local/lib/python2.7/site-packages (from arlo) (1.7.1)
Requirement already satisfied, skipping upgrade: monotonic in /usr/local/lib/python2.7/site-packages (from arlo) (1.5)
Requirement already satisfied, skipping upgrade: sseclient==0.0.22 in /usr/local/lib/python2.7/site-packages (from arlo) (0.0.22)
Requirement already satisfied, skipping upgrade: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python2.7/site-packages (from requests->arlo) (1.25.6)
Requirement already satisfied, skipping upgrade: certifi>=2017.4.17 in /usr/local/lib/python2.7/site-packages (from requests->arlo) (2019.9.11)
Requirement already satisfied, skipping upgrade: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python2.7/site-packages (from requests->arlo) (3.0.4)
Requirement already satisfied, skipping upgrade: idna<2.9,>=2.5 in /usr/local/lib/python2.7/site-packages (from requests->arlo) (2.8)
Requirement already satisfied, skipping upgrade: six in /usr/local/lib/python2.7/site-packages (from sseclient==0.0.22->arlo) (1.12.0)
Installing collected packages: arlo
  Found existing installation: arlo 1.2.30
    Uninstalling arlo-1.2.30:
      Successfully uninstalled arlo-1.2.30
Successfully installed arlo-1.2.35

jeffreydwalter avatar Mar 30 '20 19:03 jeffreydwalter

thx Jeff for updating this! works like a charm!!!. not sure but seems also to be faster now.

cheers. one beer for u

nst2020 avatar Mar 30 '20 19:03 nst2020

Woo hoo! back in business. Thanks so much!

apsteinmetz avatar Mar 30 '20 20:03 apsteinmetz

In regards to MFA, I think there is a solution possible without a script requiring access to your mailbox. From what I can tell only push notifications and SMS messages are options (could be wrong). I did a quick test with SMS going to a Google Voice number and got the message. I have Google Voice set up to forward to my email (I think the only option for email address is the one associated with your Google Voice account).

I could envision a simple little AWS Lambda/SES/Dynamo/S3/API Gateway system that could help with parsing out the MFA code. Perhaps it could even be a "service" that others could use. The process would be Arlo MFA -> SMS Google Voice -> your email inbox -> autoforward rule set up to forward Arlo MFA messages to an email address behind AWS SES -> Lambda parses out the MFA code and stores in S3 -> Arlo python script queries S3 for the code. I would need to work out the details but this seems quite possible.

While folks could roll their own implementation of this, I think it may make more sense as a service being offered. I could build a prototype and host it - i can't imagine this would cost more than $1-$2 a month at most. Of course it would be best effort and no guarantee of up time.

The Arlo python script would (still thinking through the details) make a call to this service and pass in the email address the email will be forwarded from (likely SHA256 of the email so the service doesnt have to store plaintext emails) and a UUID. The return would be a presigned S3 URL (good for 1-2 minutes). The S3 object key would be in the form of <SHA256 of email>-<UUID> so the object is unique to the caller. And the object would be deleted after a short period of time as well.

Then the script performs authentication to Arlo as normal and the MFA process is kicked off, resulting in an email being sent to this service (via the Google Voice process noted above). Then the service performs SHA256 on the sender email address, finds the associated UUID, parses out the MFA, and saves the code to the S3 object.

As that is happening the python script polls every 1-2 seconds checking if the code has made it into the S3 object. Once the code is available it makes the Arlo API call with the code to advance the authentication.

Still thinking through all the details of course.

If there is interest in the community, I can try to prototype this out.

twratl avatar Apr 04 '20 17:04 twratl