- https://github.com/growthbook/growthbook
-
GrowthBook
-
Open Source Feature Flagging and A/B Testing Platform
-
Gotta love somewhat pointless features like “encrypt the feature flags response so people can’t see it”:
In something that needs to be able to access it from a frontend web app by definition:
- In Chrome DevTools, Network tab, look for a request like this:
- In Chrome DevTools search panel, search across the sites loaded code for the SDK slug (eg.
sdk-xABCD1234EFG
) - Find code like this:
-
let el = { apiHost: "https://cdn.growthbook.io", clientKey: "sdk-xABCD1234EFG", decryptionKey: "/a1bcdEFghIjKlMnopqrSt==", enableDevMode: !(0, F.Bl)(), subscribeToChanges: !0, trackingCallback: (e,t)=>{ (0, ea.L9)("View Experiment", { experiment: e, result: t }) } };
-
a.useEffect)(()=>{ fetch("https://cdn.growthbook.io/api/features/sdk-xABCD1234EFG").then(e=>e.json()).then(e=>{ ei.setEncryptedFeatures(e.encryptedFeatures) } ) }
-
- Then you could extract the
decryptionKey
and manually decrypt things outside of the running site; or just set some more debug breakpoints and let the site do it for you... - Searching the code for
setEncryptedFeatures
:-
setFeatures(e) { this._ctx.features = e, this.ready = !0, this._render() } async setEncryptedFeatures(e, t, r) { let i = await P(e, t || this._ctx.decryptionKey, r); this.setFeatures(JSON.parse(i)) } setExperiments(e) { this._ctx.experiments = e, this.ready = !0, this._updateAllAutoExperiments() } async setEncryptedExperiments(e, t, r) { let i = await P(e, t || this._ctx.decryptionKey, r); this.setExperiments(JSON.parse(i)) } async decryptPayload(e, t, r) { return e.encryptedFeatures && (e.features = JSON.parse(await P(e.encryptedFeatures, t || this._ctx.decryptionKey, r)), delete e.encryptedFeatures), e.encryptedExperiments && (e.experiments = JSON.parse(await P(e.encryptedExperiments, t || this._ctx.decryptionKey, r)), delete e.encryptedExperiments), e }
-
- If we set a breakpoint within
setFeatures
andsetExperiments
we would be able to see the content after it's decrypted. - At that point, we could also store a reference to
this
/this._ctx
/ similar to access the rest of the stored data/settings/etc, and read/manipulate it as we like.