goatcounter icon indicating copy to clipboard operation
goatcounter copied to clipboard

Embed results as `iframe`

Open S1SYPHOS opened this issue 2 years ago • 18 comments

Hey there, I'm thinking about showing current stats in my admin interface without reinventing the wheel and just embed the main page in an iframe. Does this work on a non-public goatcounter page? Has someone done it and would share the setup?

Thanks for any pointers in the right direction on this!

Cheers S1SYPHOS

// Update: If there's another way of getting a nice view of the data (like the default results page) without having to reimplement everything from API results, render graphs etc, I'm grateful for suggestions!

S1SYPHOS avatar Mar 27 '22 08:03 S1SYPHOS

Hello there @arp242, I just discovered that I may allow "everyone" to see the stat's page, by doing so embedding via iframe would work BUT since goatcounter sets X-Frame-Options to same-origin, being located at a subdomain prevents iframe embeds ..

S1SYPHOS avatar Mar 30 '22 14:03 S1SYPHOS

I'd also love to have "iframe-able" site view.

I think absolutely ideal would be:

  • just the site view (so no settings, no other sites)
  • no X-Frame-options (or even better: safelist for domains & localhost?)
  • ideally, some weird hash URL for a tiny bit of security (like goatcounter.com/embed/{sha256} or whatever)

adamkiss avatar May 10 '22 14:05 adamkiss

goatcounter sets X-Frame-Options to same-origin

This is for a reason: it prevents certain "clickjacking" attacks, we can't "just" remove it.

So need to add a new setting which sets frame-ancestors from CSP. I'll work on that.

just the site view (so no settings, no other sites)

I'm not sure how useful this will be? If you're logged in, you will presumably want the site settings. If you're not logged in, you already don't see anything relating to the settings.

The only thing that might be useful is removing the top navigation where you can set the date range and such, but it adds a lot of if .. in the template, which is already a bit ugly. I think you can do it with CSS already if you really want to; I'll take a look and add it in the docs.

some weird hash URL for a tiny bit of security (like goatcounter.com/embed/{sha256} or whatever)

It already has this; If you select "Dashboard viewable by" in the settings you can select "logged in users or with secret token". You will need to set that to either that or "public" anyway for embedding to work outside of logged in users.

arp242 avatar Aug 12 '22 15:08 arp242

@arp242 I'm currently working on a Python CLI tool exporting / displaying data from GC's API. This might prove useful with what I had in mind ;) thanks for your effort with the CSP setting though!

S1SYPHOS avatar Aug 12 '22 16:08 S1SYPHOS

See here: https://codeberg.org/RefBW/goatpie

S1SYPHOS avatar Aug 13 '22 14:08 S1SYPHOS

You can now set "Sites that can embed GoatCounter" in the settings; see https://www.goatcounter.com/help/frame for the full docs.

See here: https://codeberg.org/RefBW/goatpie

Cheers, that's pretty neat – I've thought about creating something similar, but never got around to creating it. I couldn't get it to run though, but I'll create an issue on goatpie's issue tracker for that.

arp242 avatar Aug 22 '22 04:08 arp242

I'm working on adding a real API @S1SYPHOS (#629, not yet merged but should be finished fairly soon; mostly just need to finish the docs), which should work better than using the export API for this kind of thing.

Also added goatcounter dashboard, it's not as nice as goatpie (yet), but it works fairly well. For now it's mostly just so that I can verify the API works for real-world things, but I may work on it a bit more later.

cap-2022-10-20T23:15:00_border

Anyway, just FYI; would be useful for goatpie too, although you'd have to rewrite it quite a bit to use it.

arp242 avatar Oct 20 '22 21:10 arp242

Definitely piqued my interest 😉 you're a really cool fella, you know that?

S1SYPHOS avatar Oct 20 '22 21:10 S1SYPHOS

@arp242 Finally tried to set up the iframe.

I have both "viewable by" and "allowed domains" set correctly:

CleanShot 2022-10-28 at 19 44 13@2x

But the iframe source still returns 303 with redirect to /user/new. Am I missing something? Is it a DNS cache in the browser? What can be wrong?

adamkiss avatar Oct 28 '22 17:10 adamkiss

Edit: I've tried a quick test with codepen, and also a minimal iframe embed in a pure HTML, and it doesn't work anywhere. I'm now pretty sure the "AccessToken -> Cookie -> Redirect" pattern simply doesn't work for the iframe embed

adamkiss avatar Oct 29 '22 14:10 adamkiss

It seems to work if I try it; e.g. I added:

<iframe src="https://goatcounter.goatcounter.com?access-token=xxxx" style="width: 100%; height: 10em;"></iframe>

To https://new.arp242.net (which is just my alias for localhost) and then it loads in both Firefox and Chrome, with new profiles (just to ensure I don't have a login cookie set):

cap-2022-10-30T14:11:32

I'm pretty sure I tested this before, too.

I think the problem is that you use http:// in your example, and you need to use https as browsers will reject the cookie over HTTP (Chrome does so silently IIRC, but Firefox should have a warning in the console).

arp242 avatar Oct 30 '22 13:10 arp242

@arp242 Doesn't seem to work for me - neither safari 15.5 nor latest FF DevEd: https://akgciframe.netlify.app/ (yes, those are my real analytics for my site, I'll just switch it off or change the access-token later)

these are the settings in the goat counter:

CleanShot 2022-10-30 at 14 51 10@2x

I don't know what else could I set up differently.

Update: it works if I switch the counter to public, which, of course, isn't what I want. If switch it on and off, the last publically visible version is cached, but otherwise, it doesn't work for me. Is it possible that it doesn't actually work for "token" analytics and works only for public analytics?

adamkiss avatar Oct 30 '22 13:10 adamkiss

Do you have errors in the browser console? And/or can you send me a link so I can take a look (can email me at [email protected] if you don't want to post it here)

arp242 avatar Oct 30 '22 14:10 arp242

Oh wait, you did include a link; do'h.

It loads for me, but not sure if you have it set to public or "secret" now?

arp242 avatar Oct 30 '22 14:10 arp242

Ah, finally isolated the issue: in safari, it's the "Prevent cross-site tracking" setting (settings > privacy), in the firefox, it's the "Enhanced Tracking Prevention" (the shield next to URL bar) I'm of two minds about this: on one hand, at least in Firefox, it's easy to create an exception, and since iframe embed is probably for your own stuff you otherwise trust, it's good enough.

In Safari, it's either on or off, and you can't create exception.

I'd say this is good enough, but perhaps the note in the docs, something like:

"The iframe embed saves the access-token as a cookie. You need to create an exception for "Cross-site tracking" for the embedding website in your browser"

adamkiss avatar Oct 30 '22 15:10 adamkiss

Ah right; "Cookies" is set to to "Cross-site tracking cookies, and isolate cross-site cookies" for me in Firefox. I'm not sure what the default is. I don't have an Apple device; need to check my VM or BrowserStack later.


The reason it uses a cookie is so that 1) https://mine.goatcounter.com?access-key=kinda-secret doesn't show in the URL bar, can be accidentally screenshotted, copied/pasted, etc. and 2) so I don't need to add access-token=... to every single URL.

The first isn't really an issue inside frames, because you don't see the URL, although the second issue remains, but that's not necessarily a huge issue; I need to look at it. Just passing the token around as a query is perhaps better, because this entire cookie bonanza is pretty confusing.

arp242 avatar Oct 30 '22 15:10 arp242

@arp242 Thank you for helping me identify the issue.

Now I sort of get the problem of seeing the URL in the browser bar, but I identified another problem with the cookie based approach. I now opened the analytics, to turn off the token visibility for my analytics, but since I have the cookie saved, I don't actually see the "login" header. I needed to open storage, delete the cookie, and only then I was redirected to the login screen :D

Additional thing: the hideui param & the access-token won't work at the same time, i.e. xxx.goatcounter.com/?hideui=1&access-token=whatever still show the UI, since you're redirected to the default / view.

Thanks again!

adamkiss avatar Oct 30 '22 15:10 adamkiss

@arp242

Could you use noncing techniques ?

the iFrame paeans only has a nonce for stopping attacks

you record a uuid per iFrame

You embed on sone site as an iFrame . The call sends in the last nonce

server marks the uuid as used and creates another one and sends it back to the iFrame

It’s basically acting as a user session tracking system

If you have CSP you are isolating it to the domain the iFrame is running in.

So the used of the nonce is a different thing from an Api key .

the nonce is always changing and so when the third party web site wants to embed an iFrame it’s backend must call to ask for a nonce, then put thst nonce in the iFrame url, so that the iFrame uses it.

Each user of the site is unique and so gets a unique iFrame nonce - yes it’s a backend call on load time again :)

the db just needs to store a nonce per website embed per unique visiting load. They are rolling and so you could just use Redis or other also.

let me know if this is utter garbage for te problem domain though

gedw99 avatar Jan 22 '23 19:01 gedw99