Call Elasticsearch service without exposing sensitive data in the client-side

Hey guys,

I've being playing with Kibana Plugins. Now I need to migrate one of my plugins from the Legacy to the Platform API, but I'm facing some problems when trying to made some Elasticsearch requests without expositing sensitive data on the browser-side. In the past I do this in injected vars.

So, how can I call the Elasticsearch API from front-end (public/)...

esResponse = await client.callAsCurrentUser('searh', ...vars);

...without exposing anything at the browser-side (vars) and without recurring to routes and HTTP service:

    // server-side
    router.get(
     {
       path: '/some/endpoint',
     }, async (context, request, response) => {
        // some code
        esResponse = await client.callAsCurrentUser('searh', ...vars);
       // and more code
    });

But only calling directly the Elasticsearch Service. I would like to do this at the public async start(core: coreStart) in the client-side ({pluginName}/public/plugin.ts)

It's something like this what I'm searching for, but not for config values :sweat_smile:

Other than the issue you linked to to share config values to the browser, there isn't a generic way to inject data into the browser. You will have to create a server-side plugin with a route like /myplugin/getmyvar that you can fetch.

I would discourage this pattern for sharing secrets like Elasticsearch username/password information though. Even if the user is authorized exposing the secret feels like a security risk.

For this reason the console app inside Kibana has a Elasticsearch proxy that proxies requests from the browser to Elasticsearch so that the secret never has to be exposed. You can take a look at the source code here kibana/index.ts at master · elastic/kibana · GitHub

Also keep in mind that the elasticsearch-js client library does not support running from a browser, primarily for security reasons.

As Rudolf mentioned, the recommended approach here is to expose your plugin on both the client & server, and create routes on the server that use the core.elasticsearch service under the hood. Then you can talk to the endpoints you've created from the front end with core.http.

Thanks guys!

What I'm really looking for is avoiding create a request on the front-end using core.http. A solution that allows me to query over Elastic without showing params on the client-side will be perfect... for example, imagine on the the client-side hiding some navControls based on some backend (server) function value which needs as input value a parameter that comes from the front-end for example some role or something like that...

What's important here is avoiding any kind of injection based on the payload request or respose... Like was I said, in legacy plugins I achieve this via replaceInjectedVars returning some server function.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.