Category Archives: Uncategorized

Do you have it ? Really ?

What we are looking for the the probability of a person having Corona given a positive test and the test is 90% accurate.

For brevity:

A = have Corona
B = have positive test

P(A) = 0,01 – base rate of contagion in the population. And by implication P(not-A) = 0,99

Test is 90% accurate, and let us further suppose that this is both the sensitivity and the specificity. Where sensitivity is about the absence of false negatives – are you finding it all ? – the proportion of actual positives that are correctly identified as such. And Specificity is about the absence of false positives – are you detecting something else ? – the proportion of actual negatives that are correctly identified as such. Ideally both should be high, but typically one will have to be traded off against the other in any real test. Both being 90% is unrealisitc.

For short P(B|A) = 0.9 and P(not-B | not-A) = 0.9

From this we use the fact that conditional probabilities add up to 1

i.e. P ( B|A ) + P(not-B|A) = 1

and get P(not-B | A) = 0.1 and P( B | not-A) = 0.1

Bayes’ Theorem stipulate P(A|B) = P(B|A) * P(A) / P(B)

Where P(B) = P(B,A) + P(B,not-A) = P(B|A) * P(A) + P(B | not-A) * P(not-A)

Putting in the numbers from above:

P(A|B) = ( 0,9 * 0,01) / ( 0,9 * 0,01 + 0,1 * 0,99) = 0,009 / ( 0,009 + 0,099) ~ 10%

In plan language: The probability of actually having the Corona given a positive test with a 90% accuracy, is only about 10%

 

Let’s recast: what is the chance of not having Corona given the test say you don’t. In other words: how reliable is the all-clear ?


For brevity: What is P ( not-A | not-B) ?

Bayes’ says P(A|B) = P(B|A) * P(A) / P(B)

which for this purpose becomes:

P(not-A| not-B) = P(not-B| not-A) * P(not-A) / P(not-B)

Where P(not-B) = P(not-B, not-A) + P(not-B, A) = P(not-B| not-A) * P(not-A) + P(not-B | A) * P(A)


All of these numbers we have


P(not-A| not-B) = 0,9 * 0,99 / ( 0,9 * 0,99 + 0,1 * 0,01 ) ~ 99,9%


Which is rather impressive. The all-clear really is all-clear. No means no.

Business and reuptational damage from shoddy security pratices at subcontractors. (Norwegian)

I en tid har jeg hatt Telenor Bedrift som mobil leverandør. Men nå har jeg sluttet med det.

Grunnet en heller uklar fakturerings model ble noen av fakturaene fra Telenor avvist for å overstige beløps grensen. Og gikk videre til inkasso. So far, so good. Her ble det interessant. Inkasso firmaet var for meg en helt ukjent firma, Gothia Group, GG. Som sendte en epost med henstilling å betale til KTO nr og KID nummer. De hevdet å agere på vegne av Telenor (merk: ikke «Telenor Bedrift», som jeg har mitt kundeforhold hos). Gitt at en betydelig andel av Norges befolkning har et kunde forhold til Telenor er en slik generisk påstand en ganske god start på et masse-phishing angrep.

Eposten inneholdt heller lite (intet) som forutsatte detaljert kjennskap til kunde forholdet hos Telenor: Ikke opprinnelig faktura nummer eller kunde nummer. Dette ble senere fulgt opp med en oppringning som likeledes var blottet for spesifikk informasjon. Stemmen på telefonen hadde ikke noen tydelig russisk aksent men ellers kunne alt sammen vært generert i en russisk hacker fabrikk. Men gitt av en del call-senter oppgaver er flyttet ut av landet, er ikke en aksent umiddelbart mistenkelig heller. Mangel på spesifikk informasjon derimot er det.

Etter å ha sjekket opp mailen med Telenor gikk jeg inn på den i eposten oppgitte nettsiden.

Starten var mindre enn tillitts vekkedne. GG sine nettsider har ikke sine digitale sertifikater satt opp på en måte som må anses som minste kravet til en virksomhet som driver med penger.

Spesifikt: de benytter Let’s Encrypt Authority X3 som CA for sertifikatet på www.gothiagroup.com. Dette er IKKE en forsvarlig utsteder av digital sertifikater for formålet å identifisere organisasjoners nettsteder. Noe Let’s Encrypt selv heller ikke påstår.

Om penger er involvert er det ikke urimelig at organisasjonen bak nettstedet faktisk identifiserer seg overfor brukerens nettleser.

Men i det minste følger GG godpraksis i at kunden må logg seg inn for å finne korrekt betalings informasjon: En epost kan som kjent komme fra hvor som helst. Den sikkre informasjonen er den kunden selv finner frem til.

Men dette gjelder ikke for Telenor Bedrifts kunder. Den eneste innloggings mekanismen GG har er BankID. Og det virker som de ikke har noen integrasjon som gjøre at de kan koble den personlige innloggingen i BankID med en organisasjon. Så bedrifts kunder kan ikke logge seg inn hos GG for å hente betalings detaljer. De må få dette på epost, etter oppfordring. Eposter som ikke inneholder noen informasjon som kobler kravet til opprinnelig faktura fra Telenor Bedrift. Intet i den er hentet fra Telenor eller er av en slik art at ikke hvem som helst vet det. En russisk «troll farm» ville kunne sendt den eksakt samme eposten.

Så Telenor benytter Gothia Group som ikke kan håndtere bedrifts kunder, for sine bedrifts kunder.

Jeg er ikke lengre en kunde av Telenor Bedrift.

federated rigamarole (dual Norwegian and English)

Hvor mange nettsteder er man innom dersom man logger seg inn på NAV med BankId. Er det fler enn 10 ?
Det rette antallet er faktisk 14, spred over 7 domener. I disse GDPR tider kan det være instruktivt å se hvem som følger med på deg når du logger inn på NAV.

Gå til https :// www . nav . no/ og slå på Web Console før du starter med inloggingen , så får du se. Jeg gjorde dette, lagret resultatet til en HAR-fil og gjorde noen enkle uttrekk fra denne.

egrep “\”url\”:” HAR-file | sed ‘s/.*”url”: “htt[^\/]*\/\///’ | sed ‘s/\/.*//’ | sed ‘s/.*\.\([^\.]*\.[^\.]*\)$/\1/’ | sort | uniq -c | sort -r

61 nav.no
55 difi.no
14 bankid.no
5 psplugin.com
2 taskanalytics.com
2 microsoftonline.com
2 googletagmanager.com

We’re definitely at nav.no, with a total of 61 calls there. Bankid.no is as expected; And difi.no is no surprice as the government federation gateway (55 calls).
Men så blir det interessant. De 3 nederste på listen er noe overaskende. Når det det nødvendig å koble in Microsoft for en pålogging til NAV ?
Det er heller ikke åpenbart at Google trenger å vite når noen innom NAV. Selv om det nok er kunder av Google Analytics som gjerne kunne tenke seg å vite det.

But who are making these quiestioanable calls ?
Going back to the HAR-file.

egrep -v “text\”:” HAR-file | tr -d “\n” | sed ‘s/”url”:/\n “url\”:/g’ | sed ‘s/ */ /g’ | egrep “Referer” | sed ‘s/”url”: “\([^\”]*\)”.*{ “name”: “Referer”, “value”: “\([^\”]*\).*/\2 \1 /g’ | sed ‘s/ [^/]*:\/\/\([^/]*\)\/[^ ]* [^/]*:\/\/\([^/]*\)\/[^ ]*/\1 \2/’ | sort | uniq

appres.nav.no appres.nav.no
csfe.bankid.no csfe.bankid.no
csfe.bankid.no idporten.difi.no
idporten.difi.no csfe.bankid.no
idporten.difi.no idporten.difi.no
idporten.difi.no oidc.difi.no
oidc.difi.no login.microsoftonline.com
oidc.difi.no loginservice.nav.no
oidc.difi.no http://www.nav.no
http://www.nav.no account.psplugin.com
http://www.nav.no appres.nav.no
http://www.nav.no eumgw.nav.no
http://www.nav.no idporten.difi.no
http://www.nav.no in.taskanalytics.com
http://www.nav.no jsagent.nav.no
http://www.nav.no login.microsoftonline.com
http://www.nav.no loginservice.nav.no
http://www.nav.no nav.psplugin.com
http://www.nav.no oidc.difi.no
http://www.nav.no tjenester.nav.no
http://www.nav.no http://www.googletagmanager.com
http://www.nav.no http://www.nav.no

The culprit is NAV itself. It is their web application which is making calls to Google.
The calls to psplugin.com, taskanalytics.com and googletagmanager.com are all only from NAV

The microsoft call is made by Difi too. So let’s look at that first.

The following command extracts the domain call and redirect sequence. (HTTP 302 redirects)

egrep -v “text\”:” HAR-file | tr -d “\n” | sed ‘s/”url”:/\n “url\”:/g’ | sed ‘s/ */ /g’ | egrep “\”status\”: 302″ | sed ‘s/\(\”url\”: \”[^\”]*\”\).*\”Location\”, \”value\”: \(\”[^\”]*\).*/\n\n\n\1\n\n\”Location\”: \2/’

Showing the url being called and the URL being redirected too (the Location HTTP header sent back to the browser from the site along with the HTTP 302 code) when calling that URL.

“url”: “https://tjenester.nav.no/dittnav/oversikt”
“Location”: “https://www.nav.no/person/dittnav/

“url”: “https://loginservice.nav.no/login?level=Level3&redirect=https://www.nav.no/person/dittnav/”
“Location”: “https://login.microsoftonline.com/navnob2c.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1a_idporten&response_type=code&client_id=45104d6a-f5bc-4e8c-b352-4bbfc9381f25&redirect_uri=https%3A%2F%2Floginservice.nav.no%2Fcallback&scope=openid+offline_access+45104d6a-f5bc-4e8c-b352-4bbfc9381f25&state=_JTWomMWhyZw6bZifoPHgUw-7OccK-hV9BKi1VaMQYk&nonce=HLPaFgxW368_-E6Rj5L6D0iT4yufUO6kydE21oT3QJE&level=Level3

“url”: “https://login.microsoftonline.com/navnob2c.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1a_idporten&response_type=code&client_id=45104d6a-f5bc-4e8c-b352-4bbfc9381f25&redirect_uri=https%3A%2F%2Floginservice.nav.no%2Fcallback&scope=openid+offline_access+45104d6a-f5bc-4e8c-b352-4bbfc9381f25&state=_JTWomMWhyZw6bZifoPHgUw-7OccK-hV9BKi1VaMQYk&nonce=HLPaFgxW368_-E6Rj5L6D0iT4yufUO6kydE21oT3QJE&level=Level3”

“Location”: “https://oidc.difi.no/idporten-oidc-provider/authorize?client_id=oidc_nav&redirect_uri=https%3a%2f%2flogin.microsoftonline.com%2fte%2fnavnob2c.onmicrosoft.com%2foauth2%2fauthresp&response_type=code&scope=openid&response_mode=form_post&nonce=%2fC9sCl2kb7TZMD4tPS1%2fAg%3d%3d&acr_values=Level3&state=StateProperties%3deyJTSUQiOiJ4LW1zLWNwaW0tcmM6MTQ4MTE4YzctODc3MC00MzQ2LTkwMGEtNTkwYWVkZmI5MThlIiwiVElEIjoiZmE2OGVkYzctZTg0OS00MzA2LThmZmItOTExYmYwMjkzZDZmIn0

“url”: “https://oidc.difi.no/idporten-oidc-provider/authorize?client_id=oidc_nav&redirect_uri=https%3a%2f%2flogin.microsoftonline.com%2fte%2fnavnob2c.onmicrosoft.com%2foauth2%2fauthresp&response_type=code&scope=openid&response_mode=form_post&nonce=%2fC9sCl2kb7TZMD4tPS1%2fAg%3d%3d&acr_values=Level3&state=StateProperties%3deyJTSUQiOiJ4LW1zLWNwaW0tcmM6MTQ4MTE4YzctODc3MC00MzQ2LTkwMGEtNTkwYWVkZmI5MThlIiwiVElEIjoiZmE2OGVkYzctZTg0OS00MzA2LThmZmItOTExYmYwMjkzZDZmIn0”

“Location”: “https://idporten.difi.no/opensso/SSORedirect/metaAlias/norge.no/idp4?SAMLRequest=nZRNj5swEIbv%2FRXId8JHaBosYJVNumqkbUMD20MvK689bCyBTW2TTf99DQkpldocekKaGT%2Fzet4xyd2pqZ0jKM2lSFEw85EDgkrGxWuKnsoHd4nusneJJk0dtnjVmYPYw48OtHFWWoMy9txaCt01oApQR07haf%2BYooMxrcaeJzmjM8YrPhMSR9Hc46yVyoBw%2B4zbKnnkDJRHRhi9wJCzsU24IGZQNvLG4yPTky0IraVXFLs9MK6AGq8BQ1Y1J9oTUr1CX2bPRch5kIrCcIkUVaTWgJztJkXP7xdx6H%2BI%2FaW%2FWIY08oN5RBc%2B8%2BNg%2FrJYLGNbpnUHW6ENESZFoR%2FEbhC4flwGMfYjHMSzOF5%2BR06upJFU1vdcnGfYKYEl0VxjQRrQ2FBcrD4%2F4nDm45dzkcafyjJ3811RIufb6EXYe2HdERqfp3%2Bb1V4ao%2BxsFh4UqynhNuDqAMqmpiXeFJclDcMfT9aAXqS%2B0Bt2G937wYghVttO3MOB1NWuGro8C3JMvEkw8f5okI2b98VCt5tc1pz%2BdFZ1Ld%2FWCoiBFBnVweBsQ8xtGX2EM7caSnHbD1rbRgY5Rd7zv3aktpcGlaLpBJB3VXFZfWDDDtm9N3Ayzlo2LVFc9641XPCma64uTAvXtZ3xHqr%2F8uRmGcW0Z9twbj9vUrF%2BD%2B1TAFYqInT%2FZkYj%2F6YouyT%2FccPf6ekPIPsF&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=Avn4sIA3WxkCiEEZZwGkiJ4csP3FzR14fCBEEeKwbTLfqsWz8tRyoVJiNY7POtD%2BvVvjCk4MtJMCqBDxWyycVSzzDj%2F9i507Qef36D5V2Ai265ekyAPECvg5rR%2BgVB3ZkpDbWEBbTNR2wMAzH%2FKiND623p%2BMfBOa5vyUE7HEArJKumjAI4HdZHOfuLtFDGksdI5dGkZAiXs2h5ab5k4TvO8h0tqe%2BFjb333S4ZGb2vL%2B4TSuziNhjDJVISxjQcuCxCxF6Rj%2BN2qWO0ERHxge2v1rJO8awdZAkFU%2FrKz5MHxGJ27paaIZXg4pArkPAMdvs%2FaHetR%2Ff4LeFaMJM6UQUg%3D%3D&locale=nb

“url”: “https://idporten.difi.no/opensso/SSORedirect/metaAlias/norge.no/idp4?SAMLRequest=nZRNj5swEIbv%2FRXId8JHaBosYJVNumqkbUMD20MvK689bCyBTW2TTf99DQkpldocekKaGT%2Fzet4xyd2pqZ0jKM2lSFEw85EDgkrGxWuKnsoHd4nusneJJk0dtnjVmYPYw48OtHFWWoMy9txaCt01oApQR07haf%2BYooMxrcaeJzmjM8YrPhMSR9Hc46yVyoBw%2B4zbKnnkDJRHRhi9wJCzsU24IGZQNvLG4yPTky0IraVXFLs9MK6AGq8BQ1Y1J9oTUr1CX2bPRch5kIrCcIkUVaTWgJztJkXP7xdx6H%2BI%2FaW%2FWIY08oN5RBc%2B8%2BNg%2FrJYLGNbpnUHW6ENESZFoR%2FEbhC4flwGMfYjHMSzOF5%2BR06upJFU1vdcnGfYKYEl0VxjQRrQ2FBcrD4%2F4nDm45dzkcafyjJ3811RIufb6EXYe2HdERqfp3%2Bb1V4ao%2BxsFh4UqynhNuDqAMqmpiXeFJclDcMfT9aAXqS%2B0Bt2G937wYghVttO3MOB1NWuGro8C3JMvEkw8f5okI2b98VCt5tc1pz%2BdFZ1Ld%2FWCoiBFBnVweBsQ8xtGX2EM7caSnHbD1rbRgY5Rd7zv3aktpcGlaLpBJB3VXFZfWDDDtm9N3Ayzlo2LVFc9641XPCma64uTAvXtZ3xHqr%2F8uRmGcW0Z9twbj9vUrF%2BD%2B1TAFYqInT%2FZkYj%2F6YouyT%2FccPf6ekPIPsF&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=Avn4sIA3WxkCiEEZZwGkiJ4csP3FzR14fCBEEeKwbTLfqsWz8tRyoVJiNY7POtD%2BvVvjCk4MtJMCqBDxWyycVSzzDj%2F9i507Qef36D5V2Ai265ekyAPECvg5rR%2BgVB3ZkpDbWEBbTNR2wMAzH%2FKiND623p%2BMfBOa5vyUE7HEArJKumjAI4HdZHOfuLtFDGksdI5dGkZAiXs2h5ab5k4TvO8h0tqe%2BFjb333S4ZGb2vL%2B4TSuziNhjDJVISxjQcuCxCxF6Rj%2BN2qWO0ERHxge2v1rJO8awdZAkFU%2FrKz5MHxGJ27paaIZXg4pArkPAMdvs%2FaHetR%2Ff4LeFaMJM6UQUg%3D%3D&locale=nb”

“Location”: “https://idporten.difi.no:443/opensso/UI/Login?realm=/norge.no&spEntityID=oidc.difi.no&service=IDPortenLevel3List&goto=http://idporten.difi.no/opensso/SSORedirect/metaAlias/norge.no/idp4?ReqID%3D_5692079080682c40134c60d0913b6689%26index%3Dnull%26acsURL%3Dhttps://oidc.difi.no:443/idporten-oidc-provider/assertionconsumer%26spEntityID%3Doidc.difi.no%26binding%3Durn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST

 

“url”: “https://idporten.difi.no/opensso/bidresponse”

“Location”: “https://idporten.difi.no:443/opensso/UI/Login?realm=norge.no&ForceAuth=&gx_charset=UTF-8&locale=nb&goto=http://idporten.difi.no/opensso/SSORedirect/metaAlias/norge.no/idp4?ReqID=_5692079080682c40134c60d0913b6689&service=BankIDResponse

 

“url”: “https://idporten.difi.no/opensso/UI/Login?realm=norge.no&ForceAuth=&gx_charset=UTF-8&locale=nb&goto=http://idporten.difi.no/opensso/SSORedirect/metaAlias/norge.no/idp4?ReqID=_5692079080682c40134c60d0913b6689&service=BankIDResponse”

“Location”: “https://idporten.difi.no/opensso/SSORedirect/metaAlias/norge.no/idp4?ReqID=_5692079080682c40134c60d0913b6689

“url”: “https://oidc.difi.no/idporten-oidc-provider/assertionconsumer”

“Location”: “https://oidc.difi.no/idporten-oidc-provider/consent?mid=_5692079080682c40134c60d0913b6689

 

“url”: “https://login.microsoftonline.com/te/navnob2c.onmicrosoft.com/oauth2/authresp”

“Location”: “https://loginservice.nav.no/callback?state=_JTWomMWhyZw6bZifoPHgUw-7OccK-hV9BKi1VaMQYk&code=eyJraWQiOiJhT05QQk9fWDV0bzNIX2tsMllSTjRFRGdUMkVvQ201bmNCNlB1MEhOSlNJIiwidmVyIjoiMS4wIiwiemlwIjoiRGVmbGF0ZSIsInNlciI6IjEuMCJ9.b5lGSnVxsolX3Wa1gqGh5qqhm8upQh3laxBhYbqC2FixHYog53-6ilhTGxNevcqYL-gFih4xwTqNYJuEH7ux-eRr8YoUcv7Mv1TO3U-VtddA1O7ZMF6mbu3L8DcOFqHR7OahL4j_QVZm9z-gAYFl_yZvAMmQ4Selk_uKAzvwLkjE57u4S61nArLSknOJDV8XwpO4Ow_iicpL5RC_dr4jaLGH6WH6bMgLrtQ2uNfb2KhYQYQhkTmkYjqgx7fgPbqddz0OOCF8PUIEL7sKpl1-d0Uv75iAqXUJofZlFVDcDfBoO6noxaLVkWmNjWvHWmKHbHImmOTD__XtExAMoMK8wg.LJS-OSzaHhkhVERs.LCBP0FbMPn9OKkej4fmYlN9fj-cgwYPCKSulz96qY06wrmMOFokm5Iies7nsPsS2SD5WJGw-D4vlso-ac-yjHqNI_s-KequNz5XiNjMS_gaJYh19bfivmKJmCxOJjrobA95FzBAkJaOHezJNDWP_tlfB-0wzD8Y5JYCYJGw3CXvhlQDtNH3vAprgkEtA9sHxzoz_ejzZwT2Xrb5z2aI8RUJI1Y2WDHLKo8uXfkROJDAajYtWKIm2LcaFwdtnm90kXGHFB7tIRF76L8sOgc2IuK6l3UBlFpJcsaPeY-bvGK9rMotjSKqZjAiIs_OTkcpL_GPNbpyiicjQWdVFLLf51ivWlHvdADrCxDH20yLWu6GiYZMHUW4YXCDODhmrZx4LmEp35v_1Wpji-1HeKH3X7gPgZXVjhL9bK0ApnyCsUy6Vi-P5KyEy8Ne6UV0UKQZQjl58SoV67UKrabt44Wr9CDvYHCQwBh4WwJ-3pw2lF4-FbwXYE9A3ssdbAI5sM9M8XHAt537KRWTgaXw1xmrEQ3VQ8q6nNBIUhEKdtr43-q8NULpc2Yh8Q8fFPhBaUbtYSEeRKl-vrpiKI2yB4deG8bz6dwtgCiHdQ9R81hPCloAqNgUHzIl0roZkyu1acw.BDHTKPyICH1GZs9SIr-Xqg

 

“url”: “https://loginservice.nav.no/callback?state=_JTWomMWhyZw6bZifoPHgUw-7OccK-hV9BKi1VaMQYk&code=eyJraWQiOiJhT05QQk9fWDV0bzNIX2tsMllSTjRFRGdUMkVvQ201bmNCNlB1MEhOSlNJIiwidmVyIjoiMS4wIiwiemlwIjoiRGVmbGF0ZSIsInNlciI6IjEuMCJ9.b5lGSnVxsolX3Wa1gqGh5qqhm8upQh3laxBhYbqC2FixHYog53-6ilhTGxNevcqYL-gFih4xwTqNYJuEH7ux-eRr8YoUcv7Mv1TO3U-VtddA1O7ZMF6mbu3L8DcOFqHR7OahL4j_QVZm9z-gAYFl_yZvAMmQ4Selk_uKAzvwLkjE57u4S61nArLSknOJDV8XwpO4Ow_iicpL5RC_dr4jaLGH6WH6bMgLrtQ2uNfb2KhYQYQhkTmkYjqgx7fgPbqddz0OOCF8PUIEL7sKpl1-d0Uv75iAqXUJofZlFVDcDfBoO6noxaLVkWmNjWvHWmKHbHImmOTD__XtExAMoMK8wg.LJS-OSzaHhkhVERs.LCBP0FbMPn9OKkej4fmYlN9fj-cgwYPCKSulz96qY06wrmMOFokm5Iies7nsPsS2SD5WJGw-D4vlso-ac-yjHqNI_s-KequNz5XiNjMS_gaJYh19bfivmKJmCxOJjrobA95FzBAkJaOHezJNDWP_tlfB-0wzD8Y5JYCYJGw3CXvhlQDtNH3vAprgkEtA9sHxzoz_ejzZwT2Xrb5z2aI8RUJI1Y2WDHLKo8uXfkROJDAajYtWKIm2LcaFwdtnm90kXGHFB7tIRF76L8sOgc2IuK6l3UBlFpJcsaPeY-bvGK9rMotjSKqZjAiIs_OTkcpL_GPNbpyiicjQWdVFLLf51ivWlHvdADrCxDH20yLWu6GiYZMHUW4YXCDODhmrZx4LmEp35v_1Wpji-1HeKH3X7gPgZXVjhL9bK0ApnyCsUy6Vi-P5KyEy8Ne6UV0UKQZQjl58SoV67UKrabt44Wr9CDvYHCQwBh4WwJ-3pw2lF4-FbwXYE9A3ssdbAI5sM9M8XHAt537KRWTgaXw1xmrEQ3VQ8q6nNBIUhEKdtr43-q8NULpc2Yh8Q8fFPhBaUbtYSEeRKl-vrpiKI2yB4deG8bz6dwtgCiHdQ9R81hPCloAqNgUHzIl0roZkyu1acw.BDHTKPyICH1GZs9SIr-Xqg”

“Location”: “https://www.nav.no/person/dittnav/

 

So the sequence is from NAV to Microsoft to Difi and then reversing the steps back again. Which is how Micorsoft is called by both Difi and NAV.

Where are the calls to psplugin.com, taskanalytics.com and googletagmanager.com from, and more particularly what are they?

egrep -v “text\”:” HAR-file | tr -d “\n” | sed ‘s/”url”:/\n “url\”:/g’ | sed ‘s/ */ /g’ | egrep “Referer” | sed ‘s/”url”: “\([^\”]*\)”.*{ “name”: “Referer”, “value”: “\([^\”]*\).*/\2 \1 /g’ | egrep “(psplugin.com|taskanalytics.com|googletagmanager.com)”

https://www.nav.no/person/dittnav/ https://www.googletagmanager.com/gtm.js?id=GTM-PM9RP3
https://www.nav.no/person/dittnav/ https://in.taskanalytics.com/02013/tm.js?r=skip&1573326257975
https://www.nav.no/person/dittnav/ https://www.googletagmanager.com/gtm.js?id=GTM-PM9RP3
https://www.nav.no/person/dittnav/ https://in.taskanalytics.com/02013/tm.js?r=skip&1573326295196
https://www.nav.no/person/dittnav/ https://account.psplugin.com/83BD7664-B38B-4EEE-8D99-200669A32551/ps.js
https://www.nav.no/person/dittnav/ https://nav.psplugin.com/api/v1/session/bucket/visitor?json=true&sessionId=f1f43342-d73f-4242-aaad-cc5a951d83b7%2BFogm7TkHIHjpVxuZ4w0e6KDH9p2WZkmphcX6U9L4%3D
https://www.nav.no/person/dittnav/ https://nav.psplugin.com/api/v1/Group/Status/83bd7664-b38b-4eee-8d99-200669a32551?json=true&sessionId=f1f43342-d73f-4242-aaad-cc5a951d83b7%2BFogm7TkHIHjpVxuZ4w0e6KDH9p2WZkmphcX6U9L4%3D&groupId=D3F9B5D9-C9FD-43AD-BA23-6E112D23ABFC&groupId=0D034F9F-CD29-4E4D-BD26-9C943D8D5557&groupId=641833F0-C54C-4BDE-9DDF-6AFF0A512FF5&groupId=85723614-0E9A-45CF-93C3-445DCDBF87FE&groupId=975CAC35-8D3E-402C-B9E3-0930D30FFFB7&groupId=D48EC512-991E-4541-8062-CAF97C3757D9&groupId=A034081B-6B73-46B7-BE27-23B8E9CE3079
https://www.nav.no/person/dittnav/ https://nav.psplugin.com/api/v1/batch/?json=true&sessionId=f1f43342-d73f-4242-aaad-cc5a951d83b7%2BFogm7TkHIHjpVxuZ4w0e6KDH9p2WZkmphcX6U9L4%3D
https://www.nav.no/person/dittnav/ https://nav.psplugin.com/api/v1/batch/?json=true&sessionId=f1f43342-d73f-4242-aaad-cc5a951d83b7%2BFogm7TkHIHjpVxuZ4w0e6KDH9p2WZkmphcX6U9L4%3D

Some things here are not necessarily ok.
psplugin.com has “nav” as a subdomain and the calls go here. Apparently with session specific information. Which is user specific information. Where is it going ?

This command will get the registration info on the domain

curl ‘https://www.site24x7.com/tools/action.do’ -H ‘Content-type: application/x-www-form-urlencoded;charset=UTF-8’ –data “execute=getLocation&isip=false&url=nav.psplugin.com&method=getLocation&timestamp=$(( $(date +%s)-10))” | sed ‘s/#:#/\n/g’

Falkenberg in Sweden. Well, that might be ok geographically. But it is not inside Norway, and NAV is a goverment agency.

Google is in California, but their datacenters are all over.
in.taskanalytics.com gives a Dublin address, again that can mean anything.
Though in either case the location to which data is being sent is not likely in Norway.

Let’s look at some of that data. Are there any POST calls? HTTP POSTs have the highest potential for carrying off data (tough cookies can carry plenty too )

cat HAR-file | tr -d “\n” | sed ‘s/”url”:/\n “url\”:/g’ | sed ‘s/ */ /g’ | egrep -i “\”method\”: \”POST\”” | egrep -v “^ \”url\”: \”https://%5B^/]*.(bankid|nav|difi).no”

“url”: “https://nav.psplugin.com/api/v1/batch/?json=true&sessionId=f1f43342-d73f-4242-aaad-cc5a951d83b7%2BFogm7TkHIHjpVxuZ4w0e6KDH9p2WZkmphcX6U9L4%3D”, “httpVersion”: “HTTP/1.1”, “headers”: [ { “name”: “Host”, “value”: “nav.psplugin.com” }, { “name”: “User-Agent”, “value”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0” }, { “name”: “Accept”, “value”: “application/json” }, { “name”: “Accept-Language”, “value”: “en-GB,en;q=0.5” }, { “name”: “Accept-Encoding”, “value”: “gzip, deflate, br” }, { “name”: “Content-Type”, “value”: “text/plain; charset=utf-8” }, { “name”: “Content-Length”, “value”: “724” }, { “name”: “Origin”, “value”: “https://www.nav.no” }, { “name”: “DNT”, “value”: “1” }, { “name”: “Connection”, “value”: “keep-alive” }, { “name”: “Referer”, “value”: “https://www.nav.no/person/dittnav/” }, { “name”: “Cookie”, “value”: “vngage.srvid=da46b3656037eb53” } ], “cookies”: [ { “name”: “vngage.srvid”, “value”: “da46b3656037eb53” } ], “queryString”: [ { “name”: “json”, “value”: “true” }, { “name”: “sessionId”, “value”: “f1f43342-d73f-4242-aaad-cc5a951d83b7 Fogm7TkHIHjpVxuZ4w0e6KDH9p2WZkmphcX6U9L4=” } ], “headersSize”: 552, “postData”: { “mimeType”: “text/plain; charset=utf-8”, “params”: [], “text”: “{\”items\”:[{\”contentHeaders\”:{\”Content-Type\”:\”application/json\”},\”method\”:\”post\”,\”uri\”:\”https://nav.psplugin.com/api/v1/Tracking/Bundle\”,\”body\”:\”[{\\\”type\\\”:\\\”Navigation\\\”,\\\”url\\\”:\\\”https://www.nav.no/person/dittnav/\\\”,\\\”referrer\\\”:\\\”\\\”,\\\”visitId\\\”:\\\”00000000-0000-0000-0000-000000000000\\\”,\\\”siteId\\\”:\\\”1F1046B2-16A5-40A1-AD72-65B34BA29159\\\”,\\\”metaData\\\”:[{\\\”property\\\”:\\\”triggerType\\\”,\\\”content\\\”:\\\”pageload\\\”}]},{\\\”type\\\”:\\\”Opportunity\\\”,\\\”visitId\\\”:\\\”00000000-0000-0000-0000-000000000000\\\”,\\\”siteId\\\”:\\\”1F1046B2-16A5-40A1-AD72-65B34BA29159\\\”,\\\”opportunityId\\\”:\\\”615FF5E7-37B7-4697-A35F-72598B0DC53B\\\”,\\\”correlationId\\\”:\\\”0B9BA0C0-3C13-4947-A8C3-AFCDDFEEC82B\\\”,\\\”tags\\\”:[],\\\”source\\\”:\\\”visitor\\\”,\\\”tag\\\”:{},\\\”score\\\”:0}]\”}]}” } }, “response”: { “status”: 200, “statusText”: “OK”, “httpVersion”: “HTTP/1.1”, “headers”: [ { “name”: “Date”, “value”: “Sat, 09 Nov 2019 19:04:56 GMT” }, { “name”: “Content-Type”, “value”: “application/json; charset=utf-8” }, { “name”: “Transfer-Encoding”, “value”: “chunked” }, { “name”: “Access-Control-Allow-Credentials”, “value”: “true” }, { “name”: “Access-Control-Allow-Origin”, “value”: “https://www.nav.no” }, { “name”: “Access-Control-Max-Age”, “value”: “604800” }, { “name”: “P3p”, “value”: “CP=\”IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\”” }, { “name”: “X-Content-Type-Options”, “value”: “nosniff” } ], “cookies”: [], “content”: { “mimeType”: “application/json; charset=utf-8”, “size”: 63, “text”: “{\”items\”:[{\”statusCode\”:200,\”headers\”:{},\”contentHeaders\”:{}}]}” }, “redirectURL”: “”, “headersSize”: 361, “bodySize”: 424 }, “cache”: {}, “timings”: { “blocked”: 1, “dns”: 0, “connect”: 0, “ssl”: 0, “send”: 0, “wait”: 47, “receive”: 0 }, “time”: 48, “_securityState”: “secure”, “serverIPAddress”: “194.54.166.38”, “connection”: “443” }, { “pageref”: “page_3”, “startedDateTime”: “2019-11-09T20:04:57.371+01:00”, “request”: { “bodySize”: 5417, “method”: “POST”,

That wasn’t much. Some session ids but not much else.

From where is the call to google in being made and why ?

A javastip file  https://appres.nav.no/_public/beta.nav.no/built-navno/js/navno/google-tag-manager.js

 

This login was very messy and the calls out to external parties most worrysome. But what strikes me as the most unusual is the call to Microsoft. And as a step in the login process too.
Why should Microsoft be involved in a federated login to a government agency ?

 

egrep -v “text\”:” HAR-file | tr -d “\n” | sed ‘s/”url”:/\n “url\”:/g’ | sed ‘s/ */ /g’ | egrep “^ \”url\”: \”https://%5B^/]*.microsoftonline.com” | sed ‘s/”response”/\n\n\n”response”/g’ | sed ‘s/ “url”/\n\n\n”url”/g’

“url”: “https://login.microsoftonline.com/navnob2c.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1a_idporten&response_type=code&client_id=45104d6a-f5bc-4e8c-b352-4bbfc9381f25&redirect_uri=https%3A%2F%2Floginservice.nav.no%2Fcallback&scope=openid+offline_access+45104d6a-f5bc-4e8c-b352-4bbfc9381f25&state=_JTWomMWhyZw6bZifoPHgUw-7OccK-hV9BKi1VaMQYk&nonce=HLPaFgxW368_-E6Rj5L6D0iT4yufUO6kydE21oT3QJE&level=Level3”, “httpVersion”: “HTTP/1.1”, “headers”: [ { “name”: “Host”, “value”: “login.microsoftonline.com” }, { “name”: “User-Agent”, “value”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0” }, { “name”: “Accept”, “value”: “text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8” }, { “name”: “Accept-Language”, “value”: “en-GB,en;q=0.5” }, { “name”: “Accept-Encoding”, “value”: “gzip, deflate, br” }, { “name”: “Referer”, “value”: “https://www.nav.no/person/dittnav/” }, { “name”: “DNT”, “value”: “1” }, { “name”: “Connection”, “value”: “keep-alive” }, { “name”: “Upgrade-Insecure-Requests”, “value”: “1” } ], “cookies”: [], “queryString”: [ { “name”: “p”, “value”: “b2c_1a_idporten” }, { “name”: “response_type”, “value”: “code” }, { “name”: “client_id”, “value”: “45104d6a-f5bc-4e8c-b352-4bbfc9381f25” }, { “name”: “redirect_uri”, “value”: “https://loginservice.nav.no/callback” }, { “name”: “scope”, “value”: “openid offline_access 45104d6a-f5bc-4e8c-b352-4bbfc9381f25” }, { “name”: “state”, “value”: “_JTWomMWhyZw6bZifoPHgUw-7OccK-hV9BKi1VaMQYk” }, { “name”: “nonce”, “value”: “HLPaFgxW368_-E6Rj5L6D0iT4yufUO6kydE21oT3QJE” }, { “name”: “level”, “value”: “Level3” } ], “headersSize”: 758 },

“response”: { “status”: 302, “statusText”: “Found”, “httpVersion”: “HTTP/1.1”, “headers”: [ { “name”: “Cache-Control”, “value”: “private” }, { “name”: “Content-Type”, “value”: “text/html; charset=utf-8” }, { “name”: “Location”, “value”: “https://oidc.difi.no/idporten-oidc-provider/authorize?client_id=oidc_nav&redirect_uri=https%3a%2f%2flogin.microsoftonline.com%2fte%2fnavnob2c.onmicrosoft.com%2foauth2%2fauthresp&response_type=code&scope=openid&response_mode=form_post&nonce=%2fC9sCl2kb7TZMD4tPS1%2fAg%3d%3d&acr_values=Level3&state=StateProperties%3deyJTSUQiOiJ4LW1zLWNwaW0tcmM6MTQ4MTE4YzctODc3MC00MzQ2LTkwMGEtNTkwYWVkZmI5MThlIiwiVElEIjoiZmE2OGVkYzctZTg0OS00MzA2LThmZmItOTExYmYwMjkzZDZmIn0” }, { “name”: “x-ms-gateway-requestid”, “value”: “6be20d8a-8de5-4744-9554-0e5d916b0646” }, { “name”: “Set-Cookie”, “value”: “x-ms-cpim-rc:148118c7-8770-4346-900a-590aedfb918e=aGxSZjI4UFlYMlhxZjN3dGs3bnpZc2Q3dCtSSmtkRDlJNVp6TWxwS3VSQ1VLZmE4UEVjdHBWSStmTWhaVWdHWHQvTU9BRHlBMXhrU2tmanpBaGNNWXc9PTsyMDE5LTExLTA5VDE5OjA0OjE5Ljc1MDE5MTRaO3ZOdVdHUGlMYTZLcVRrN2RJVWZFMmc9PTt7IlRhcmdldEVudGl0eSI6IklkUG9ydGVuRXhjaGFuZ2UiLCJPcmNoZXN0cmF0aW9uU3RlcCI6MX0=; domain=login.microsoftonline.com; path=/; SameSite=None; secure; HttpOnly” }, { “name”: “Set-Cookie”, “value”: “x-ms-cpim-cache:x-1o-knobkop-5eb8ck9bw_0=m1.zcF9N87I+2/g1yeG.UTmH1gNjIyc69CLP0dMrJg==.0.xoG2yeldPtYiejoQ1QkTa6xU6Mp8IwRk4wbClfYYeaH7BczY8d++EydY4qYxTQSMLySLgHc+nROLyX1zwt4Zfb5gEN4TbAGP9uRMlrKDQE/SN6j5lU1UQA7nYqAIG+yq0t4BsO0KCh7Y9cK2oLi8S12xFGXwFHaB76r6DH4ZTaaJAROmz0cD/NAohTjqqi8YgrK0Lz03x64r0dbjHXTyXhgJJy91KBPGeTXc98WseRgsw429BSVfJToIC7rEfHk8ugnPZfZVIY7k13n1DGzpzKjfFZ67LsS6KEUg3YBDcs0AQULdPWZ15Bn0hk9vwfkBWMUi3kZRPxyfQyktCktF3wcbYQ5VYZh4f6BMz2RLqQHMPIDwzB5GSZvRuW7YkAywNb6dFS8yN4c9mx7EfgQjuexVmeJv+asyUASINQANZmpgHQQbDN/skHbOpSr4Zf+Sr/7wC0hy8vueOQFJad6hu6WYKp10b2MFlmLnnZyr9jeVdQEvTp0fsRu/6xacCH5fHG9VvjooZax89P8sBEyA/1HMGRURxGtaJpKHCllTlGaYrQYgn4ILcnANDHW8DWawHKM6sB8a2nS056/yyiPGVMaG+YV08qdWd/xM6J5I2e4KXzxKYdEIFYPVVg8otyp6M/mKK+QIxvHKKdcnGE93JcdYKhC0pOjznhQuxaaEZvXn8bit+WWzPeYxeSPWDQadXUNSXwG4L66AWn/X; domain=login.microsoftonline.com; path=/; SameSite=None; secure; HttpOnly” }, { “name”: “Set-Cookie”, “value”: “x-ms-cpim-trans=eyJUX0RJQyI6W3siSSI6ImZhNjhlZGM3LWU4NDktNDMwNi04ZmZiLTkxMWJmMDI5M2Q2ZiIsIlQiOiJuYXZub2IyYy5vbm1pY3Jvc29mdC5jb20iLCJQIjoiYjJjXzFhX2lkcG9ydGVuIiwiQyI6IjQ1MTA0ZDZhLWY1YmMtNGU4Yy1iMzUyLTRiYmZjOTM4MWYyNSIsIlMiOjEsIk0iOnt9LCJEIjowfV0sIkNfSUQiOiJmYTY4ZWRjNy1lODQ5LTQzMDYtOGZmYi05MTFiZjAyOTNkNmYifQ==; domain=login.microsoftonline.com; path=/; SameSite=None; secure; HttpOnly” }, { “name”: “X-Frame-Options”, “value”: “DENY” }, { “name”: “Strict-Transport-Security”, “value”: “max-age=31536000; includeSubDomains” }, { “name”: “X-Content-Type-Options”, “value”: “nosniff” }, { “name”: “X-XSS-Protection”, “value”: “1; mode=block” }, { “name”: “Set-Cookie”, “value”: “x-ms-gateway-slice=001-000; path=/; SameSite=None; secure; HttpOnly” }, { “name”: “Set-Cookie”, “value”: “stsservicecookie=cpim_te; path=/; SameSite=None; secure; HttpOnly” }, { “name”: “Date”, “value”: “Sat, 09 Nov 2019 19:04:19 GMT” }, { “name”: “Content-Length”, “value”: “599” } ], “cookies”: [ { “name”: “x-ms-cpim-rc:148118c7-8770-4346-900a-590aedfb918e”, “value”: “aGxSZjI4UFlYMlhxZjN3dGs3bnpZc2Q3dCtSSmtkRDlJNVp6TWxwS3VSQ1VLZmE4UEVjdHBWSStmTWhaVWdHWHQvTU9BRHlBMXhrU2tmanpBaGNNWXc9PTsyMDE5LTExLTA5VDE5OjA0OjE5Ljc1MDE5MTRaO3ZOdVdHUGlMYTZLcVRrN2RJVWZFMmc9PTt7IlRhcmdldEVudGl0eSI6IklkUG9ydGVuRXhjaGFuZ2UiLCJPcmNoZXN0cmF0aW9uU3RlcCI6MX0=” }, { “name”: “x-ms-cpim-cache:x-1o-knobkop-5eb8ck9bw_0”, “value”: “m1.zcF9N87I+2/g1yeG.UTmH1gNjIyc69CLP0dMrJg==.0.xoG2yeldPtYiejoQ1QkTa6xU6Mp8IwRk4wbClfYYeaH7BczY8d++EydY4qYxTQSMLySLgHc+nROLyX1zwt4Zfb5gEN4TbAGP9uRMlrKDQE/SN6j5lU1UQA7nYqAIG+yq0t4BsO0KCh7Y9cK2oLi8S12xFGXwFHaB76r6DH4ZTaaJAROmz0cD/NAohTjqqi8YgrK0Lz03x64r0dbjHXTyXhgJJy91KBPGeTXc98WseRgsw429BSVfJToIC7rEfHk8ugnPZfZVIY7k13n1DGzpzKjfFZ67LsS6KEUg3YBDcs0AQULdPWZ15Bn0hk9vwfkBWMUi3kZRPxyfQyktCktF3wcbYQ5VYZh4f6BMz2RLqQHMPIDwzB5GSZvRuW7YkAywNb6dFS8yN4c9mx7EfgQjuexVmeJv+asyUASINQANZmpgHQQbDN/skHbOpSr4Zf+Sr/7wC0hy8vueOQFJad6hu6WYKp10b2MFlmLnnZyr9jeVdQEvTp0fsRu/6xacCH5fHG9VvjooZax89P8sBEyA/1HMGRURxGtaJpKHCllTlGaYrQYgn4ILcnANDHW8DWawHKM6sB8a2nS056/yyiPGVMaG+YV08qdWd/xM6J5I2e4KXzxKYdEIFYPVVg8otyp6M/mKK+QIxvHKKdcnGE93JcdYKhC0pOjznhQuxaaEZvXn8bit+WWzPeYxeSPWDQadXUNSXwG4L66AWn/X” }, { “name”: “x-ms-cpim-trans”, “value”: “eyJUX0RJQyI6W3siSSI6ImZhNjhlZGM3LWU4NDktNDMwNi04ZmZiLTkxMWJmMDI5M2Q2ZiIsIlQiOiJuYXZub2IyYy5vbm1pY3Jvc29mdC5jb20iLCJQIjoiYjJjXzFhX2lkcG9ydGVuIiwiQyI6IjQ1MTA0ZDZhLWY1YmMtNGU4Yy1iMzUyLTRiYmZjOTM4MWYyNSIsIlMiOjEsIk0iOnt9LCJEIjowfV0sIkNfSUQiOiJmYTY4ZWRjNy1lODQ5LTQzMDYtOGZmYi05MTFiZjAyOTNkNmYifQ==” }, { “name”: “x-ms-gateway-slice”, “value”: “001-000” }, { “name”: “stsservicecookie”, “value”: “cpim_te” } ], “content”: { “mimeType”: “text/html; charset=UTF-8”, “size”: 14892, “comment”: “Response bodies are not included.” }, “redirectURL”: “https://oidc.difi.no/idporten-oidc-provider/authorize?client_id=oidc_nav&redirect_uri=https%3a%2f%2flogin.microsoftonline.com%2fte%2fnavnob2c.onmicrosoft.com%2foauth2%2fauthresp&response_type=code&scope=openid&response_mode=form_post&nonce=%2fC9sCl2kb7TZMD4tPS1%2fAg%3d%3d&acr_values=Level3&state=StateProperties%3deyJTSUQiOiJ4LW1zLWNwaW0tcmM6MTQ4MTE4YzctODc3MC00MzQ2LTkwMGEtNTkwYWVkZmI5MThlIiwiVElEIjoiZmE2OGVkYzctZTg0OS00MzA2LThmZmItOTExYmYwMjkzZDZmIn0”, “headersSize”: 2634, “bodySize”: 17526 }, “cache”: {}, “timings”: { “blocked”: 202, “dns”: 0, “connect”: 79, “ssl”: 120, “send”: 0, “wait”: 110, “receive”: 0 }, “time”: 511, “_securityState”: “secure”, “serverIPAddress”: “40.126.1.165”, “connection”: “443” }, { “pageref”: “page_3”, “startedDateTime”: “2019-11-09T20:04:19.838+01:00”, “request”: { “bodySize”: 0, “method”: “GET”,

 

“url”: “https://login.microsoftonline.com/te/navnob2c.onmicrosoft.com/oauth2/authresp”, “httpVersion”: “HTTP/1.1”, “headers”: [ { “name”: “Host”, “value”: “login.microsoftonline.com” }, { “name”: “User-Agent”, “value”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0” }, { “name”: “Accept”, “value”: “text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8” }, { “name”: “Accept-Language”, “value”: “en-GB,en;q=0.5” }, { “name”: “Accept-Encoding”, “value”: “gzip, deflate, br” }, { “name”: “Content-Type”, “value”: “application/x-www-form-urlencoded” }, { “name”: “Content-Length”, “value”: “212” }, { “name”: “Origin”, “value”: “https://oidc.difi.no” }, { “name”: “DNT”, “value”: “1” }, { “name”: “Connection”, “value”: “keep-alive” }, { “name”: “Referer”, “value”: “https://oidc.difi.no/idporten-oidc-provider/consent?mid=_5692079080682c40134c60d0913b6689” }, { “name”: “Cookie”, “value”: “x-ms-cpim-rc:148118c7-8770-4346-900a-590aedfb918e=aGxSZjI4UFlYMlhxZjN3dGs3bnpZc2Q3dCtSSmtkRDlJNVp6TWxwS3VSQ1VLZmE4UEVjdHBWSStmTWhaVWdHWHQvTU9BRHlBMXhrU2tmanpBaGNNWXc9PTsyMDE5LTExLTA5VDE5OjA0OjE5Ljc1MDE5MTRaO3ZOdVdHUGlMYTZLcVRrN2RJVWZFMmc9PTt7IlRhcmdldEVudGl0eSI6IklkUG9ydGVuRXhjaGFuZ2UiLCJPcmNoZXN0cmF0aW9uU3RlcCI6MX0=; x-ms-cpim-cache:x-1o-knobkop-5eb8ck9bw_0=m1.zcF9N87I+2/g1yeG.UTmH1gNjIyc69CLP0dMrJg==.0.xoG2yeldPtYiejoQ1QkTa6xU6Mp8IwRk4wbClfYYeaH7BczY8d++EydY4qYxTQSMLySLgHc+nROLyX1zwt4Zfb5gEN4TbAGP9uRMlrKDQE/SN6j5lU1UQA7nYqAIG+yq0t4BsO0KCh7Y9cK2oLi8S12xFGXwFHaB76r6DH4ZTaaJAROmz0cD/NAohTjqqi8YgrK0Lz03x64r0dbjHXTyXhgJJy91KBPGeTXc98WseRgsw429BSVfJToIC7rEfHk8ugnPZfZVIY7k13n1DGzpzKjfFZ67LsS6KEUg3YBDcs0AQULdPWZ15Bn0hk9vwfkBWMUi3kZRPxyfQyktCktF3wcbYQ5VYZh4f6BMz2RLqQHMPIDwzB5GSZvRuW7YkAywNb6dFS8yN4c9mx7EfgQjuexVmeJv+asyUASINQANZmpgHQQbDN/skHbOpSr4Zf+Sr/7wC0hy8vueOQFJad6hu6WYKp10b2MFlmLnnZyr9jeVdQEvTp0fsRu/6xacCH5fHG9VvjooZax89P8sBEyA/1HMGRURxGtaJpKHCllTlGaYrQYgn4ILcnANDHW8DWawHKM6sB8a2nS056/yyiPGVMaG+YV08qdWd/xM6J5I2e4KXzxKYdEIFYPVVg8otyp6M/mKK+QIxvHKKdcnGE93JcdYKhC0pOjznhQuxaaEZvXn8bit+WWzPeYxeSPWDQadXUNSXwG4L66AWn/X; x-ms-cpim-trans=eyJUX0RJQyI6W3siSSI6ImZhNjhlZGM3LWU4NDktNDMwNi04ZmZiLTkxMWJmMDI5M2Q2ZiIsIlQiOiJuYXZub2IyYy5vbm1pY3Jvc29mdC5jb20iLCJQIjoiYjJjXzFhX2lkcG9ydGVuIiwiQyI6IjQ1MTA0ZDZhLWY1YmMtNGU4Yy1iMzUyLTRiYmZjOTM4MWYyNSIsIlMiOjEsIk0iOnt9LCJEIjowfV0sIkNfSUQiOiJmYTY4ZWRjNy1lODQ5LTQzMDYtOGZmYi05MTFiZjAyOTNkNmYifQ==; x-ms-gateway-slice=001-000; stsservicecookie=cpim_te” }, { “name”: “Upgrade-Insecure-Requests”, “value”: “1” } ], “cookies”: [ { “name”: “x-ms-cpim-rc:148118c7-8770-4346-900a-590aedfb918e”, “value”: “aGxSZjI4UFlYMlhxZjN3dGs3bnpZc2Q3dCtSSmtkRDlJNVp6TWxwS3VSQ1VLZmE4UEVjdHBWSStmTWhaVWdHWHQvTU9BRHlBMXhrU2tmanpBaGNNWXc9PTsyMDE5LTExLTA5VDE5OjA0OjE5Ljc1MDE5MTRaO3ZOdVdHUGlMYTZLcVRrN2RJVWZFMmc9PTt7IlRhcmdldEVudGl0eSI6IklkUG9ydGVuRXhjaGFuZ2UiLCJPcmNoZXN0cmF0aW9uU3RlcCI6MX0=” }, { “name”: “x-ms-cpim-cache:x-1o-knobkop-5eb8ck9bw_0”, “value”: “m1.zcF9N87I+2/g1yeG.UTmH1gNjIyc69CLP0dMrJg==.0.xoG2yeldPtYiejoQ1QkTa6xU6Mp8IwRk4wbClfYYeaH7BczY8d++EydY4qYxTQSMLySLgHc+nROLyX1zwt4Zfb5gEN4TbAGP9uRMlrKDQE/SN6j5lU1UQA7nYqAIG+yq0t4BsO0KCh7Y9cK2oLi8S12xFGXwFHaB76r6DH4ZTaaJAROmz0cD/NAohTjqqi8YgrK0Lz03x64r0dbjHXTyXhgJJy91KBPGeTXc98WseRgsw429BSVfJToIC7rEfHk8ugnPZfZVIY7k13n1DGzpzKjfFZ67LsS6KEUg3YBDcs0AQULdPWZ15Bn0hk9vwfkBWMUi3kZRPxyfQyktCktF3wcbYQ5VYZh4f6BMz2RLqQHMPIDwzB5GSZvRuW7YkAywNb6dFS8yN4c9mx7EfgQjuexVmeJv+asyUASINQANZmpgHQQbDN/skHbOpSr4Zf+Sr/7wC0hy8vueOQFJad6hu6WYKp10b2MFlmLnnZyr9jeVdQEvTp0fsRu/6xacCH5fHG9VvjooZax89P8sBEyA/1HMGRURxGtaJpKHCllTlGaYrQYgn4ILcnANDHW8DWawHKM6sB8a2nS056/yyiPGVMaG+YV08qdWd/xM6J5I2e4KXzxKYdEIFYPVVg8otyp6M/mKK+QIxvHKKdcnGE93JcdYKhC0pOjznhQuxaaEZvXn8bit+WWzPeYxeSPWDQadXUNSXwG4L66AWn/X” }, { “name”: “x-ms-cpim-trans”, “value”: “eyJUX0RJQyI6W3siSSI6ImZhNjhlZGM3LWU4NDktNDMwNi04ZmZiLTkxMWJmMDI5M2Q2ZiIsIlQiOiJuYXZub2IyYy5vbm1pY3Jvc29mdC5jb20iLCJQIjoiYjJjXzFhX2lkcG9ydGVuIiwiQyI6IjQ1MTA0ZDZhLWY1YmMtNGU4Yy1iMzUyLTRiYmZjOTM4MWYyNSIsIlMiOjEsIk0iOnt9LCJEIjowfV0sIkNfSUQiOiJmYTY4ZWRjNy1lODQ5LTQzMDYtOGZmYi05MTFiZjAyOTNkNmYifQ==” }, { “name”: “x-ms-gateway-slice”, “value”: “001-000” }, { “name”: “stsservicecookie”, “value”: “cpim_te” } ], “queryString”: [], “headersSize”: 2093, “postData”: { “mimeType”: “application/x-www-form-urlencoded”, “params”: [ { “name”: “code”, “value”: “MryzERHWMbxfjnvLYEiJpw7_ojLZ4qKowtDMHytb7I0” }, { “name”: “state”, “value”: “StateProperties=eyJTSUQiOiJ4LW1zLWNwaW0tcmM6MTQ4MTE4YzctODc3MC00MzQ2LTkwMGEtNTkwYWVkZmI5MThlIiwiVElEIjoiZmE2OGVkYzctZTg0OS00MzA2LThmZmItOTExYmYwMjkzZDZmIn0” } ], } },

“response”: { “status”: 302, “statusText”: “Found”, “httpVersion”: “HTTP/1.1”, “headers”: [ { “name”: “Cache-Control”, “value”: “private” }, { “name”: “Content-Type”, “value”: “text/html; charset=utf-8” }, { “name”: “Location”, “value”: “https://loginservice.nav.no/callback?state=_JTWomMWhyZw6bZifoPHgUw-7OccK-hV9BKi1VaMQYk&code=eyJraWQiOiJhT05QQk9fWDV0bzNIX2tsMllSTjRFRGdUMkVvQ201bmNCNlB1MEhOSlNJIiwidmVyIjoiMS4wIiwiemlwIjoiRGVmbGF0ZSIsInNlciI6IjEuMCJ9.b5lGSnVxsolX3Wa1gqGh5qqhm8upQh3laxBhYbqC2FixHYog53-6ilhTGxNevcqYL-gFih4xwTqNYJuEH7ux-eRr8YoUcv7Mv1TO3U-VtddA1O7ZMF6mbu3L8DcOFqHR7OahL4j_QVZm9z-gAYFl_yZvAMmQ4Selk_uKAzvwLkjE57u4S61nArLSknOJDV8XwpO4Ow_iicpL5RC_dr4jaLGH6WH6bMgLrtQ2uNfb2KhYQYQhkTmkYjqgx7fgPbqddz0OOCF8PUIEL7sKpl1-d0Uv75iAqXUJofZlFVDcDfBoO6noxaLVkWmNjWvHWmKHbHImmOTD__XtExAMoMK8wg.LJS-OSzaHhkhVERs.LCBP0FbMPn9OKkej4fmYlN9fj-cgwYPCKSulz96qY06wrmMOFokm5Iies7nsPsS2SD5WJGw-D4vlso-ac-yjHqNI_s-KequNz5XiNjMS_gaJYh19bfivmKJmCxOJjrobA95FzBAkJaOHezJNDWP_tlfB-0wzD8Y5JYCYJGw3CXvhlQDtNH3vAprgkEtA9sHxzoz_ejzZwT2Xrb5z2aI8RUJI1Y2WDHLKo8uXfkROJDAajYtWKIm2LcaFwdtnm90kXGHFB7tIRF76L8sOgc2IuK6l3UBlFpJcsaPeY-bvGK9rMotjSKqZjAiIs_OTkcpL_GPNbpyiicjQWdVFLLf51ivWlHvdADrCxDH20yLWu6GiYZMHUW4YXCDODhmrZx4LmEp35v_1Wpji-1HeKH3X7gPgZXVjhL9bK0ApnyCsUy6Vi-P5KyEy8Ne6UV0UKQZQjl58SoV67UKrabt44Wr9CDvYHCQwBh4WwJ-3pw2lF4-FbwXYE9A3ssdbAI5sM9M8XHAt537KRWTgaXw1xmrEQ3VQ8q6nNBIUhEKdtr43-q8NULpc2Yh8Q8fFPhBaUbtYSEeRKl-vrpiKI2yB4deG8bz6dwtgCiHdQ9R81hPCloAqNgUHzIl0roZkyu1acw.BDHTKPyICH1GZs9SIr-Xqg” }, { “name”: “x-ms-gateway-requestid”, “value”: “9c4f492d-2cb5-4b76-a4b1-f23caceeebf4” }, { “name”: “Set-Cookie”, “value”: “x-ms-cpim-rc:148118c7-8770-4346-900a-590aedfb918e=; domain=login.microsoftonline.com; expires=Fri, 08-Nov-2019 19:04:53 GMT; path=/; SameSite=None; secure; HttpOnly” }, { “name”: “Set-Cookie”, “value”: “x-ms-cpim-sso:navnob2c.onmicrosoft.com_0=m1.RP3BbsClW5XQVM+s.zoR66H3kXPuUX94F/tcPBw==.0.QGnjHX4eTe5vLHtrfAdtBkA0ZJK6aAaPM8CWVJSWvSLqR3JiWGuA0+9m9o2rYn2RUncXsHAlg3bAFD2rBSv69N96/niU3312pxLnuetVzCHHVneCRL0kw8OhYa5NQeHct+Vr4sC11K49f+9e5Cnvi8cVx/qntlWx0JWDqGpQhxFiSGJXBfk0sjr039GL7cvGCWezUbvjbQnz1cF6n8hCWqCk; domain=login.microsoftonline.com; path=/; SameSite=None; secure; HttpOnly” }, { “name”: “Set-Cookie”, “value”: “x-ms-cpim-cache:x-1o-knobkop-5eb8ck9bw_0=; domain=login.microsoftonline.com; expires=Fri, 08-Nov-2019 19:04:53 GMT; path=/; SameSite=None; secure; HttpOnly” }, { “name”: “Set-Cookie”, “value”: “x-ms-cpim-trans=; domain=login.microsoftonline.com; expires=Fri, 08-Nov-2019 19:04:53 GMT; path=/; SameSite=None; secure; HttpOnly” }, { “name”: “X-Frame-Options”, “value”: “DENY” }, { “name”: “Strict-Transport-Security”, “value”: “max-age=31536000; includeSubDomains” }, { “name”: “X-Content-Type-Options”, “value”: “nosniff” }, { “name”: “X-XSS-Protection”, “value”: “1; mode=block” }, { “name”: “Set-Cookie”, “value”: “x-ms-gateway-slice=001-000; path=/; SameSite=None; secure; HttpOnly” }, { “name”: “Set-Cookie”, “value”: “stsservicecookie=cpim_te; path=/; secure; HttpOnly” }, { “name”: “Date”, “value”: “Sat, 09 Nov 2019 19:04:53 GMT” }, { “name”: “Content-Length”, “value”: “1359” } ], “cookies”: [ { “name”: “x-ms-cpim-rc:148118c7-8770-4346-900a-590aedfb918e”, “value”: “” }, { “name”: “x-ms-cpim-sso:navnob2c.onmicrosoft.com_0”, “value”: “m1.RP3BbsClW5XQVM+s.zoR66H3kXPuUX94F/tcPBw==.0.QGnjHX4eTe5vLHtrfAdtBkA0ZJK6aAaPM8CWVJSWvSLqR3JiWGuA0+9m9o2rYn2RUncXsHAlg3bAFD2rBSv69N96/niU3312pxLnuetVzCHHVneCRL0kw8OhYa5NQeHct+Vr4sC11K49f+9e5Cnvi8cVx/qntlWx0JWDqGpQhxFiSGJXBfk0sjr039GL7cvGCWezUbvjbQnz1cF6n8hCWqCk” }, { “name”: “x-ms-cpim-cache:x-1o-knobkop-5eb8ck9bw_0”, “value”: “” }, { “name”: “x-ms-cpim-trans”, “value”: “” }, { “name”: “x-ms-gateway-slice”, “value”: “001-000” }, { “name”: “stsservicecookie”, “value”: “cpim_te” } ], “content”: { “mimeType”: “text/html; charset=utf-8”, “size”: 44986, “comment”: “Response bodies are not included.” }, “redirectURL”: “https://loginservice.nav.no/callback?state=_JTWomMWhyZw6bZifoPHgUw-7OccK-hV9BKi1VaMQYk&code=eyJraWQiOiJhT05QQk9fWDV0bzNIX2tsMllSTjRFRGdUMkVvQ201bmNCNlB1MEhOSlNJIiwidmVyIjoiMS4wIiwiemlwIjoiRGVmbGF0ZSIsInNlciI6IjEuMCJ9.b5lGSnVxsolX3Wa1gqGh5qqhm8upQh3laxBhYbqC2FixHYog53-6ilhTGxNevcqYL-gFih4xwTqNYJuEH7ux-eRr8YoUcv7Mv1TO3U-VtddA1O7ZMF6mbu3L8DcOFqHR7OahL4j_QVZm9z-gAYFl_yZvAMmQ4Selk_uKAzvwLkjE57u4S61nArLSknOJDV8XwpO4Ow_iicpL5RC_dr4jaLGH6WH6bMgLrtQ2uNfb2KhYQYQhkTmkYjqgx7fgPbqddz0OOCF8PUIEL7sKpl1-d0Uv75iAqXUJofZlFVDcDfBoO6noxaLVkWmNjWvHWmKHbHImmOTD__XtExAMoMK8wg.LJS-OSzaHhkhVERs.LCBP0FbMPn9OKkej4fmYlN9fj-cgwYPCKSulz96qY06wrmMOFokm5Iies7nsPsS2SD5WJGw-D4vlso-ac-yjHqNI_s-KequNz5XiNjMS_gaJYh19bfivmKJmCxOJjrobA95FzBAkJaOHezJNDWP_tlfB-0wzD8Y5JYCYJGw3CXvhlQDtNH3vAprgkEtA9sHxzoz_ejzZwT2Xrb5z2aI8RUJI1Y2WDHLKo8uXfkROJDAajYtWKIm2LcaFwdtnm90kXGHFB7tIRF76L8sOgc2IuK6l3UBlFpJcsaPeY-bvGK9rMotjSKqZjAiIs_OTkcpL_GPNbpyiicjQWdVFLLf51ivWlHvdADrCxDH20yLWu6GiYZMHUW4YXCDODhmrZx4LmEp35v_1Wpji-1HeKH3X7gPgZXVjhL9bK0ApnyCsUy6Vi-P5KyEy8Ne6UV0UKQZQjl58SoV67UKrabt44Wr9CDvYHCQwBh4WwJ-3pw2lF4-FbwXYE9A3ssdbAI5sM9M8XHAt537KRWTgaXw1xmrEQ3VQ8q6nNBIUhEKdtr43-q8NULpc2Yh8Q8fFPhBaUbtYSEeRKl-vrpiKI2yB4deG8bz6dwtgCiHdQ9R81hPCloAqNgUHzIl0roZkyu1acw.BDHTKPyICH1GZs9SIr-Xqg”, “headersSize”: 2574, “bodySize”: 11337 }, “cache”: {}, “timings”: { “blocked”: 0, “dns”: 0, “connect”: 0, “ssl”: 0, “send”: 0, “wait”: 426, “receive”: 0 }, “time”: 426, “_securityState”: “secure”, “serverIPAddress”: “40.126.1.165”, “connection”: “443” }, { “pageref”: “page_3”, “startedDateTime”: “2019-11-09T20:04:53.489+01:00”, “request”: { “bodySize”: 0, “method”: “GET”,

There is plenty of guff here, but a picture emerges.

The first call

https://login.microsoftonline.com/navnob2c.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1a_idporten&response_type=code&client_id=45104d6a-f5bc-4e8c-b352-4bbfc9381f25&redirect_uri=https%3A%2F%2Floginservice.nav.no%2Fcallback&scope=openid+offline_access+45104d6a-f5bc-4e8c-b352-4bbfc9381f25&state=_JTWomMWhyZw6bZifoPHgUw-7OccK-hV9BKi1VaMQYk&nonce=HLPaFgxW368_-E6Rj5L6D0iT4yufUO6kydE21oT3QJE&level=Level3″

which redirects to

https://oidc.difi.no/idporten-oidc-provider/authorize?client_id=oidc_nav&redirect_uri=https%3a%2f%2flogin.microsoftonline.com%2fte%2fnavnob2c.onmicrosoft.com%2foauth2%2fauthresp&response_type=code&scope=openid&response_mode=form_post&nonce=%2fC9sCl2kb7TZMD4tPS1%2fAg%3d%3d&acr_values=Level3&state=StateProperties%3deyJTSUQiOiJ4LW1zLWNwaW0tcmM6MTQ4MTE4YzctODc3MC00MzQ2LTkwMGEtNTkwYWVkZmI5MThlIiwiVElEIjoiZmE2OGVkYzctZTg0OS00MzA2LThmZmItOTExYmYwMjkzZDZmIn0

On the way back
https://login.microsoftonline.com/te/navnob2c.onmicrosoft.com/oauth2/authresp
which redirects to

https://loginservice.nav.no/callback?state=_JTWomMWhyZw6bZifoPHgUw-7OccK-hV9BKi1VaMQYk&code=eyJraWQiOiJhT05QQk9fWDV0bzNIX2tsMllSTjRFRGdUMkVvQ201bmNCNlB1MEhOSlNJIiwidmVyIjoiMS4wIiwiemlwIjoiRGVmbGF0ZSIsInNlciI6IjEuMCJ9.b5lGSnVxsolX3Wa1gqGh5qqhm8upQh3laxBhYbqC2FixHYog53-6ilhTGxNevcqYL-gFih4xwTqNYJuEH7ux-eRr8YoUcv7Mv1TO3U-VtddA1O7ZMF6mbu3L8DcOFqHR7OahL4j_QVZm9z-gAYFl_yZvAMmQ4Selk_uKAzvwLkjE57u4S61nArLSknOJDV8XwpO4Ow_iicpL5RC_dr4jaLGH6WH6bMgLrtQ2uNfb2KhYQYQhkTmkYjqgx7fgPbqddz0OOCF8PUIEL7sKpl1-d0Uv75iAqXUJofZlFVDcDfBoO6noxaLVkWmNjWvHWmKHbHImmOTD__XtExAMoMK8wg.LJS-OSzaHhkhVERs.LCBP0FbMPn9OKkej4fmYlN9fj-cgwYPCKSulz96qY06wrmMOFokm5Iies7nsPsS2SD5WJGw-D4vlso-ac-yjHqNI_s-KequNz5XiNjMS_gaJYh19bfivmKJmCxOJjrobA95FzBAkJaOHezJNDWP_tlfB-0wzD8Y5JYCYJGw3CXvhlQDtNH3vAprgkEtA9sHxzoz_ejzZwT2Xrb5z2aI8RUJI1Y2WDHLKo8uXfkROJDAajYtWKIm2LcaFwdtnm90kXGHFB7tIRF76L8sOgc2IuK6l3UBlFpJcsaPeY-bvGK9rMotjSKqZjAiIs_OTkcpL_GPNbpyiicjQWdVFLLf51ivWlHvdADrCxDH20yLWu6GiYZMHUW4YXCDODhmrZx4LmEp35v_1Wpji-1HeKH3X7gPgZXVjhL9bK0ApnyCsUy6Vi-P5KyEy8Ne6UV0UKQZQjl58SoV67UKrabt44Wr9CDvYHCQwBh4WwJ-3pw2lF4-FbwXYE9A3ssdbAI5sM9M8XHAt537KRWTgaXw1xmrEQ3VQ8q6nNBIUhEKdtr43-q8NULpc2Yh8Q8fFPhBaUbtYSEeRKl-vrpiKI2yB4deG8bz6dwtgCiHdQ9R81hPCloAqNgUHzIl0roZkyu1acw.BDHTKPyICH1GZs9SIr-Xqg

This is an Oauth transaction where Microsoft is the identity provider for NAV. The result is a JWT token passed from Microsoft to NAV. Microsoft in turn calls on Difi to establish the user’s identity.
At first look, Microsoft passes back more information than it receives. The call back from Difi to MS is a POST, but it contains only two parameters

MS to Difi

client_id: oidc_nav
redirect_uri: https%3a%2f%2flogin.microsoftonline.com%2fte%2fnavnob2c.onmicrosoft.com%2foauth2%2fauthresp
response_type: code
scope: openid
response_mode: form_post
nonce: %2fC9sCl2kb7TZMD4tPS1%2fAg%3d%3d
acr_values: Level3
state: StateProperties%3deyJTSUQiOiJ4LW1zLWNwaW0tcmM6MTQ4MTE4YzctODc3MC00MzQ2LTkwMGEtNTkwYWVkZmI5MThlIiwiVElEIjoiZmE2OGVkYzctZTg0OS00MzA2LThmZmItOTExYmYwMjkzZDZmIn0

Difi to MS
code: MryzERHWMbxfjnvLYEiJpw7_ojLZ4qKowtDMHytb7I0
state: StateProperties=eyJTSUQiOiJ4LW1zLWNwaW0tcmM6MTQ4MTE4YzctODc3MC00MzQ2LTkwMGEtNTkwYWVkZmI5MThlIiwiVElEIjoiZmE2OGVkYzctZTg0OS00MzA2LThmZmItOTExYmYwMjkzZDZmIn0

MS to NAV
state: _JTWomMWhyZw6bZifoPHgUw-7OccK-hV9BKi1VaMQYk&code=eyJraWQiOiJhT05QQk9fWDV0bzNIX2tsMllSTjRFRGdUMkVvQ201bmNCNlB1MEhOSlNJIiwidmVyIjoiMS4wIiwiemlwIjoiRGVmbGF0ZSIsInNlciI6IjEuMCJ9.b5lGSnVxsolX3Wa1gqGh5qqhm8upQh3laxBhYbqC2FixHYog53-6ilhTGxNevcqYL-gFih4xwTqNYJuEH7ux-eRr8YoUcv7Mv1TO3U-VtddA1O7ZMF6mbu3L8DcOFqHR7OahL4j_QVZm9z-gAYFl_yZvAMmQ4Selk_uKAzvwLkjE57u4S61nArLSknOJDV8XwpO4Ow_iicpL5RC_dr4jaLGH6WH6bMgLrtQ2uNfb2KhYQYQhkTmkYjqgx7fgPbqddz0OOCF8PUIEL7sKpl1-d0Uv75iAqXUJofZlFVDcDfBoO6noxaLVkWmNjWvHWmKHbHImmOTD__XtExAMoMK8wg.LJS-OSzaHhkhVERs.LCBP0FbMPn9OKkej4fmYlN9fj-cgwYPCKSulz96qY06wrmMOFokm5Iies7nsPsS2SD5WJGw-D4vlso-ac-yjHqNI_s-KequNz5XiNjMS_gaJYh19bfivmKJmCxOJjrobA95FzBAkJaOHezJNDWP_tlfB-0wzD8Y5JYCYJGw3CXvhlQDtNH3vAprgkEtA9sHxzoz_ejzZwT2Xrb5z2aI8RUJI1Y2WDHLKo8uXfkROJDAajYtWKIm2LcaFwdtnm90kXGHFB7tIRF76L8sOgc2IuK6l3UBlFpJcsaPeY-bvGK9rMotjSKqZjAiIs_OTkcpL_GPNbpyiicjQWdVFLLf51ivWlHvdADrCxDH20yLWu6GiYZMHUW4YXCDODhmrZx4LmEp35v_1Wpji-1HeKH3X7gPgZXVjhL9bK0ApnyCsUy6Vi-P5KyEy8Ne6UV0UKQZQjl58SoV67UKrabt44Wr9CDvYHCQwBh4WwJ-3pw2lF4-FbwXYE9A3ssdbAI5sM9M8XHAt537KRWTgaXw1xmrEQ3VQ8q6nNBIUhEKdtr43-q8NULpc2Yh8Q8fFPhBaUbtYSEeRKl-vrpiKI2yB4deG8bz6dwtgCiHdQ9R81hPCloAqNgUHzIl0roZkyu1acw.BDHTKPyICH1GZs9SIr-Xqg

Being bigger is not neccesarily important: the JSON in a JWT token contains metadata. And in this case the JWT token is also encrypted.
However, the stateproperties passed back and forth between MS and Difi is not

It contains only the base64 encoded JSON
{“SID”:”x-ms-cpim-rc:148118c7-8770-4346-900a-590aedfb918e”,”TID”:”fa68edc7-e849-4306-8ffb-911bf0293d6f”}

If this is not encrypted, why is the JWT encrypted ? Either both or neither to my mind. The question is not confidentiality here, these are merely temprary reference values, but rather integrity. In this case I’d say both should have been encrypted. It seems the connection between MS and Difi is not robust.
If MS maintains state such that the authorization token and stateproperties received from Difi is matched with the statepropertes sent to Difi – then fine. If not, then not fine at all.

What is in the JWT ? It is too big for only metadata. And nothing about the user was passed from Difi to MS, so if the JWT contain user info, where did it come from?

But this begs a larger question. Why is microsoftonline.com involved at all ?
Because it is not necessary, obviously. Another example from another government service. They set up a much tighter login, still using the same federation partner Bankid.

Similar domain name hit histogram as above

52 idporten.difi.no
20 anmeldelse.pub.politiet.no
14 csfe.bankid.no
3 oidc.difi.no

Clearly a very much tighter operation here. Since the government federation broker is difi.no here to the minimum number of domains, including the ID-provider, is 3. A first look a total of four domains involved must be considered a solid piece of work. Everything has a dot-no domain. So GDPR should not be a concern.
But perhaps the details show some things slipping through where it shouldn’t.

“url”: “https://anmeldelse.pub.politiet.no/webjars/anmeldelse/skjema.html?type=sykkel”, “httpVersion”: “HTTP/2.0”, “headers”: [ { “name”: “Host”, “value”: “anmeldelse.pub.politiet.no” }, { “name”: “User-Agent”, “value”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0” }, { “name”: “Accept”, “value”: “text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8” }, { “name”: “Accept-Language”, “value”: “en-GB,en;q=0.5” }, { “name”: “Accept-Encoding”, “value”: “gzip, deflate, br” }, { “name”: “DNT”, “value”: “1” }, { “name”: “Connection”, “value”: “keep-alive” }, { “name”: “Referer”, “value”: “https://anmeldelse.pub.politiet.no/webjars/anmeldelse/index.html?type=sykkel” }, { “name”: “Cookie”, “value”: “XSRF-TOKEN=a308a8d1-ffa5-4591-9c1e-6d2e0af98e8c; ApplicationGatewayAffinity=218f983d4932882bd40a98762d95d965a6cdbef861a68362433bb959d0589ee0” }, { “name”: “Upgrade-Insecure-Requests”, “value”: “1” }, { “name”: “TE”, “value”: “Trailers” } ], “cookies”: [ { “name”: “XSRF-TOKEN”, “value”: “a308a8d1-ffa5-4591-9c1e-6d2e0af98e8c” }, { “name”: “ApplicationGatewayAffinity”, “value”: “218f983d4932882bd40a98762d95d965a6cdbef861a68362433bb959d0589ee0” } ], “queryString”: [ { “name”: “type”, “value”: “sykkel” } ], “headersSize”: 627 }, “response”: { “status”: 302, “statusText”: “Found”, “httpVersion”: “HTTP/2.0”, “headers”: [ { “name”: “cache-control”, “value”: “no-cache, no-store, max-age=0, must-revalidate” }, { “name”: “pragma”, “value”: “no-cache” }, { “name”: “expires”, “value”: “0” }, { “name”: “location”, “value”: “https://anmeldelse.pub.politiet.no/oauth2/authorization/idporten” }, { “name”: “set-cookie”, “value”: “JSESSIONID=53848E5BB6B11F125EB7524836844FEB; Path=/; Secure; HttpOnly” }, { “name”: “x-content-type-options”, “value”: “nosniff” }, { “name”: “x-xss-protection”, “value”: “1; mode=block” }, { “name”: “strict-transport-security”, “value”: “max-age=1036800 ; includeSubDomains” }, { “name”: “x-frame-options”, “value”: “DENY” }, { “name”: “content-security-policy”, “value”: “default-src ‘self’;connect-src ‘self’ https://*.difi.no;style-src ‘self’ ‘unsafe-inline’;img-src ‘self’ data:” }, { “name”: “date”, “value”: “Sun, 05 Jan 2020 10:33:29 GMT” }, { “name”: “content-length”, “value”: “0” }, { “name”: “X-Firefox-Spdy”, “value”: “h2” } ], “cookies”: [ { “name”: “JSESSIONID”, “value”: “53848E5BB6B11F125EB7524836844FEB” } ], “content”: { “mimeType”: “text/html; charset=UTF-8”, “size”: 15043, “comment”: “Response bodies are not included.” }, “redirectURL”: “https://anmeldelse.pub.politiet.no/oauth2/authorization/idporten”, “headersSize”: 639, “bodySize”: 15682 }, “cache”: {}, “timings”: { “blocked”: 0, “dns”: 0, “connect”: 0, “ssl”: 0, “send”: 0, “wait”: 69, “receive”: 0 }, “time”: 69, “_securityState”: “secure”, “serverIPAddress”: “40.85.119.201”, “connection”: “443” }, { “pageref”: “page_1”, “startedDateTime”: “2020-01-05T11:33:28.807+01:00”, “request”: { “bodySize”: 0, “method”: “GET”,

“url”: “https://anmeldelse.pub.politiet.no/oauth2/authorization/idporten”, “httpVersion”: “HTTP/2.0”, “headers”: [ { “name”: “Host”, “value”: “anmeldelse.pub.politiet.no” }, { “name”: “User-Agent”, “value”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0” }, { “name”: “Accept”, “value”: “text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8” }, { “name”: “Accept-Language”, “value”: “en-GB,en;q=0.5” }, { “name”: “Accept-Encoding”, “value”: “gzip, deflate, br” }, { “name”: “Referer”, “value”: “https://anmeldelse.pub.politiet.no/webjars/anmeldelse/index.html?type=sykkel” }, { “name”: “DNT”, “value”: “1” }, { “name”: “Connection”, “value”: “keep-alive” }, { “name”: “Cookie”, “value”: “XSRF-TOKEN=a308a8d1-ffa5-4591-9c1e-6d2e0af98e8c; ApplicationGatewayAffinity=218f983d4932882bd40a98762d95d965a6cdbef861a68362433bb959d0589ee0; JSESSIONID=53848E5BB6B11F125EB7524836844FEB” }, { “name”: “Upgrade-Insecure-Requests”, “value”: “1” }, { “name”: “TE”, “value”: “Trailers” } ], “cookies”: [ { “name”: “XSRF-TOKEN”, “value”: “a308a8d1-ffa5-4591-9c1e-6d2e0af98e8c” }, { “name”: “ApplicationGatewayAffinity”, “value”: “218f983d4932882bd40a98762d95d965a6cdbef861a68362433bb959d0589ee0” }, { “name”: “JSESSIONID”, “value”: “53848E5BB6B11F125EB7524836844FEB” } ], “queryString”: [], “headersSize”: 659 }, “response”: { “status”: 302, “statusText”: “Found”, “httpVersion”: “HTTP/2.0”, “headers”: [ { “name”: “cache-control”, “value”: “no-cache, no-store, max-age=0, must-revalidate” }, { “name”: “pragma”, “value”: “no-cache” }, { “name”: “expires”, “value”: “0” }, { “name”: “location”, “value”: “https://oidc.difi.no/idporten-oidc-provider/authorize?response_type=code&client_id=d57e1963-4d31-418d-a4aa-85329c0a5971&scope=openid%20profile&state=kzSBcqvpGyGRUMEQ8sejiIJYcQxzTslzRfW4lG1_t7U%3D&redirect_uri=https://anmeldelse.pub.politiet.no/login/oauth2/code/idporten&nonce=GAYtjS6wlIvJ0veysvHFP0Vs3Mxyy1_sywqQq1X-IfI” }, { “name”: “x-content-type-options”, “value”: “nosniff” }, { “name”: “x-xss-protection”, “value”: “1; mode=block” }, { “name”: “strict-transport-security”, “value”: “max-age=1036800 ; includeSubDomains” }, { “name”: “x-frame-options”, “value”: “DENY” }, { “name”: “content-security-policy”, “value”: “default-src ‘self’;connect-src ‘self’ https://*.difi.no;style-src ‘self’ ‘unsafe-inline’;img-src ‘self’ data:” }, { “name”: “date”, “value”: “Sun, 05 Jan 2020 10:33:29 GMT” }, { “name”: “content-length”, “value”: “0” }, { “name”: “X-Firefox-Spdy”, “value”: “h2” } ], “cookies”: [], “content”: { “mimeType”: “text/html; charset=UTF-8”, “size”: 15043, “comment”: “Response bodies are not included.” }, “redirectURL”: “https://oidc.difi.no/idporten-oidc-provider/authorize?response_type=code&client_id=d57e1963-4d31-418d-a4aa-85329c0a5971&scope=openid%20profile&state=kzSBcqvpGyGRUMEQ8sejiIJYcQxzTslzRfW4lG1_t7U%3D&redirect_uri=https://anmeldelse.pub.politiet.no/login/oauth2/code/idporten&nonce=GAYtjS6wlIvJ0veysvHFP0Vs3Mxyy1_sywqQq1X-IfI”, “headersSize”: 812, “bodySize”: 15855 }, “cache”: {}, “timings”: { “blocked”: 0, “dns”: 2, “connect”: 0, “ssl”: 0, “send”: 0, “wait”: 53, “receive”: 0 }, “time”: 55, “_securityState”: “secure”, “serverIPAddress”: “40.85.119.201”, “connection”: “443” }, { “pageref”: “page_1”, “startedDateTime”: “2020-01-05T11:33:28.860+01:00”, “request”: { “bodySize”: 0, “method”: “GET”,

“url”: “https://oidc.difi.no/idporten-oidc-provider/authorize?response_type=code&client_id=d57e1963-4d31-418d-a4aa-85329c0a5971&scope=openid%20profile&state=kzSBcqvpGyGRUMEQ8sejiIJYcQxzTslzRfW4lG1_t7U%3D&redirect_uri=https://anmeldelse.pub.politiet.no/login/oauth2/code/idporten&nonce=GAYtjS6wlIvJ0veysvHFP0Vs3Mxyy1_sywqQq1X-IfI”

“Location”: “https://idporten.difi.no/opensso/SSORedirect/metaAlias/norge.no/idp4?SAMLRequest=nZRNj9owEIbv%2FRWR7yGfQLBIVix0VaRtoZDtoZfK2JPFUmKntsOy%2F75OIDSVWg49RbJn3nk9z0zmD%2BeqdE6gNJciRcHIRw4IKhkXryl6yZ%2FcBD1kH%2BaaVGVY40VjjmIHPxvQxlloDcrYvKUUuqlA7UGdOIWX3XOKjsbUGnue5IyOGC%2F4SEgcx5HHWS2VAeG2N26t5IkzUB7pxehVDDkrW4QLYjpnvV6f3mt6sgahtfT2%2B80OGFdAjVeBIYuSE%2B0JqV6hDbN5MXKepKLQPSJFBSk1IGe9StGPSciSMKax74eH6XhSRAkNWZQExWE2IYxENkzrBtZCGyJMikI%2F9F0%2FcP1xHvg4inA4GyXT8XfkbJU0ksrykYtLDxslsCSaayxIBRobiveLz884HPn4cAnS%2BFOeb93tZp8j51vPImxZWDpC40v372vV18Iou8DCnWM1VLgvcCOAsiG0uTeUy%2BYVwx%2FPFkBrUl%2FVK3ZfuuXBiCHW20Y8wpGUxabI2HgKwWwSuTGLAjcOEuaSmBA3GUfhjPpkPJsGc2%2BQMPf%2BKJ71U%2FnFFlyvtrLk9N1ZlKV8WyogBlJkVAMd9YqY%2BxbbE87cogvFdQtB20IGOfttq%2F%2B1IaVtCKgUDbuDvJuL61oA6%2BbL7oSBs3GWsqqJ4rolWnHBq6a6ERoGLkvb%2Fx0U%2F8XrbhjFtNW2x1v7eZOKtTNq1wRYrojQ7T71kP%2FmKLte%2FuOFv6%2BHP4fsFw%3D%3D&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=WhMFeI5wORYVEVNcqzjS6AYN8jcMnpMPfARFCR0jl2X%2F80HKB55L7nUEl8BCAUe48oOOVfy7tFburXcqMfFPR%2FLPiikniI1m7a%2Fy0hucr%2FGkZMOChi%2Bf%2BHwHA3GAj9kedHgy%2BCO5zp%2FS3EtQ9LQ5WIA3zkr%2BQQ%2BElV41zOIBVAotNnM9FG7M39tCwU2q%2BnCHZ1u4zrZQNtDy%2BEmucmcdWrSv7RIZoCToJ3qE%2F7BeTWPP9xLdKap9CmVe7j0i52%2F23TLK0oQxJ2UfbMEtf5R89FGZ3tMzP3e5297Etbs6vsq9vUjUzkyik6POPQBa46w6mmvRjPM3ikZSpN1pUP751A%3D%3D&locale=nb

“url”: “https://idporten.difi.no/opensso/SSORedirect/metaAlias/norge.no/idp4?SAMLRequest=nZRNj9owEIbv%2FRWR7yGfQLBIVix0VaRtoZDtoZfK2JPFUmKntsOy%2F75OIDSVWg49RbJn3nk9z0zmD%2BeqdE6gNJciRcHIRw4IKhkXryl6yZ%2FcBD1kH%2BaaVGVY40VjjmIHPxvQxlloDcrYvKUUuqlA7UGdOIWX3XOKjsbUGnue5IyOGC%2F4SEgcx5HHWS2VAeG2N26t5IkzUB7pxehVDDkrW4QLYjpnvV6f3mt6sgahtfT2%2B80OGFdAjVeBIYuSE%2B0JqV6hDbN5MXKepKLQPSJFBSk1IGe9StGPSciSMKax74eH6XhSRAkNWZQExWE2IYxENkzrBtZCGyJMikI%2F9F0%2FcP1xHvg4inA4GyXT8XfkbJU0ksrykYtLDxslsCSaayxIBRobiveLz884HPn4cAnS%2BFOeb93tZp8j51vPImxZWDpC40v372vV18Iou8DCnWM1VLgvcCOAsiG0uTeUy%2BYVwx%2FPFkBrUl%2FVK3ZfuuXBiCHW20Y8wpGUxabI2HgKwWwSuTGLAjcOEuaSmBA3GUfhjPpkPJsGc2%2BQMPf%2BKJ71U%2FnFFlyvtrLk9N1ZlKV8WyogBlJkVAMd9YqY%2BxbbE87cogvFdQtB20IGOfttq%2F%2B1IaVtCKgUDbuDvJuL61oA6%2BbL7oSBs3GWsqqJ4rolWnHBq6a6ERoGLkvb%2Fx0U%2F8XrbhjFtNW2x1v7eZOKtTNq1wRYrojQ7T71kP%2FmKLte%2FuOFv6%2BHP4fsFw%3D%3D&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=WhMFeI5wORYVEVNcqzjS6AYN8jcMnpMPfARFCR0jl2X%2F80HKB55L7nUEl8BCAUe48oOOVfy7tFburXcqMfFPR%2FLPiikniI1m7a%2Fy0hucr%2FGkZMOChi%2Bf%2BHwHA3GAj9kedHgy%2BCO5zp%2FS3EtQ9LQ5WIA3zkr%2BQQ%2BElV41zOIBVAotNnM9FG7M39tCwU2q%2BnCHZ1u4zrZQNtDy%2BEmucmcdWrSv7RIZoCToJ3qE%2F7BeTWPP9xLdKap9CmVe7j0i52%2F23TLK0oQxJ2UfbMEtf5R89FGZ3tMzP3e5297Etbs6vsq9vUjUzkyik6POPQBa46w6mmvRjPM3ikZSpN1pUP751A%3D%3D&locale=nb”

“Location”: “https://idporten.difi.no:443/opensso/UI/Login?realm=/norge.no&spEntityID=oidc.difi.no&service=IDPortenLevel3List&goto=http://idporten.difi.no/opensso/SSORedirect/metaAlias/norge.no/idp4?ReqID%3D_62d824c4002b756f38c2d381fb96ada3%26index%3Dnull%26acsURL%3Dhttps://oidc.difi.no:443/idporten-oidc-provider/assertionconsumer%26spEntityID%3Doidc.difi.no%26binding%3Durn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST

“url”: “https://idporten.difi.no/opensso/bidresponse”

“Location”: “https://idporten.difi.no:443/opensso/UI/Login?realm=norge.no&ForceAuth=&gx_charset=UTF-8&locale=nb&goto=http://idporten.difi.no/opensso/SSORedirect/metaAlias/norge.no/idp4?ReqID=_62d824c4002b756f38c2d381fb96ada3&service=BankIDResponse

“url”: “https://idporten.difi.no/opensso/UI/Login?realm=norge.no&ForceAuth=&gx_charset=UTF-8&locale=nb&goto=http://idporten.difi.no/opensso/SSORedirect/metaAlias/norge.no/idp4?ReqID=_62d824c4002b756f38c2d381fb96ada3&service=BankIDResponse”

“Location”: “https://idporten.difi.no/opensso/SSORedirect/metaAlias/norge.no/idp4?ReqID=_62d824c4002b756f38c2d381fb96ada3

“url”: “https://oidc.difi.no/idporten-oidc-provider/assertionconsumer”

“Location”: “https://oidc.difi.no/idporten-oidc-provider/consent?mid=_62d824c4002b756f38c2d381fb96ada3

“url”: “https://oidc.difi.no/idporten-oidc-provider/consent?mid=_62d824c4002b756f38c2d381fb96ada3”

“Location”: “https://anmeldelse.pub.politiet.no/login/oauth2/code/idporten?code=gtJFV1p5nKatkV7FyXkU02jhcfPFgEoz47k4q7PnCxY&state=kzSBcqvpGyGRUMEQ8sejiIJYcQxzTslzRfW4lG1_t7U%3D

“url”: “https://anmeldelse.pub.politiet.no/login/oauth2/code/idporten?code=gtJFV1p5nKatkV7FyXkU02jhcfPFgEoz47k4q7PnCxY&state=kzSBcqvpGyGRUMEQ8sejiIJYcQxzTslzRfW4lG1_t7U%3D”, “httpVersion”: “HTTP/2.0”, “headers”: [ { “name”: “Host”, “value”: “anmeldelse.pub.politiet.no” }, { “name”: “User-Agent”, “value”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0” }, { “name”: “Accept”, “value”: “text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8” }, { “name”: “Accept-Language”, “value”: “en-GB,en;q=0.5” }, { “name”: “Accept-Encoding”, “value”: “gzip, deflate, br” }, { “name”: “Referer”, “value”: “https://idporten.difi.no/” }, { “name”: “DNT”, “value”: “1” }, { “name”: “Connection”, “value”: “keep-alive” }, { “name”: “Cookie”, “value”: “XSRF-TOKEN=a308a8d1-ffa5-4591-9c1e-6d2e0af98e8c; ApplicationGatewayAffinity=218f983d4932882bd40a98762d95d965a6cdbef861a68362433bb959d0589ee0; JSESSIONID=53848E5BB6B11F125EB7524836844FEB” }, { “name”: “Upgrade-Insecure-Requests”, “value”: “1” }, { “name”: “TE”, “value”: “Trailers” } ], “cookies”: [ { “name”: “XSRF-TOKEN”, “value”: “a308a8d1-ffa5-4591-9c1e-6d2e0af98e8c” }, { “name”: “ApplicationGatewayAffinity”, “value”: “218f983d4932882bd40a98762d95d965a6cdbef861a68362433bb959d0589ee0” }, { “name”: “JSESSIONID”, “value”: “53848E5BB6B11F125EB7524836844FEB” } ], “queryString”: [ { “name”: “code”, “value”: “gtJFV1p5nKatkV7FyXkU02jhcfPFgEoz47k4q7PnCxY” }, { “name”: “state”, “value”: “kzSBcqvpGyGRUMEQ8sejiIJYcQxzTslzRfW4lG1_t7U=” } ], “headersSize”: 707 }, “response”: { “status”: 302, “statusText”: “Found”, “httpVersion”: “HTTP/2.0”, “headers”: [ { “name”: “cache-control”, “value”: “no-cache, no-store, max-age=0, must-revalidate” }, { “name”: “pragma”, “value”: “no-cache” }, { “name”: “expires”, “value”: “0” }, { “name”: “location”, “value”: “https://anmeldelse.pub.politiet.no/webjars/anmeldelse/skjema.html?type=sykkel” }, { “name”: “set-cookie”, “value”: “JSESSIONID=93798A700538A6625D75042F2816EB6B; Path=/; Secure; HttpOnly” }, { “name”: “set-cookie”, “value”: “XSRF-TOKEN=; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure” }, { “name”: “set-cookie”, “value”: “XSRF-TOKEN=76c82040-160f-471c-a4e0-4d85e9c6b361; Path=/; Secure” }, { “name”: “x-content-type-options”, “value”: “nosniff” }, { “name”: “x-xss-protection”, “value”: “1; mode=block” }, { “name”: “strict-transport-security”, “value”: “max-age=1036800 ; includeSubDomains” }, { “name”: “x-frame-options”, “value”: “DENY” }, { “name”: “content-security-policy”, “value”: “default-src ‘self’;connect-src ‘self’ https://*.difi.no;style-src ‘self’ ‘unsafe-inline’;img-src ‘self’ data:” }, { “name”: “date”, “value”: “Sun, 05 Jan 2020 10:34:20 GMT” }, { “name”: “content-length”, “value”: “0” }, { “name”: “X-Firefox-Spdy”, “value”: “h2” } ], “cookies”: [ { “name”: “JSESSIONID”, “value”: “93798A700538A6625D75042F2816EB6B” }, { “name”: “XSRF-TOKEN”, “value”: “” }, { “name”: “XSRF-TOKEN”, “value”: “76c82040-160f-471c-a4e0-4d85e9c6b361” } ], “content”: { “mimeType”: “text/html”, “size”: 724, “comment”: “Response bodies are not included.” }, “redirectURL”: “https://anmeldelse.pub.politiet.no/webjars/anmeldelse/skjema.html?type=sykkel”, “headersSize”: 794, “bodySize”: 1362 }, “cache”: {}, “timings”: { “blocked”: 0, “dns”: 1, “connect”: 0, “ssl”: 0, “send”: 0, “wait”: 284, “receive”: 0 }, “time”: 285, “_securityState”: “secure”, “serverIPAddress”: “40.85.119.201”, “connection”: “443” }, { “pageref”: “page_1”, “startedDateTime”: “2020-01-05T11:34:19.748+01:00”, “request”: { “bodySize”: 0, “method”: “GET”,

Both Oauth and SAML are involed, but there is nothing wrong with that. For my money SAML is more robust (let’s hear it for signed and encrypted tokens contaning usefull data!), but OAuth is of course newer and leaner if you think byte count in HTTP traffic matters.

Token based API access control has a critical flaw

I’ve written on this subject before. I come back to the subject because I keep coming across this problem. Granted where or not it is a problem depends on how you look at things. My view is from the point of view of robustness and fail-safety.

I work with programmers quite a bit and theirs is to deliver functionality out the door. Which is understandable: that is what they are measured on.

Then I come along later and try to track down a problem. Over privileged service accounts which is what these API access tokens amount to is a perennial problem. Leaving aside for the moment the security aspect of it. A service account and an API access token can be poorly implemented in two main ways. Be given too much access privileges, let’s call that a Type 1 fault; and be shared by too many different entities, call that Type 2. I’ve seen plenty of both. Okta is a good(bad) example of the former. Their SaaS REST API only grants one kind of access token. To everything.  Type 1 fault as bad as can be.

Programmers using the API for Okta can then keep reusing the same access token – it is just a text string after all – to any extent rather than going to the rigmarole of issuing another. Yes, it happens. A lot. Type 2 fault. The API access tokens are usually valid for a long time since they are meant to be used by other applications, hence the service account equivalence, but can be selectively revoked and at least in Okta there is good overview of currently valid tokens. But not what has been going on with them and what they have been used for.

In Unix/Linux these API tokens are like having multiple root accounts that have been shared with people you do not know and being used for unknown things. No one would call that a satisfactory state of affairs on a *x server system. But it is rarely expressed in those terms.

The root account comparison is apt. On unix -like systems the root user is not subject to OS-level access control. Access is unlimited. Switching to any other user however souped-up, is better. But it involves actually implementing some access control: groups and permissions in a unix-like system. Which can be laborious – and worse, error prone. So let’s just give it root – at least it will work.

Yes, laziness. The malicious user/intruders best friend.  API access tokens are employed on great many platforms but since we call them API access tokens rather than user/service accounts, little or no scrutiny is ever applied to them.

Now we have these API tokens with good-like system powers. Revocable, sure, but does that ever happen ?

Funny symptoms on OpenAM when session handling is under strain.

Of late I have been examining  an intermittent error situation at a large OpenAM implementation. Several aspects of the implementation are not in accordance with the recommendation of the vendor, or even good practice. But that has afforded some very good learning opportunities. As is often the case when straying from the preferred path.

The deployment there are four OpenAM instances and four peer-to-peer replicated OpenDJ instances for data storage.

OpenAM keeps policy, configuration and session information in a directory. OpenDJ in this scenario. It is for obvious reasons recommended to keep the session store (it takes more load and does not need a backup) separate from the policy and configuration store.

An early clue was that the error conditions where resolvable with restarts. Clearly this was not fundamentally a policy matter. Policies persist across restarts. Sessions however, do not. Following up on this it was discovered that the sessions store and policy store where collocated.

OpenAM has caching on session token validation operations. So there would be no need to ask the directory everytime a session token is to be validated. But this is an object cache, not a search cache. So the session object can be cached on the OpenAM instance but if there is an attempt to validate a non-existent token, that attempt would result in a search against the underlying session object store. Every time. Examination of the search logs on the object store revealed that between 12% and 40% of token search operations were for tokens that did not exist.

It gets worse. Since the customer had declined to implement stickyness on the load balancer in front of the multiple OpenAM instances, users were sprayed across all of them. This leads to an excessive number of session token modification operations. Quite a large number of them in fact; Many tokens were modified hundreds of times. And with all modifications replicated across all of the directory store instances, the load on the OpenDJ instances is considerable.

But wait, it gets worse still. Forgerock is quite adamant that there can be no load balancing going on between the OpenAM and directories used as session store. In this design there are four OpenDJ OpenDJ instances used for sessions store, one designated for each OpenAM instance. Should one OpenDJ instance become unavailable “it’s” OpenAM instance will use one of the others, but otherwise the OpenAM instance will used it’s designated OpenDJ instance for all session token operations.

One can of course argue about what constitutes load balancing but I think of it as being chiefly about load distribution, with or with out stickyness. This design I would describe the OpenAM to OpenDJ connection to load balanced with permanent stickyness.

Does this matter ? In a replicated environment all the OpenDJ instances will be equal. Ideally, no. But not always. There will always be some replication delay. The problem here was the users being distributed across all OpenAM instances. Meaning that the same token operation could arrive at two, or more, different OpenAM instances practically simultaneously. Replication is fast in a good network and with good indexing. But it does not take zero time. If different OpenAM instances uses different OpenDJ instances as session token store, there will be errors. Probably not many, but ones likely to increase in frequency with increasing system load.

Ok. How to determine this. First: have plenty of logging on the OpenDJs. The search request for session tokens are easy to identity in the OpenDJ access log. They are base-level searches and therefore simple to extract reliably with an egrep statement. The same with failures to find a token. In fact directly related to the base level searches for tokens. A base level search when the base object does not exist produces an error to that effect. In this case the access log clearly states that the session token object is not present. Very convenient. And egrep-able.

So it is easy the get a list of tokens being searched for and which ones were not found. Extract these list from all OpenDJ instances within the same time period – say one hour. And determine if there where any failed token searches on any instance that succeeded on any of the others. There were.

 

We all gripe about vendor documentation. And Forerock has had some doosies. But there is usually good advice in there. Don’t ignore it without very good reason backed up by observational data.

The short and sweet on OpenAM, play nice with your session handling.

true desktop Single Sign-on for any web based application ?… get out of here.

Single SIgn-on, SSO for short, is an an attractive but elusive thing. Log into to your dekstop PC and be signed in to all your other applications – be they local or remote.  Your cloud provided business applications: Office 365, Amazon Web Services. Your online news site: The Economist etc.  Without having to enter username and password again. This does sound attractive.

So much so that some have found it expedient to sell something as SSO which strictly speaking is only single-login. There are tools for propagating usernames and synchronizing users stores. But they don’t log you in when you need to. You still have to enter your username and password. This is not SSO, merely single provisioning. Helpful, but still a nuisance with repeated entering of login information. What we want is true Single Sign-on.

All those login names and passwords. If you consistently use only your email address (and always the same one) as user name. Perhaps even, incautiously use the same password everywhere. There is sheer nuisance of it all.  Which in and of it self is enough to make people use the same password everywhere. This makes corporate systems vulnerable. If someone has used a password in an external system and this system is compromised, and the password revealed. Well, the attacker now has a very good password first guess for further attacks. So SSO which obviates the practical need to unified login information, but particularly the re-use of passwords, is much needed.

Such solutions do exists. User federation happen in many ways. You can now sing in to many applications simply by using your login to Facebook. Microsoft provides ADFS which allows SSO to many applications in the Windows sphere, most particularly Office 365, from you Windows desktop. This is what we want SSO from the desktop, but without the limitations of ADFS. We want to be able to login anywhere, not just to places that have been configured for ADFS.

For the purposes of this article I’ll limit myself to Sing-on part – the actual loging in. This presupposes the existence of an account in the target system, leaving just-in-time-provisioning aside (but see here for exploration on the topic of account-less access) which I will assume is already in place. There are any number of ways to provision accounts. and to the extent that this is a one-time thing, not really much of a bother for the end user.

Recently I had occasion to explore the identity management tools from Okta (www.okta.com) which promised to deliver on this tall order.

 

What follows is not a complete “cook book.” but it will include all the steps I went through , in order, to put in place true desktop SSO using the Okta framework. Both for an application that accepts SAML based federated login: Here I picked Amazon Web Services, AWS, for the demonstration. And one that just has a username/password login: Here I selected The Economist.

 

 

The Okta SSO architecture contain the following components:

The user’s Windows desktop PC.

The Windows domain controller, DC, to which it subscribes,

The Okta server at https://<your domain>.okta.com, When your organization subscribed to Okta, this is set up for you with a sub-domain name of  your choosing. There is also an administration domain name of the form <yourdomain>-admin,okta.com,

The user’s browser,The SSO is only for web based applications. A browser is always employed in their access.

The plugin provided by Okta for that browser. The supported browsers are Internet Explorer, Mozilla Firefox, Google Chrome and Safari. This plugin is essential for populating login fields for non-SAML based logins.

Okta agent for the Windows DC. This agent must be installed somewhere in you corporate infrastructure on a Windows server with direct access to the DC. In this case it was installed directly on the DC.

Okta’s Integrated Windows Authentication, IWA, login application. This is a web applications that runs on an IIS instance in your corporate Windows server infrastructure. When your browser is configured to send Windows Authentication information to configured list of web domains, this application is on that list. This is the main way the ID with which you are authenticated to your desktop is collected by the Okta infrastructure. In this case it was installed directly on the DC.

 

First subscribe to Okta and login to the Okta admin interface. Okta has two free subscription options: A developers license with a limit on the number of different applications that can be connected to it, but last forever. Or a regular, “enterprise”, license with no limits on the applications but which is good (read: free) for only a 30-day trial period. In this example I have selected the “regular” one since the time limit is of no concern here.

After signup, an confirmation email is sent to you with the relevant login details.

Login to your corporate Okta page as the admin and go on to the administration interface (the “admin” button) From Setting- Download download the following:

The plugin for the browser(s) you are using. Keep the plugin install files for later installation in other browsers.

The AD agent installer.

SSO IWA Web App Installer

We won’t use the password synch agent in this exercise.

 

Create a serviceaccount for the AD Agent on the DC. I called it “OktaService” and placed in the root container in my “cloudworks” (dc=cloudworks,dc=demo) domain. This user must be granted permissions to log on as a service and as a batchjob. Plus the, for service accounts usual do not change at first logon and password never expires options.

Run the AD Agent installer (OktaADAgentSetup-3.2.1.exe) on a windows Server with access to the DC. I used Windows 2012 R2 which also hosts the DC, and this proved an excellent choice.

The installer ask for

Install path: accept defult

Domain: cloudwork.demo

Okta AD Agent service account: this will be used to access AD and is the one created earlier: “OktaService@cloudworks.demo” / password

Proxy Configuration: no

Register Okta AD Agent: The agent will be connected to the Okta infrastructure. specify you domain here. https.//cloudworks.okta.no  which means just ticking “Production” and entering “cloudwork” in the subdomain field.

A browser window opens and a HTTP connection is being made to Okta.  You are presnted wit ha login window where you specify the administrator login details for your corporate Okta account established above.

A question is presented: Okta AD Agent is requesting permission to access the Okta API. Click “Allow Access”.

Install the IWA application. This is a web application that we will install on an instance of IIS (version 8.5.9600 running locally on the DC. But you can install the IWA application on any existing instance of IIS you have handy.

The IWA installer request the details of the service account the IWA applicaiton will need to run (specifically the application pool set up in the IIS) I reused OktaService account from above.

Specify the okta subdomain to be used: “cloudworks”, in this example. Once again a browser windows is openen and a login windows to Okta is presented. Enter the administration login as per above.  “Okta Desktop SSO Agent is requesting permission to: access the entire Okta API” ? Click “Allow Access”.

Go to the IIS manager where the IWA is installed and make sure it really is running. It should have an Application pool names OktaIWA with the identity specified with the installer. One of the installed Sites should be IWA. Under it in the web tree you should see the directories: bin, certificate, conftemplate, docs, img, installerlog and tools.

Log in to the Okta admin console at https://<your subdomain>.okta.com which is https://cloudworks.okta.com

This login works on Internet Explorer but not on Firefox. initial front page

 

 

 

 

 

 

 

 

The message states that I do not have any applications. Which makes sense since I have not configured any yet. I logged in as the administrator so the little triangle next to my name is a drop-down menu with “Admin” on it. Selecting this brings me to the administration interface for our Okta implementation. This URL: https://cloudworks-admin.okta.com/admin/dashboard. which I will use directly from now on.

admin initial front page

 

 

 

 

 

 

 

 

 

 

Token-in-token, Agent-Principal model of authorization delegation

PAML tokens create portable authorization where the Enforcement point need not know either the Principal making the request or the Owner authorized to grant the request. But the Principal/user must be in direct contact with the enforcement point to establish, through a cryptographic handshake, ownership of the PAML token being used. In many scenarios this direct connection is undesirable, even impossible. The Principal can not have a direct connection to the enforcement point.
A medical records repository is a good example. Security rules prohibit direct access over the internet to such a repository. Intermediary entities, application servers, firewall and the like, are mandated gateways.
In effect someone or something, must act on behalf of the Principal with the Enforcement point: An Agent.

This can be effected by placing one PAML token inside another. This token-in-token functionality is described in detail below. Any number of tokens can be embedded inside one another. In some ways like a certificate chain.
As with a standard Agent-Principal model the Principal trusts the Agent to act in the way the Principal desires. But with PAML token the Principal can narrow the Agents latitude to the extent desired.

Definition of terms

The Principal. This is the person, or entity, on whose behalf the request is undertaken.

Agent. The person or entity carrying out the request task on behalf of the Principal.

Owner. The person or entity that decides if the Principal is entitled to have the request(s) undertaken.

Enforcer. Person or entity in control of the resource and handles the request from the Agent. The Enforcer accepts the PAML token for authorization decisions.

Here is a schematic of the flow

alt text

Agent-Principal use of PAML tokens

 

Explanation of steps
Step 1 Principal prepares a list of request, or logical super-set of requests, in an XML format document; and signs this list with the Principal’s own private key. The logical super-sets can include rules according to which the requests made by the agent should be evaluated. The Agent can only carry out request on this list or ones contained in super-sets on this list. The XML document can include XSLT operations to be applied at enforcement time to the request made by the Agent. With this XSLT the Principal can enforce additional limitations (such as timing or checking token revocation list) on the requests the Agent is making.

Creating (pseudo XML document)

<principal.signature><request.list/></principal.signature>

Using the private key used to sign the request list document and the public key that belong to it: engage in cryptographic handshake with Agent and through this, establish to the Agent’s satisfaction that the Principal is in possession of the private key used to sign the request list.
Pass the signed list to the Agent.

Step 2 Agent attaches own usage conditions to Principal’s signed request.

Creating

<principal.signature><request.list/></principal.signature><agents.usage.conditions/>

And sign with the Agent’s own private key.
Creating

<agent.signature><principal.signature><request.list/></principal.signature><agents.usage.conditions/></agent.signature>

Using the private key used to sign the document and the public key that belong to it: engage in cryptographic handshake with the Owner and through this, establish to the Owner’s satisfaction that the Agent is in possession of the private key used to sign the document.
Pass the signed document to the Owner.

Step 3
Owner attaches own usage conditions to Agent’s signed request.

Creating

<agent.signature><principal.signature><request.list/></principal.signature><agents.usage.conditions/></agent.signature><owners.usage.conditions/>

And sign with the Owners own private key. This is the same private key used to sign the resource the PAML token governs access to.

Creating

<owner.signature><agent.signature><principal.signature><request.list/></principal.signature><agents.usage.conditions/></agent.signature><owners.usage.conditions/></owner.signature>

The PAML token is now completed.
Return the PAML to the Agent.

Step 4
The Agent now has a PAML token providing authorized access to resources signed with the same private key that signed the token. The PAML token can be reused to the limits specified in the owner’s usage conditions. Typically these would at least include validity time periods.
The Agent can now make request to the Enforcer and have them be authorized by the token. The requests are on behalf of the Principal but do not have to be directly from the Principal.

The Agent engages in a cryptographic handshake with the Enforcer using the private key used to sign the document from the Principal and the public key that belong to it: engage in cryptographic handshake with the Enforcer and through this, establish to the Enforcer’s satisfaction that the Agent is in possession of the private key used to create agent signature in the PAML token document.
Passed one or more PAML tokens to the Enforcer.
Pass a request to the Enforcer.

Step 5

The Enforcer examines the PAML tokens it has received. The tokens are checked in the following way and order:
XML validation. Those containing invalid XML are discarded.
XML schema validation. Those containing improper XML are discarded.
Agents signature validation: Using the public key of the Agent established in the cryptographic handshake the agent signature in the token validated. Tokens failing this validation are discarded.
Remaining tokens are tokens the Agent is properly entitled to use.

Examine the request and match it to the request list part of the remaining PAML tokens.
Those token that do not govern the request are discarded. Meaning that the request list in the token(s) do(es) not have at least one match for the request.
The remaining PAML tokens, if any, both belong to the Agent and govern the request the Agent is making.
The Enforcer examines the resource the request is for and what, if any digital signature it bears. Only if the resource bears a signature that can be validated with the same public key that can also validate the owners signature on the PAML token, is the resource considered “in scope” for the request. These two signature validation are carried out using the public key of the owner included with owner’s signature on the PAML token. If both signatures can be successfully validated the request is authorized.

In step 5 we get the desired situation that a completely stand-alone enforcement point can make authorization decisions for agents acting on behalf of someone else, without having to know the identity of either of the parties. This gives obvious benefits in reduced complexity and  ease of deployment.

Steganographic applications

Steganography is the practice of concealing something in something else. For instance hiding a text message inside a larger body of text. There is no cryptography. The security of the message, such as it is, is in the form of obscurity. That may be enough. Cryptography is computational expensive and required management of encryption keys. And it is no more secure that the keys employed. It appears that the better cryptographic algorithms are quite good and attacks tend to focus on the keys.
Attacking steganography would be different. Rather than asking Where is the key, one would ask is there anything there at all ?
There are applications for conducting steganography. Capable of embedding a message inside an image for example. But this is not about conducting steganography.

What I am after here is for application itself to be steganographic. To conceal the application, not inside another application, like a trojan, but altogether.

What would it mean for an application itself to steganographic.

Imagine an application as a book. And using an application as equivalent of reading a book from cover to cover.
Lets further imagine that we cut the the spine of a number of books and shuffle the loose pages together like so many decks of cards. Assuming uniformity of paper quality and page size, layout and font, and no metadata on page – having a loose page tells you little about which book it was from. Or if it came from any book at all.
If you have access to the full text of the original books that were shuffled together, you could do a text comparison and quickly identify which book the page came from. But in the absence of that there would be little to go on. Analyzing the text on the pages would yield some clues and more or less probable guesses could be made. Particularly if the books had comparatively few pages, i.e. if any one page contained a large fraction of the complete text.
The obfuscation could be further improved by cutting the pages up into individual lines of text.
Identifying a line as belonging to only one particular book would be difficult in many cases.

On a side note: what difference does it make cutting the pages up along the lines or across them, for the purposes of putting back together the original page. Again assuming uniformity of paper, layout and font. I venture that a line of text is harder to mach than a column of text. There is a certain balance here. While a line contains more meaningful information, a whole sentence perhaps – it also has fewer markers, fragments of words, that would match it to the strips of paper on either side of it. You gain information in one way and lose it in another. Specifically the anchoring within the larger body.

But the analogy we’re pursuing here is application functionality as reading a complete text: whole book to page to line.

Alright, so we have a large pile of individual strips of paper. Now, how do we read the book?

The premise being that the application, the book in out analogy, is concealed among a large body of code. Where only those knowing exactly what to look for, can find it. The secret in steganography is not the decryption key but how to find what you are looking for – the detection key if you will.
A steganographic application would have to have a detection key. With which you can locate the application and without which you can not. A link to first page, in the book analogy.

In a book you can just turn the pages but here all the pages are separated from one another. How do you get from page to page – or from one line to the next, in the more fine grained analogy.

Each page has a link to the next page but that link is only usable to someone who has a key. Else anyone stumbling on a page would discover the whole book. The idea was that a page does not guarantee a book. Given a pile of pages you can’t know how many books are in it or even if there are any at all. All you have are disjointed pages. Or code.

What will the STORK bring us ?

STORK is a federated security initiative from the EU. The acronym is ridiculously forced, being short for “Secure idenTity acrOss boRders linKed.” Less than auspicious.
It is supposed to secure interoperability between electronic identity (eID) schemes in different countries. With a few extra bit thrown in on top. Interoperability sounds very nice. Yes, lets have some of that. I applaud the effort.

However, I am dubious about the stuff “under the hood”. Can it be made to work as promised, and even if it can, do we want it or need it ?
I’ll examine this STORK thing more closely and report back here.

sailing the data ocean

What if there was a way for access to data could be authorized everywhere. If you were authorized to access a piece of data you could get access to it wherever it happened to be located.

This is not the way things work at the moment for sure, but if it could be made to work in a convenient way, what should it be like ?

When the first web browser arose some 20+ years ago. Static html pages and other media and document files where available by calling a URL over the HTTP protocol. Security was added – at first pretty coarse grained: If you were logged in you could access pretty much anything. It got better.
Comprehensive tools became available to centrally manage all web access to any document, with the finest granularity. The writing of the rules of who should access to do what, when and where, could be delegated out to those who actually were in a position to know.
But crucially, these tools could only manage access to stuff directly under their control. Often operating in a reverse-proxy mode intercepting HTTP traffic. APIs were available through which other applications could tap into them to take advantage of access control rules contained in them, to do their own authorization. In this way the data under the control of a unified set of access control rules could be made corporate wide. Access to all of a data in a corporation being governed by rules maintained in one place. Everyone would play together in the same data security pool.
In practice this never happened. (re-)Writing applications to take advantage of the API of the chosen security software platform , was too expensive. Other tools emerged to export the security rules from one software platform to another, leaving them to do their own enforcement through their own rule infrastructures. This didn’t work very well because it was too complicated. Rules are fundamentally about meaning, and meaning doesn’t translate easily. Never the less this was an attempt to federate authorization.

Data protected by the same access control rule infrastructure is part of the same pool. A database is a single pool. It has its own internal security governing access to individual pieces of data contained in it, but has no reach outside. The database maintains it’s own list of who gets to access which column in what tables.
A server has it’s own internal arrangement for governing access to the data in its own file systems. It may also have access remote file systems. Some remote file systems would be on other servers, which would govern access (NFS, FTP, Samba etc.) and would therefore not be part of the server’s own pool.

If authorizations could be federated between pools all data would exist in one big virtual pool.
A virtual pool made of multiple physical pools; individual databases, file servers etc. At present this is difficult as there may be user federation between some data pools, but each pool has it’s one authorization, it’s own way to enforce access rules. The rules in one are not known, or directly enforceable in another. There is no federated authorization.

Lets further suppose that any piece of data in this virtual data pool, data ocean really, is accessible over TCP with a URI. The URI may have various formats depending on what type of physical pool is being addressed.
For example, this would be the syntax of an URI accessing a directory (LDAP) store

ldap[s]://hostname:port/base_dn?attributes?scope?filter

And this to access a individual file, using HTTP(S)

https://host:port/path

Access to one of the secure web reverse-proxies mention above, would look like this too.

The would be many others. Note that the username and password does not appear. There would not be any prompting for this information either.
Access control would be through PAML tokens, passed in the headers. A SSL handshake would take place to establish the requesting entity’s authorization for the tokens presented.
All physical pools are defined by the entity that control access to it, and all of these entities, be they LDAP server and file/web server in the URI examples above must be equipped to handle PAML tokens to verify the authorization for the request. Through the acceptance of these PAML token the pools together form a virtual data ocean. Any application can call on data anywhere else and present PAML tokens for authorization.

This leave quite a bit of scope for application architecture. The use of a PAML token require access to the private key of the user to which the PAML token was issued. Which means that if a user is engaged in a transaction with an application and this application needs access to data kept somewhere else on behalf of the user, the application can only present its own PAML token, not forward those it has received from the users. The user must at a minimum contact this other data store directly and engage in a SSL handshake. This way the user’s ownership of the public key is established for the benefit of the data store. The application can then pass the PAML token received from the user on to the data store and the store would now know that the PAML tokens are OK to use; or the user could make the data retrieval directly and pass the data to the application that needs it. Sort of like a data federation.

Note that PAML token are tied to data, not any particular host environment. Among other things this means that the requesting client may send the server a considerable number of tokens in order to establish authorization for all required data. The server will grant the union of all these tokens.