API Schema

Scan API Entrypoints using a schema

To scan API entrypoints, upload an API schema file to Bright. For a scan to be successful, please make sure that you are using a valid schema that is configured in compliance with the original specification (OpenAPI/ Swagger or Postman, respectively).

To scan API entrypoints using a predefined schema, follow these steps:

  1. In the Targets tab, scroll to the Discover Entrypoints section, and select For APIs to use either an Open API specification (Swagger) or a Postman collection: *.yml / *.yaml / *.json.

🚧

Important:

Bright supports the following versions of the API schemas: Swagger 2+, OpenAPI 3+, Postman 2+. To ensure proper scanning of an API, you must configure the schema according to the general specification and specific Bright requirements. Find more information about the configuration validation here.


  1. Select a schema file for the scan. You can either upload the file from a disk or use a pre-uploaded file. Also, you can import a schema from a cloud by specifying the relative URL.
1556

Once you upload the schema file, you can open it in the Schema Editor. Use this option to validate and edit the uploaded schema before running a scan. Some schema files may contain configuration errors that block scanning. To learn how to identify the files with configuration errors, see Configuring an API Schema.

πŸ“˜

Note:

Some hosts specified in the uploaded schema may be unreachable or unauthorized for direct scanning from the cloud. In this case, you may need to connect the local Repeater for the scan or change the hosts in the schema using the Schema editor functionality.

1401

πŸ“˜

Note:

When using a pre-uploaded file, make sure this user has an access to the project and appropriate permissions to operate with it. For more, see Managing Organization Users.

Sample file

This is the sample .json file with defined Default Values, made for BrokenCrystals:

{
  "openapi": "3.0.0",
  "info": {
    "title": "Broken Crystals",
    "description": "\n  ![BC logo](/assets/img/logo_blue_small.png)\n\n  This is the _Broken Crystals_ REST API.\n\n  _Broken Crystals_ is a benchmark application that uses modern technologies and implements a set of common security vulnerabilities.\n\n  ## Available endpoints\n\n  * [App](#/App%20controller) - common operations\n\n  * [Auth](#/Auth%20controller) - operations with authentication methods\n\n  * [User](#/User%20controller) - operations with users(creation, searching)\n\n  * [Files](#/Files%20controller) - operations with files\n\n  * [Subscriptions](#/Subscriptions%20controller) - operations with subscriptions\n\n  * [Testimonials](#/Testimonials%20controller) - operations with testimonials\n\n  * [Products](#/Products%20controller) β€” operations with products\n\n\n  ",
    "version": "1.0",
    "contact": {}
  },
  "tags": [],
  "servers": [
    {
      "url": "https://brokencrystals.com"
    }
  ],
  "components": {
    "schemas": {
      "AppConfig": {
        "type": "object",
        "properties": {
          "awsBucket": {
            "type": "string"
          },
          "sql": {
            "type": "string"
          },
          "googlemaps": {
            "type": "string"
          }
        },
        "required": [
          "awsBucket",
          "sql",
          "googlemaps"
        ]
      },
      "LoginRequest": {
        "type": "object",
        "properties": {
          "user": {
            "type": "string"
          },
          "password": {
            "type": "string"
          },
          "op": {
            "type": "string",
            "enum": [
              "basic",
              "html",
              "csrf",
              "csrf_dom",
              "oidc"
            ]
          }
        },
        "required": [
          "user",
          "password",
          "op"
        ]
      },
      "LoginResponse": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "ldapProfileLink": {
            "type": "string",
            "description": "ldap query link for user details"
          }
        },
        "required": [
          "email",
          "ldapProfileLink"
        ]
      },
      "OidcClientResponse": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string"
          },
          "clientSecret": {
            "type": "string"
          },
          "metadataUrl": {
            "type": "string"
          }
        },
        "required": [
          "clientId",
          "clientSecret",
          "metadataUrl"
        ]
      },
      "LoginJwtResponse": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "ldapProfileLink": {
            "type": "string",
            "description": "ldap query link for user details"
          }
        },
        "required": [
          "token",
          "email",
          "ldapProfileLink"
        ]
      },
      "JwtValidationResponse": {
        "type": "object",
        "properties": {
          "secret": {
            "type": "string"
          }
        },
        "required": [
          "secret"
        ]
      },
      "UserDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          }
        },
        "required": [
          "email",
          "firstName",
          "lastName"
        ]
      },
      "CreateUserRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "password": {
            "type": "string"
          }
        },
        "required": [
          "email",
          "firstName",
          "lastName",
          "password"
        ]
      },
      "CreateTestimonialRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "title",
          "message"
        ]
      },
      "TestimonialDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "title",
          "message"
        ]
      },
      "ProductDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "photoUrl": {
            "type": "string"
          },
          "description": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "category",
          "photoUrl",
          "description"
        ]
      }
    }
  },
  "paths": {
    "/api/render": {
      "post": {
        "operationId": "AppController_renderTemplate",
        "summary": "",
        "description": "Template for rendering by doT. Expects plain text as request body",
        "parameters": [],
        "requestBody": {
          "required": true,
          "description": "Write your text here",
          "content": {
            "text/plain": {
              "schema": {
                "type": "string"
              },
              "example": "This is a value"
            }
          }
        },
        "responses": {
          "201": {
            "description": "Rendered result"
          }
        },
        "tags": [
          "App controller"
        ]
      }
    },
    "/api/goto": {
      "get": {
        "operationId": "AppController_redirect",
        "summary": "",
        "description": "Redirects the user to the provided url",
        "parameters": [
          {
            "name": "url",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "https://brokencrystals.com/api/users/basic"
          }
        ],
        "responses": {
          "200": {
            "description": "Redirected"
          }
        },
        "tags": [
          "App controller"
        ]
      }
    },
    "/api/metadata": {
      "post": {
        "operationId": "AppController_xml",
        "summary": "",
        "description": "Receives client's metadata in XML format. Returns the passed XML",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "string"
              },
              "example": "<note>\n<to>Tove</to>\n<from>Jani</from>\n<heading>Reminder</heading>\n<body>Don't forget me this weekend!</body>\n</note>"
            }
          }
        },
        "responses": {
          "201": {
            "description": "XML passed successfully"
          },
          "500": {
            "description": "Invalid data"
          }
        },
        "tags": [
          "App controller"
        ]
      }
    },
    "/api": {
      "options": {
        "operationId": "AppController_getTestOptions",
        "summary": "",
        "description": "Returns the list of supported operations",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "App controller"
        ]
      }
    },
    "/api/spawn": {
      "get": {
        "operationId": "AppController_launchCommand",
        "summary": "",
        "description": "Launches system command on server",
        "parameters": [
          {
            "name": "command",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "ls /var/www/*"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "App controller"
        ]
      }
    },
    "/api/config": {
      "get": {
        "operationId": "AppController_getConfig",
        "summary": "",
        "description": "Returns server configuration to the client",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppConfig"
                }
              }
            }
          }
        },
        "tags": [
          "App controller"
        ]
      }
    },
    "/api/auth/admin/login": {
      "post": {
        "operationId": "AuthController_loginWithRSAJwtKeysAdmin",
        "summary": "",
        "description": "Authenticates user and returns JWT token with RSA256 protocol. The key is siigned with RSA private key.",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              },
              "example": "{\n  \"user\": \"admin\",\n  \"password\": \"admin\",\n  \"op\": \"basic\"\n}"
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/login": {
      "post": {
        "operationId": "AuthController_loginWithRSAJwtKeys",
        "summary": "",
        "description": "Authenticates user and returns JWT token with RSA256 protocol. The key is siigned with RSA private key.",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              },
              "example": "{\n  \"user\": \"admin\",\n  \"password\": \"admin\",\n  \"op\": \"basic\"\n}"
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/dom-csrf-flow": {
      "get": {
        "operationId": "AuthController_getDomCsrfToken",
        "summary": "",
        "description": "Authenticates user and returns DOM CSRF token.",
        "parameters": [],
        "responses": {
          "400": {
            "description": "Bad request, fingerprint is required",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number"
                    },
                    "message": {
                      "type": "string"
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/simple-csrf-flow": {
      "get": {
        "operationId": "AuthController_getCsrfToken",
        "summary": "",
        "description": "Returns Simple CSRF token.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Returns simple csrf token"
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/oidc-client": {
      "get": {
        "operationId": "AuthController_getOidcClient",
        "summary": "",
        "description": "Get OIDC client configuration. Returns public OIDC. These keys are configurable via CLIENT_ID, CLIENT_SECRET env variables.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OidcClientResponse"
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/jwt/kid-sql/login": {
      "post": {
        "operationId": "AuthController_loginWithKIDSqlJwt",
        "summary": "",
        "description": "Authenticates user and returns JWT token with HCA256. The key id is provided in KID protocol.",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              },
              "example": "{\n  \"user\": \"admin\",\n  \"password\": \"admin\",\n  \"op\": \"basic\"\n}"
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginJwtResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/jwt/kid-sql/validate": {
      "get": {
        "operationId": "AuthController_validateWithKIDSqlJwt",
        "summary": "",
        "description": "Validates the JWT header and returns secret if the header is valid. Executes SQL query by concatenating the KID value with the query.\n    In case of None algorithm ignores the signature.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JwtValidationResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/jwt/weak-key/login": {
      "post": {
        "operationId": "AuthController_loginWithWeakKeyJwt",
        "summary": "",
        "description": "Authenticates user and returns JWT token with HCA256. The key is configurable on server via the JWT_SECRET_KEY env variable.",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              },
              "example": "{\n  \"user\": \"admin\",\n  \"password\": \"admin\",\n  \"op\": \"basic\"\n}"
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginJwtResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/jwt/weak-key/validate": {
      "get": {
        "operationId": "AuthController_validateWithWeakKeyJwt",
        "summary": "",
        "description": "Validates the JWT header and return secret if the header is valid. The token validation is done using algorithm in header and key\n    that is configured in JWT_SECRET_KEY env variable. In case of None algorithm ignores the signature.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JwtValidationResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/jwt/jku/login": {
      "post": {
        "operationId": "AuthController_loginWithJKUJwt",
        "summary": "",
        "description": "Authenticates user and returns JWT token with HCA256. The key is configurable on server via the JWT_SECRET_KEY env variable.",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              },
              "example": "{\n  \"user\": \"admin\",\n  \"password\": \"admin\",\n  \"op\": \"basic\"\n}"
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginJwtResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/jwt/jku/validate": {
      "get": {
        "operationId": "AuthController_validateWithJKUJwt",
        "summary": "",
        "description": "Vulnerability case: Uses publicly available JSON to check if JWT is properly signed after the Header in JWT is set to point to our JSON and sign the JWT with our private key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JwtValidationResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/jwt/jwk/login": {
      "post": {
        "operationId": "AuthController_loginWithJWKJwt",
        "summary": "",
        "description": "Authenticates user and returns JWT token with HCA256. The key is configurable on server via JWT_SECRET_KEY env variable.",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              },
              "example": "{\n  \"user\": \"admin\",\n  \"password\": \"admin\",\n  \"op\": \"basic\"\n}"
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginJwtResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/jwt/jwk/validate": {
      "get": {
        "operationId": "AuthController_validateWithJWKJwt",
        "summary": "",
        "description": "Vulrenability case: JWK field JSON in Header has empty values and our private key to sign the JWT",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JwtValidationResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/jwt/x5c/login": {
      "post": {
        "operationId": "AuthController_loginWithX5CJwt",
        "summary": "",
        "description": "Authenticates user and returns JWT token with HCA256. The key is configurable on server via the JWT_SECRET_KEY env variable.",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              },
              "example": "{\n  \"user\": \"admin\",\n  \"password\": \"admin\",\n  \"op\": \"basic\"\n}"
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginJwtResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/jwt/x5c/validate": {
      "get": {
        "operationId": "AuthController_validateWithX5CJwt",
        "summary": "",
        "description": "Vulnerability case: The application doesn’t properly check which X5C key is used for signing and when X5C headers are set to our values and signed with our private key, authentication is bypassed.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JwtValidationResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/jwt/x5u/login": {
      "post": {
        "operationId": "AuthController_loginWithX5UJwt",
        "summary": "",
        "description": "Authenticates user and returns JWT token with HCA256. The key is configurable on server via the JWT_SECRET_KEY env variable.",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              },
              "example": "{\n  \"user\": \"admin\",\n  \"password\": \"admin\",\n  \"op\": \"basic\"\n}"
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginJwtResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/auth/jwt/x5u/validate": {
      "get": {
        "operationId": "AuthController_validateWithX5UJwt",
        "summary": "",
        "description": "Vulnerability case: Uses the uploaded certificate to sign the JWT and sets the X5U Header in JWT to point to the uploaded certificate.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JwtValidationResponse"
                }
              }
            }
          },
          "401": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Auth controller"
        ]
      }
    },
    "/api/users": {
      "options": {
        "operationId": "UsersController_getTestOptions",
        "summary": "",
        "description": "List of permitted communication options",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "User controller"
        ]
      }
    },
    "/api/users/one/{email}": {
      "get": {
        "operationId": "UsersController_getUser",
        "summary": "",
        "description": "Returns user by email",
        "parameters": [
          {
            "name": "email",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "[email protected]"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns user object if it exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDto"
                }
              }
            }
          },
          "404": {
            "description": "User not founded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "User controller"
        ]
      }
    },
    "/api/users/{id}": {
      "get": {
        "operationId": "UsersController_getUserById",
        "summary": "",
        "description": "Returns user by id",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            },
            "example": "1"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns user object if it exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDto"
                }
              }
            }
          },
          "404": {
            "description": "User not founded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "User controller"
        ]
      }
    },
    "/api/users/one/{email}/photo": {
      "get": {
        "operationId": "UsersController_getUserPhoto",
        "summary": "",
        "description": "Returns user profile photo",
        "parameters": [
          {
            "name": "email",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "[email protected]"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns user profile photo"
          },
          "204": {
            "description": "Returns empty content if photo is not set"
          },
          "403": {
            "description": "Returns then user is not authenticated"
          }
        },
        "tags": [
          "User controller"
        ]
      },
      "put": {
        "operationId": "UsersController_uploadFile",
        "summary": "",
        "description": "Uploads user profile photo",
        "parameters": [
          {
            "name": "email",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "[email protected]"
          }
        ],
        "responses": {
          "200": {
            "description": "Photo updated"
          }
        },
        "tags": [
          "User controller"
        ]
      }
    },
    "/api/users/ldap": {
      "get": {
        "operationId": "UsersController_ldapQuery",
        "summary": "",
        "description": "Performs LDAP search for user details",
        "parameters": [
          {
            "name": "query",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UserDto"
                  }
                }
              }
            }
          }
        },
        "tags": [
          "User controller"
        ]
      }
    },
    "/api/users/basic": {
      "post": {
        "operationId": "UsersController_createUser",
        "summary": "",
        "description": "Creates BASIC user in PostGreSQL db",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUserRequest"
              },
              "example": "{\n  \"email\": \"[email protected]\",\n  \"firstName\": \"Jim\",\n  \"lastName\": \"Harris\",\n  \"password\": \"BC_1234\"\n}"
            }
          }
        },
        "responses": {
          "201": {
            "description": "User created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDto"
                }
              }
            }
          },
          "409": {
            "description": "User Already exists",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number"
                    },
                    "message": {
                      "type": "string"
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "User controller"
        ]
      }
    },
    "/api/users/oidc": {
      "post": {
        "operationId": "UsersController_createOIDCUser",
        "summary": "",
        "description": "Creates OIDC user in KeyCloak db",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUserRequest"
              },
              "example": "{\n  \"email\": \"[email protected]\",\n  \"firstName\": \"Jim\",\n  \"lastName\": \"Harris\",\n  \"password\": \"BC_1234\"\n}"
            }
          }
        },
        "responses": {
          "201": {
            "description": "User created, returns empty object"
          },
          "409": {
            "description": "User Already exists",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errorMessage": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "User controller"
        ]
      }
    },
    "/api/users/one/{email}/info": {
      "put": {
        "operationId": "UsersController_changeUserInfo",
        "summary": "",
        "description": "Method for updating user details. Vulnerability case: Mass Assignment allows an attacker to modify object properties, which are not supposed to be changed by the user",
        "parameters": [
          {
            "name": "email",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "[email protected]"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserDto"
              },
              "example": "{\n  \"name\": \"Jim Harris\",\n  \"title\": \"SE\",\n  \"message\": \"Lets do this string\"\n}"
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns updated user"
          },
          "403": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number"
                    },
                    "message": {
                      "type": "string"
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "User controller"
        ]
      },
      "get": {
        "operationId": "UsersController_getUserInfo",
        "summary": "",
        "description": "Returns user by email",
        "parameters": [
          {
            "name": "email",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "[email protected]"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns user info"
          },
          "403": {
            "description": "invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number"
                    },
                    "message": {
                      "type": "string"
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": ""
          }
        },
        "tags": [
          "User controller"
        ]
      }
    },
    "/api/users/one/{email}/adminpermission": {
      "get": {
        "operationId": "UsersController_getAdminStatus",
        "summary": "",
        "description": "Endpoint for checking admin rights of authenticated user",
        "parameters": [
          {
            "name": "email",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            },
            "example": "[email protected]"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns true if user has admin rights"
          },
          "403": {
            "description": "user has no admin rights",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "User controller"
        ]
      }
    },
    "/api/file": {
      "get": {
        "operationId": "FileController_loadFile",
        "summary": "",
        "description": "Reads the file from the provided path and the supplied content type and returns the file",
        "parameters": [
          {
            "name": "path",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "/etc/passwd"
          },
          {
            "name": "type",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "text"
          },
          {
            "name": "accept",
            "required": true,
            "in": "header",
            "schema": {
              "type": "string"
            },
            "example": "accept"
          }
        ],
        "responses": {
          "200": {
            "description": "File read successfully"
          },
          "500": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Files controller"
        ]
      },
      "delete": {
        "operationId": "FileController_deleteFile",
        "summary": "",
        "description": "Deletes file at the given path",
        "parameters": [
          {
            "name": "path",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "/home/user/downloads/sample.txt"
          }
        ],
        "responses": {
          "200": {
            "description": "File deleted successfully"
          },
          "500": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "location": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Files controller"
        ]
      }
    },
    "/api/file/raw": {
      "put": {
        "operationId": "FileController_uploadFile",
        "summary": "",
        "description": "Save raw content on server as a file",
        "parameters": [
          {
            "name": "path",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "/home/user/downloads/sample.txt"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "string"
              },
              "example": "{\n  \"name\": \"string\",\n  \"title\": \"string\",\n  \"message\": \"string\"\n}"
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "Files controller"
        ]
      },
      "get": {
        "operationId": "FileController_readFile",
        "summary": "",
        "description": "Read file content on server as a file",
        "parameters": [
          {
            "name": "path",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "/home/user/downloads/sample.txt"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns requested file"
          },
          "404": {
            "description": "File not Found"
          }
        },
        "tags": [
          "Files controller"
        ]
      }
    },
    "/api/subscriptions": {
      "post": {
        "operationId": "SubscriptionsController_subscribe",
        "summary": "",
        "description": "Creates subscription for provided email and returns the email address",
        "parameters": [
          {
            "name": "email",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "[email protected]"
          }
        ],
        "responses": {
          "201": {
            "description": "Returns subscribed email"
          }
        },
        "tags": [
          "Subscriptions controller"
        ]
      }
    },
    "/api/testimonials": {
      "post": {
        "operationId": "TestimonialsController_createTestimonial",
        "summary": "",
        "description": "Creates testimonial",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTestimonialRequest"
              },
              "example": "{\n  \"name\": \"string\",\n  \"title\": \"string\",\n  \"message\": \"string\"\n}"
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestimonialDto"
                }
              }
            }
          },
          "403": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number"
                    },
                    "message": {
                      "type": "string"
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Testimonials controller"
        ]
      },
      "get": {
        "operationId": "TestimonialsController_getTestimonials",
        "summary": "",
        "description": "Returns all testimonials",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TestimonialDto"
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Testimonials controller"
        ]
      }
    },
    "/api/testimonials/count": {
      "get": {
        "operationId": "TestimonialsController_getCount",
        "summary": "",
        "description": "Returns count of all testimonials based on provided sql query",
        "parameters": [
          {
            "name": "query",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "vulnerability"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "tags": [
          "Testimonials controller"
        ]
      }
    },
    "/api/products": {
      "get": {
        "operationId": "ProductsController_getProducts",
        "summary": "",
        "description": "Returns all products",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProductDto"
                  }
                }
              }
            }
          },
          "403": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "number"
                    },
                    "message": {
                      "type": "string"
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Products controller"
        ]
      }
    },
    "/api/products/latest": {
      "get": {
        "operationId": "ProductsController_getLatestProducts",
        "summary": "",
        "description": "Returns 3 latest products",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProductDto"
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Products controller"
        ]
      }
    }
  }
}


Entrypoints Validation Checklists

To ensure that the specified upload file will be correctly read and processed, follow these rules:

OpenAPI/Swagger Schema

  • Specify a Target Server (Host)
    • OpenAPI 3+: Include the servers property. Example:
      "servers": [
        {"url": "https://development.gigantic-server.com/v1", "description": "Development server"},
        {"url": "https://staging.gigantic-server.com/v1", "description": "Staging server"},
        {"url": "https://api.gigantic-server.com/v1", "description": "Production server"}
      ]
      
    • Swagger 2: Include the host property.
    • Multiple Servers: List the primary server first.
  • Parameter Values
    • Ensure all parameters have values.
    • Add values in the raw schema or Value fields in the smart view.
    • Define Variable Substitutions (OAS 3)
    • Specify substitutions for variables.

Postman Collection

  • URL Specification
    • Ensure the URL item is properly specified. Example:
      {
        "url": {
          "raw": "{{url}}/.well-known/openid-configuration?client_id={{clientId}}",
          "host": ["{{url}}"],
          "path": [".well-known", "openid-configuration"],
          "query": [
            {"key": "client_id", "value": "{{clientId}}"}
          ]
        }
      }
      
    • Avoid incomplete URL structures. Example of incorrect URL:
      "url": {"raw": "{{url}}/.well-known/openid-configuration?client_id={{clientId}}"}
      
  • Ensure every environmental variable has a value.
  • Use dynamic variables to generate random values per request.
    "variable": [
      {"key": "batchResultId", "value": "{{$guid}}"}
    ]
    

Configuring an API Schema

πŸ‘

Note

IBM API Connect Support now accessible to users, allows for seamless integration with Swagger 2.0 and OpenAPI 3.0 (already supported). With this update, creating scans using the IBM API Connect specification directly exported from API Connect is a breeze, eliminating the need for additional schema conversion.

Bright validates the API schemas you upload for a new scan, either via the Bright storage or directly during the scan setup. If the schema is configured incorrectly (breaks the specification rules), the Bright Schema Editor (Linter) will mark the file as β€œnot ready for scanning”, display an error message and prevent the user from running a scan.

You can easily detect invalid files which cannot be used for a scan by the following indicators:

  • If an uploaded file contains an error (for example, a host/server is not specified in the schema, or some parameters are specified incorrectly), then it will be indicated as NOT ready for scanning in the relevant column of the Bright storage.
  • The API schemas that are not ready for scanning are also marked with a warning icon (meaning that fixes are required) when selecting a pre-uploaded file during the scan setup.
1564
  • If a file that requires fixes is selected during the scan setup, the following warning message appears below API settings: β€œThe selected specification file cannot be used to start a scan. Please use the Schema Editor to fix the issues”.
1559

If an API schema is not ready for scanning, then you should first correct it according to the specifications using the Schema Editor. See Edit an Uploaded API Schema for more information.

The Start scan button will be disabled until you fix all the errors in the schema.

The examples of API schemas that can be properly defined and accepted for scanning by Bright are given below.

Example 1: Swagger.json

{
 "swagger": "2.0",
 "info": {
   "title": "schema",
   "description": "My API Schema",
   "version": "0.4.5"
 },
 "host": "brokencrystals.com",
 "basePath": "/home",
 "schemes": [
   "https"
 ],
 "paths": {
   "/user/{userEmail}": {
     "get": {
       "parameters": [
         {
           "in": "path",
           "name": "userEmail",
           "required": true,
           "type": "string",
           "default": "[email protected]"
         }
       ],
       "produces": [
         "application/json"
       ],
       "responses": {
         "200": {
           "description": "OK"
         }
       }
     }
   }
 }
}

Example 2: Swagger.yaml

swagger: "2.0"
info:
 title: schema
 description: My API Schema
 version: 0.4.5
host: brokencrystals.com
basePath: /home
schemes:
 - https
paths:
 /user/{userEmail}:
   get:
     parameters:
     - in: path
       name: userEmail
       required: true
       type: "string"
       default: "[email protected]"
     produces:
       - application/json
     responses:
       200:
         description: OK

Example 3: OpenAPI.json

{
 "openapi": "3.0.1",
 "info": {
   "title": "schema",
   "description": "My API Schema",
   "version": "0.4.5"
 },
 "servers": [
   {
     "url": "https://brokencrystals.com/{basePath}",
     "variables": {
       "basePath": {
         "default": "/home"
       }
     }
   }
 ],
 "paths": {
   "/user/{userEmail}": {
     "post": {
       "operationId": "userEmail",
       "parameters": [
         {
           "name": "userEmail",
           "in": "path",
           "required": true,
           "schema": {
             "type": "string",
             "default": "[email protected]"
           }
         }
       ],
       "responses": {
         "200": {
           "description": "200 response",
           "content": {
             "application/json": {
               "schema": {
                 "$ref": "#"
               }
             }
           }
         }
       }
     }
   }
 }
}

Example 4: OpenAPI.yaml

openapi: "3.0.1"
info:
 title: "schema"
 description: "My API Schema"
 version: "0.4.5"
servers:
- url: "https://brokencrystals.com/{basePath}"
  variables:
   basePath:
     default: "/home"
paths:
 /user/{userEmail}:
   post:
     operationId: "userEmail"
     parameters:
     - name: "userEmail"
       in: "path"
       required: true
       schema:
         type: "string"
         default: "[email protected]"
     responses:
       "200":
         description: "200 response"
         content:
           application/json:
             schema:
               $ref: "#"

Example 5: Postman

{
  "info": {
     "name": "schema",
     "description": "My API Schema",
     "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
     {
        "name": "/user/:userEmail",
        "request": {
           "method": "GET",
           "header": [],
           "url": {
              "raw": "{{baseUrl}}/user/:userEmail",
              "host": [
                 "{{baseUrl}}"
              ],
              "path": [
                 "user",
                 ":userEmail"
              ],
              "variable": [
                 {
                    "key": "userEmail",
                    "value": "docs@brightsec",
                    "description": "(Required) "
                 }
              ]
           }
        },
        "response": [
           {
              "name": "OK",
              "originalRequest": {
                 "method": "GET",
                 "header": [],
                 "url": {
                    "raw": "{{baseUrl}}/user/:userEmail",
                    "host": [
                       "{{baseUrl}}"
                    ],
                    "path": [
                       "user",
                       ":userEmail"
                    ],
                    "variable": [
                       {
                          "key": "userEmail"
                       }
                    ]
                 }
              },
              "status": "OK",
              "code": 200,
              "header": [
                 {
                    "key": "Content-Type",
                    "value": "text/plain"
                 }
              ],
              "cookie": [],
              "body": ""
           }
        ]
     }
  ],
  "variable": [
     {
        "key": "baseUrl",
        "value": "https://brokencrystals.com/home",
        "type": "string"
     }
  ]
}

Editing an API Schema

The Bright Schema Editor is a smart tool for parsing, validating, and editing API schemas to ensure efficient scans. It highlights incorrectly configured endpoints and root nodes with warning and error icons, making issues easy to spot and fix. Error messages include links to the issue's exact location in the schema and a brief description, enabling quick corrections. This helps users meet standard specifications and Bright's requirements, ensuring high-quality scan results.

πŸ‘

Tip:

The Schema Editor supports some features of standard parsers to simplify schema configuration. For example, for repeated nodes in the YAML files, you can identify the first occurrence of the node (object) by an anchor (mark with the ampersand - β€œ&”). Each subsequent occurrence is serialized as an alias node (referenced with an asterisk - β€œ*”) which refers back to this anchor. To get more information, see the YAML specification.

The Schema Editor allows you to view a schema in two modes: a raw schema view and a smart view. The smart view provides a clear breakdown of endpoints and represents all parameters as separate fields. The fields with incorrect or missing values are highlighted and accompanied by a corresponding warning or error message.

Step-by-Step guide

To edit an API schema uploaded for a scan, follow these steps:

  1. Click Open in schema editor next to the selected file.
1561
  1. Fix the configuration issues in the schema based on the error messages displayed at the bottom of the Schema Editor.

    You will not be able to start a scan until you fix all the errors indicated with a red icon in the navigation tree and the smart view. The configuration issues that do not prevent running a scan are indicated with a yellow warning icon in the navigation tree and the smart view.

    You can find the detailed information about configuration requirements and error types in the Troubleshooting section.

1564

πŸ“˜

Note:

Wording of the error cause may differ depending on the browser. The sample screenshots are made based on the Chrome browser.

πŸ‘

Tips:

  • You can easily switch between the error messages using the navigation buttons on the error popup.
  • In the smart view, you can filter the endpoints to show only those with problems by selecting the relevant checkbox to the left of the Search bar.
  • In the schema view, you can use the following keybindings for easy search and navigation:
    • Ctrl-F / Cmd-F: Start searching
    • Ctrl-G / Cmd-G: Find next
    • Shift-Ctrl-G / Shift-Cmd-G: Find previous
    • Shift-Ctrl-F / Cmd-Option-F: Replace
    • Shift-Ctrl-R / Shift-Cmd-Option-F: Replace all
  1. After you fix the configuration issues, click Save & Close to save the changes and proceed with the scan setup.

Troubleshooting

Bright parses an uploaded API schema to define the attack surface of the scanned target. If the schema is misconfigured, Bright displays the corresponding warnings and error messages in the Schema Editor.

This section provides guidelines on how to deal with the configuration issues that may occur while uploading an API schema for a new scan and editing it in the Schema Editor. To learn how to work with the Schema Editor, see Edit an Uploaded API Schema.

Configuration issues overview

All configuration issues can be divided into two groups:

  • The issues that may affect the scan results but do not prevent running a scan. Such issues are indicated with yellow warning icons in the navigation tree and the smart view of the Schema Editor, and are usually caused by some missing values. To ensure the best scan results, it is recommended to resolve all the warnings that the Schema Editor points out.
1554
  • Critical issues (errors) that prevent using the schema for a scan. Such issues are indicated with red error icons in the navigation tree and the smart view of the Schema Editor. They are also accompanied with the corresponding error messages at the bottom of the Schema Editor. The messages usually contain a link (path) to the place in the schema view where the issue is found and a short description of the error cause.
1566

Hierarchically, there are several levels of errors depending on their cause:

  • Syntax errors. They have the highest priority and, therefore, are displayed first in case of multiple errors of different origin. You will be able to see other errors only after you fix the syntax errors.
1565
  • Validation errors. It mostly involves incorrect specification of property names and their values. Structurally, they are presented as <location_prefix>: <error_message>, where:

    • <location_prefix> is either "Error at /path" or "Error at the schema root", where the underlined part is a link to a specific place in the schema. An external path (to an endpoint, an object) starts from /, while all items inside an object (internal path) are separated with .
    • <error_message> is a short description of the error cause.

    Below is an example of a validation error caused by incorrect data type of a value. On the screenshot, the host (url) is expected to be a string, but an additional character was added to demonstrate the error.

1555
  • Converting errors. Such errors may occur when the converter cannot generate a .HAR file based on the schema due to invalid configuration. For example:
    • When a sample value cannot be generated due to incorrect (contradicting) conditions. On the screenshot below the minimum number was set to 30, and the maximum number was set to 10. No number can meet these conditions, which results in a converting error.
1403
  • When prefixing item-level host property with a character like ^ in a Postman collection.
1554

OpenAPI/Swagger schema validation checklist

If you get a parsing error when uploading an OpenAPI schema to Bright, validate and correct the schema configuration according to the following checklist:

  1. A target server (host) must be specified:

    • If you are using OpenAPI 3+, include the servers property.
    • (For OAS 3). If the servers values contain variables, it is recommended to define them explicitly (use variable substitutions) to ensure correct scan results. See item 4 for more information.
    • If you are using a Swagger 2+ schema, include the host property.
  2. OAS 3 may include multiple servers. Here is an example taken from the Swagger documentation:

}
 "servers": [
   {
     "url": "https://development.gigantic-server.com/v1",
     "description": "Development server"
   },
   {
     "url": "https://staging.gigantic-server.com/v1",
     "description": "Staging server"
   },
   {
     "url": "https://api.gigantic-server.com/v1",
     "description": "Production server"
   }
 ]
}

Bright uses the FIRST element in the servers array as a scan target. If the first server in your schema is not the scan target, you need to change the order of the servers manually in the schema view, or use the Server field in the smart view. Once you select the server to be placed first in the smart view, the order of the servers will be updated automatically in the schema view.

843
  1. To ensure correct and complete scan results, values for all parameters should be specified. You can add the values directly to the raw schema or enter them in the corresponding Value fields in the smart view.

    If no parameter value is provided:

  • If the corresponding value field in the Schema Editor is left empty, a warning icon will appear next to the endpoint.
1410
  • Bright automatically defines the data type and generates a random alternate value when parsing the schema.
    By specifying the substitutions, you ensure correct and complete scan results.

πŸ‘

Tip:

During generation of a random value, Bright takes in to account all the constraints defined for a certain data type in the schema. By specifying the constraints, you ensure better results of alternate values generation. For example, you can use the following constraints:

  • For numbers – minimum, maximum
  • For strings – pattern , minLength, maxLength
  • For arrays – maxItems, minItems, uniqueItems
  • For objects – additionalProperties, minProperties, maxProperties

For more information, see the Swagger documentation.

  1. (For OAS 3). If variables are used for a server configuration, you should specify substitutions to ensure correct scan results. Bright automatically detects the data type if no substitution is used and generates a random alternate value when parsing the schema.

    The values in the smart view are displayed with the variables applied. In the example below, we set the domain and apiVersion variables for a server in the schema view:

"servers": [
   {
     "url": "https://{domain}/apis/{apiVersion}",
     "description": "Code API",
     "variables": {
      "domain": {
       "default": "coda.io"
     },
     "apiVersion": {
      "default": "v1"
     }
    }
   }
  ]

In this case, the server in the smart view will be displayed as follows: <https://coda.io/apis/v1>.

Postman collection validation checklist

If you get a parsing error when uploading a Postman collection to Bright, validate and correct the schema configuration according to the following checklist:

  1. The URL item must be specified properly, for example:

  • Literal
{{url}}/.well-known/openid-configuration?client_id={{clientId}}
  • Broken-down
{
 "url": {
   "raw": "{{url}}/.well-known/openid-configuration?client_id={{clientId}}",
   "host": [
     "{{url}}"
   ],
   "path": [
     ".well-known",
     "openid-configuration"
   ],
   "query": [
     {
       "key": "client_id",
       "value": "{{clientId}}"
     }
   ]
 }
}

A problem may arise when the structure of a broken-down URL is incorrect, or the required (expected) fields are missing. Please refer to the Postman documentation for more information.

Here is an example of an incomplete URL:

"url": { 
    "raw": "{{url}}/.well-known/openid-configuration?client_id={{clientId}}"
    }
  1. Every environmental variable must have a value.

    The Schema Editor supports the Postman feature of dynamic variables. This allows you to generate random values per request, for example:

"variable": [
                {
                  "key": "batchResultId",
                  "value": "{{$guid}}"
                }

The dynamic variables can also be used to generate values when converting a Postman collection into a .HAR file.