foxt / icloud.js

Library for accessing iCloud in Node.js
https://npmjs.com/icloudjs
MIT License
53 stars 5 forks source link

iCloud Advanced Data Protection (PCS) #4

Open foxt opened 1 year ago

foxt commented 1 year ago

Currently, trying to access iCloud Drive data while having ADP enabled returns

Error: Missing PCS cookies from the request

Looking at the cookies in a web browser, it seems the X-APPLE-WEBAUTH-PCS-Sharing and X-APPLE-WEBAUTH-PCS-Documents are related

Not sure exactly what PCS stands for, possibly Private/Protected Cloud Service?

The iCloud web app sends an empty post request to https://setup.icloud.com/setup/ws/1/requestWebAccessState?clientBuildNumber=2306Hotfix38&clientMasteringNumber=2306Hotfix38&clientId=0a6768e7-9914-416d-9fd2-51b095985663&dsid=12024116479 to check if the user has consented to

ADP disabled:

{"dsid":8363351371,"isWebAccessAllowed":true}

ADP enabled:

{"dsid":12024116479,"isWebAccessAllowed":true,"isDeviceConsentedForPCS":false,"isICDRSDisabled":true,"deviceConsentForPCSExpiry":0}

(ICDRS possibly meaning iCloud Data Recovery Service)

If PCS consent is not granted, iCloud website sends a POST request to https://setup.icloud.com/setup/ws/1/enableDeviceConsentForPCS?clientBuildNumber=2306Hotfix38&clientMasteringNumber=2306Hotfix38&clientId=0a6768e7-9914-416d-9fd2-51b095985663&dsid=12024116479 (with no body), to which the following response is sent

{"isDeviceConsentNotificationSent":true,"isWebAccessAllowed":true,"isDeviceConsentedForPCS":false,"isICDRSDisabled":true,"deviceConsentForPCSExpiry":0}

and a notification is sent to the users iPhone.

The URL https://setup.icloud.com/setup/ws/1/requestWebAccessState?clientBuildNumber=2306Hotfix38&clientMasteringNumber=2306Hotfix38&clientId=0a6768e7-9914-416d-9fd2-51b095985663&dsid=12024116479 is polled with an empty POST.

No consent yet:

{"dsid":12024116479,"isWebAccessAllowed":true,"isDeviceConsentedForPCS":false,"isICDRSDisabled":true,"deviceConsentForPCSExpiry":0}

Consent granted:

{"dsid":12024116479,"isWebAccessAllowed":true,"isDeviceConsentedForPCS":true,"isICDRSDisabled":true,"deviceConsentForPCSExpiry":1674401748101}

The expiry period seems to be 1 hour

When accessing an ADP service, iCloud website, if it knows PCS consent is granted, sends a POST request to https://setup.icloud.com/setup/ws/1/requestPCS?clientBuildNumber=2306Hotfix38&clientMasteringNumber=2306Hotfix38&clientId=4c1e9a0b-7cba-4c27-a9e3-c6f020fd416e&dsid=12024116479 with {"appName":"iclouddrive","derivedFromUserAction":true} to ensure that PCS cookies are present.

If PCS cookies sent with the request are not valid, but consent is already provided, the following is sent as JSON along with the cookies required

{"isWebAccessAllowed":true,"isDeviceConsentedForPCS":true,"isICDRSDisabled":true,"message":"Cookies attached.","deviceConsentForPCSExpiry":1674400678814,"status":"success"}

If PCS cookies sent with the request is valid, the following is sent

{"isWebAccessAllowed":true,"isDeviceConsentedForPCS":true,"isICDRSDisabled":true,"message":"Cookies already present.","deviceConsentForPCSExpiry":1674400678814,"status":"success"}
foxt commented 1 year ago

working

image

foxt commented 1 year ago

improved in 0a00153, needs testing

steilerDev commented 1 year ago

Hey @foxt - great analysis (and btw thank you for the shoutout to my project in your readme!)

Unfortunately I don't have access to an ADP account and trying to implement support for it. Is the first part of the process (granting consent) necessary every time you access the API - or is consent granted once and is valid for a longer period?

If this needs to happen every time you access the API this would be bad :/

(I'm hoping I only need to implement the extra step to acquire the PCS cookies - not the rest)

MaxNeedsSnacks commented 1 year ago

If I may bump in real quick: From the last time I tried to work on something iCloud related a couple of weeks ago (I was planning on writing a simple driver for linux for myself), I think I remember the PCS cookie being retained for... about an hour? I'm happy to test around with it a bit more if you need me to, since I quit before making all too much progress last time because Bun (and later just node.js as well) were being a bit of a pain in the ass about this library for some reason 🙃

foxt commented 1 year ago

@steilerDev - As @MaxNeedsSnacks said, I don't think the PCS cookies are valid for long (I can't remember, and turned off ADP on my Apple ID) before you have to re-acquire consent from the user, this is probably as this type of access was designed just so you could look at your photos on iCloud.com rather than actual long term access.

MaxNeedsSnacks commented 1 year ago

To be honest, for my use case, an hour is plenty since I'm mostly planning to put my Obsidian notes in iCloud and those will only need to be updated from remote occasionally, but yeah, it'd be a bit of a hassle to reapprove manually each time ^^;

Also found this regarding my one hour figure Seems to be pretty spot on actually!

steilerDev commented 1 year ago

Thanks for your feedback - implemented basic 'support' - not sure if I understand it correctly though - someone with ADP enabled needs to test it I guess :D

bokket commented 9 months ago

Hi, I didn't start PCS protection, but I seemed to use APIfrequently to test behavior,The result is also Error: Missing PCS cookies from the request.It is also prohibited from all functions related to iCloud on the web. It seems that I have been banned by Appleserver? Or is it temporarily blocked due to excessive access frequency? But the other functions of the phone are good.

steilerDev commented 9 months ago

@bokket I've ran into this when debugging - this is an api rate limit you should be good again in a couple of hours ;)

bokket commented 9 months ago

@bokket I've ran into this when debugging - this is an api rate limit you should be good again in a couple of hours ;)

Thanks!I almost call for asking local service Apple support