Linter rulesOpenAPIprivacy/no-personal-data-in-url

privacy/no-personal-data-in-url

Since 0.11.0

This rule reports personal data, such as e-mail addresses, names, dates of birth, phone numbers and national identification numbers, passed in path or query parameters.

Rule Details

Personal data in a URL is copied to every access log, proxy, analytics tool and browser history on its way, mostly outside the retention and access controls that protect the data store. That works against data minimisation and integrity and confidentiality (GDPR Art. 5(1)(c) and (f)), data protection by design (Art. 25) and the security of processing (Art. 32), and makes erasure requests (Art. 17) hard to honour.

The rule looks at every in: path and in: query parameter, including the parameters of components.parameters, and reports:

  • a parameter whose name contains a personal data term, in any naming convention: email, phone, msisdn, first name, last name, surname, date of birth, dob, ssn, national id, tax id, passport, iban, card number, street address, ip address, and more;
  • special categories of personal data (Art. 9) and criminal records (Art. 10): health, diagnosis, religion, ethnicity, sexual orientation, biometric, genetic, criminal record;
  • a parameter whose schema has format: email or format: idn-email;
  • an object parameter (style: form, deepObject or content) with such a property.

A term matches whole words of the name, so name or country alone are not reported, while customerEmail and LAST_NAME are. A term followed by type, status, verified, count or format describes the data rather than holding it (email_verified) and is not reported. Credentials are reported by privacy/no-credentials-in-url.

In a path, identify the resource by an opaque identifier (/customers/{customerId}, not /customers/{email}). For a search by personal data, send the criteria in the body of a POST (POST /customers/search) or, where the API supports it, of a QUERY request.

Configuration

An object with two optional properties:

  • allow: parameter and property names that are never reported, compared case-insensitively.
  • terms: more names to report, in any naming convention (loyalty card also finds loyaltyCardNo).
commands:
  lint:
    rules:
      privacy/no-personal-data-in-url:
        - warning
        - allow: [phone]
          terms: [loyalty card]

Examples

Good. The search criteria are in the request body.

paths:
  /customers/search:
    post:
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  format: email

Bad. The e-mail address is part of the URL.

paths:
  /customers:
    get:
      parameters:
        - name: email
          in: query
          schema:
            type: string

When Not to Use It

For data that the API publishes on purpose (a public author directory), allow the names or disable the rule on the parameter with x-apigenie-lint-disable.

Compatibility

This rule is compatible with all OpenAPI 3.x versions.

Related rules

Further reading