swagger-parser icon indicating copy to clipboard operation
swagger-parser copied to clipboard

Components that have a space in their name are being ignored during validation

Open erunion opened this issue 2 years ago • 0 comments

Though the JSON Schema that @apidevtools/openapi-schemas loads in requires that schemas match ^[a-zA-Z0-9\\.\\-_]+$ (code here) if a definition, as below, has spaces in its name it'll be ignored during validation:

openapi: 3.0.0
info:
  version: "1.0.0"
  title: Invalid API

security:
  - Basic Auth: []

paths:
  /:
    post:
      responses:
        '200':
          description: OK

components:
  securitySchemes:
    Basic Auth:
      type: apiKey
      name: API-TOKEN
      in: header

We uncovered this because a user had submitted a definition with the following invalid security scheme (apiKey auth shouldn't have scheme and bearerFormat) and validation didn't pick it up because its name is "Basic Auth":

components:
  securitySchemes:
    Basic Auth:
      type: apiKey
      name: API-TOKEN
      in: header
      scheme: "api token",
      bearerFormat: "JWT"

I've tried tracing down where this is happening and my JSON Schema knowledge escapes me a bit here and I'm unclear if it's a problem with @apidevtools/openapi-schemas or z-schema. Running it with z-schema along with a similar portion of the securitySchemas JSON Schema definition from @apidevtools/openapi-schemas it also allows object with spaces:

const ZSchema = require("z-schema");
const zSchema = new ZSchema();

const schema = {
  $schema: "http://json-schema.org/draft-04/schema#",
  type: "object",
  patternProperties: {
    "^[a-zA-Z0-9\\.\\-_]+$": {
      type: "object",
      required: ["name"],
      properties: {
        name: {
          type: "string"
        },
        description: {
          type: "string"
        }
      },
      additionalProperties: false
    }
  }
};

const example = {
  "Has Spaces": {
    name: 'dog',
    descriptionn: 'a description'
  }
};

let isValid = zSchema.validate(example, schema);
let err = zSchema.getLastError();

console.log({ isValid, err: err?.details })

// { isValid: true, err: undefined }

Changing "Has Spaces" to "NoSpaces" however fails:

{
  isValid: false,
  err: [
    {
      code: 'OBJECT_ADDITIONAL_PROPERTIES',
      params: [Array],
      message: 'Additional properties not allowed: descriptionn',
      path: '#/NoSpaces',
      schemaId: undefined,
      [Symbol(z-schema/schema)]: [Object],
      [Symbol(z-schema/json)]: [Object]
    }
  ]
}

What I'm unclear on here is if it's a z-schema problem or something else is because adding additionalProperties: false to the schema will trigger a failure:

const schema = {
  $schema: "http://json-schema.org/draft-04/schema#",
  type: "object",
  additionalProperties: false,
  patternProperties: {
    "^[a-zA-Z0-9\\.\\-_]+$": {
      type: "object",
      required: ["name"],
      properties: {
        name: {
          type: "string"
        },
        description: {
          type: "string"
        }
      },
      additionalProperties: false
    }
  }
};

const example = {
  "Has Spaces": {
    name: 'dog',
    descriptionn: 'a description'
  }
};

/* {
  isValid: false,
  err: [
    {
      code: 'OBJECT_ADDITIONAL_PROPERTIES',
      params: [Array],
      message: 'Additional properties not allowed: Has Spaces',
      path: '#/',
      schemaId: undefined,
      [Symbol(z-schema/schema)]: [Object],
      [Symbol(z-schema/json)]: [Object]
    }
  ]
} */

Something is definitely wrong I'm just not sure where exactly. Any help is much appreciated!

erunion avatar Aug 25 '21 01:08 erunion