Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply privateVariables to properties of custom input variables. #1498

Closed
erikkrieg opened this issue Aug 7, 2018 · 4 comments
Closed

Apply privateVariables to properties of custom input variables. #1498

erikkrieg opened this issue Aug 7, 2018 · 4 comments
Labels
⛲️ feature New addition or enhancement to existing solutions

Comments

@erikkrieg
Copy link

erikkrieg commented Aug 7, 2018

Feature suggestion

Expand the privateVariables functionality to omit properties of custom input variables in Optics traces. Currently variables can be hidden, but properties cannot be targeted specifically.

Use case

Given the following mutation, we want to hide input.password from Optics, while still supporting a flexible mutation interface using inputs.

UpdateUserInput schema:

input UpdateUserInput {
  username: String
  email: String
  password: String
}

Query:

mutation UpdateUser($input: UpdateUserInput!) {
  updateUser(input: $input) {
    updatedAt
  }
}

Variables:

{
  "input": {
    "password": "i<3nsync"
  }
}

It is also possible that in the future we learn we need to start hiding input.email or another property in order to comply with some new regulations.

Workarounds

Right now the workarounds we considered are:

  1. Change the schema so that any variables needing to be private are not properties of inputs. This can be challenging depending on how the API is being consumed and may require the mutation to be deprecated.
  2. Don't use custom inputs to contain data that might need to be private. This is hard to predict, so the more pragmatic approach would be to never use inputs, but then the API is inflexible and might encounter more breaking changes based on product changes.
  3. Make all variables private. This is probably this simplest option, but takes away a lot of value from traces.

For an issue we are encountering we are going with the first workaround, but are not very satisfied with any of the present options.

Interface suggestions

Suggestion A:

By default (or based on a flag) compare variables and their properties against the array of private variables. There are no variables named "password" in the updateUser mutation, but the "input" variable does have a "password" property, so omit it!

Example:

const server = new ApolloServer({
  typeDefs,
  resolvers,
  engine: {
    apiKey: process.env.API_KEY,
    privateVariables: ['password'],
    privateVariablesDeep: true,
  }
});

Suggestion B:

Use an interface like Lodash's get method that can use a string to match a specific variable's properties. This is my personal favorite :P

Example:

const server = new ApolloServer({
  typeDefs,
  resolvers,
  engine: {
    apiKey: process.env.API_KEY,
    privateVariables: ['password', 'input.password'],
  }
});

Suggestion C:

Accept a method to map over the variables and return the values that will be sent to Optics.

Example:

const {
  isPrivateVariable,
  hasPrivateProperty,
  replacePrivateProperties 
} = require('./my-custom-codez');

const server = new ApolloServer({
  typeDefs,
  resolvers,
  engine: {
    apiKey: process.env.API_KEY,
    privateVariables: (variable) => {
      if (isPrivateVariable(variable.name)) return '';
      if (hasPrivateProperty(variable.value)) {
        // find the private property and obscure its value
        const modifiedValue = replacePrivateProperties(variable.value);
        return modifiedValue;
      }
      return variable.value;
    }
  }
});
@ghost ghost added the ⛲️ feature New addition or enhancement to existing solutions label Aug 7, 2018
@danilobuerger
Copy link
Contributor

@martijnwalraven @abernix Isn't that actually a pretty big security risk exposing secret data like this?

@Shahor
Copy link

Shahor commented Jun 25, 2019

Just realised today that my users' passwords are being sent to apollo engine because of that exactly 😨

I have privateVariables: ['password'] but of course this doesn't work in nested inputs :|

Is there something available as of today to solve this? (couldn't find it)

@erikkrieg
Copy link
Author

@Shahor Until this functionality is expanded the easiest thing to do is hotfix your server and make all variables private, if you haven't already.

Then, if it is worth it to have variables in traces, you could change your API to accept passwords only as variables instead of properties on inputs so they can be made private.

@helenwh
Copy link
Contributor

helenwh commented Jun 28, 2019

Hi @erikkrieg, @Shahor --

We just published a release of Apollo server (2.7.0-alpha.1) that includes a fix for this issue, using something along the lines of Suggestion C mentioned above: accepting a custom method for modifying variable values as input to an EngineReportingOption. We’ve included that functionality with a new option, sendVariableValues and will be deprecating privateVariables in the future.

Here’s an example custom function input to sendVariableValues. The Apollo server docs here have been updated to describe the option more in detail, and this is the PR making these changes: #2931

Also, we've changed the default reporting settings so that, unless specified, no variable values will be included in the traces.

We’re still looking for feedback on this, so please let us know if you have any ideas on how we might be able to make this better!

@helenwh helenwh closed this as completed Jul 2, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
⛲️ feature New addition or enhancement to existing solutions
Projects
None yet
Development

No branches or pull requests

4 participants