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

[8.x] Unauthorized route migration for routes owned by kibana-security (#198334) #199382

Merged
merged 1 commit into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/plugins/interactive_setup/server/routes/configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ export function defineConfigureRoute({
router.post(
{
path: '/internal/interactive_setup/configure',
security: {
authz: {
enabled: false,
reason:
'Interactive setup is strictly a "pre-boot" feature which cannot leverage conventional authorization.',
},
},
validate: {
body: schema.object({
host: schema.uri({ scheme: ['http', 'https'] }),
Expand Down
7 changes: 7 additions & 0 deletions src/plugins/interactive_setup/server/routes/enroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ export function defineEnrollRoutes({
router.post(
{
path: '/internal/interactive_setup/enroll',
security: {
authz: {
enabled: false,
reason:
'Interactive setup is strictly a "pre-boot" feature which cannot leverage conventional authorization.',
},
},
validate: {
body: schema.object({
hosts: schema.arrayOf(schema.uri({ scheme: 'https' }), {
Expand Down
7 changes: 7 additions & 0 deletions src/plugins/interactive_setup/server/routes/ping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ export function definePingRoute({ router, logger, elasticsearch, preboot }: Rout
router.post(
{
path: '/internal/interactive_setup/ping',
security: {
authz: {
enabled: false,
reason:
'Interactive setup is strictly a "pre-boot" feature which cannot leverage conventional authorization.',
},
},
validate: {
body: schema.object({
host: schema.uri({ scheme: ['http', 'https'] }),
Expand Down
7 changes: 7 additions & 0 deletions src/plugins/interactive_setup/server/routes/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ export function defineStatusRoute({ router, elasticsearch, preboot }: RouteDefin
router.get(
{
path: '/internal/interactive_setup/status',
security: {
authz: {
enabled: false,
reason:
'Interactive setup is strictly a "pre-boot" feature which cannot leverage conventional authorization.',
},
},
validate: false,
options: { authRequired: false },
},
Expand Down
7 changes: 7 additions & 0 deletions src/plugins/interactive_setup/server/routes/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ export function defineVerifyRoute({ router, verificationCode }: RouteDefinitionP
router.post(
{
path: '/internal/interactive_setup/verify',
security: {
authz: {
enabled: false,
reason:
'Interactive setup is strictly a "pre-boot" feature which cannot leverage conventional authorization.',
},
},
validate: {
body: schema.object({
code: schema.string(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ export function defineRecordAnalyticsOnAuthTypeRoutes({
router.post(
{
path: '/internal/security/analytics/_record_auth_type',
security: {
authz: {
enabled: false,
reason:
'This route delegates authorization to the scoped ES cluster client of the internal authentication service',
},
},
validate: {
body: schema.nullable(
schema.object({ signature: schema.string(), timestamp: schema.number() })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ export function defineRecordViolations({ router, analyticsService }: RouteDefini
router.post(
{
path: '/internal/security/analytics/_record_violations',
security: {
authz: {
enabled: false,
reason:
'This route is used by browsers to report CSP and Permission Policy violations. These requests are sent without authentication per the browser spec.',
},
},
validate: {
/**
* Chrome supports CSP3 spec and sends an array of reports. Safari only sends a single
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,17 @@ export function defineAnonymousAccessGetCapabilitiesRoutes({
getAnonymousAccessService,
}: RouteDefinitionParams) {
router.get(
{ path: '/internal/security/anonymous_access/capabilities', validate: false },
{
path: '/internal/security/anonymous_access/capabilities',
security: {
authz: {
enabled: false,
reason:
'This route delegates authorization to the scoped ES cluster client of the anonymous access service',
},
},
validate: false,
},
async (_context, request, response) => {
const anonymousAccessService = getAnonymousAccessService();
return response.ok({ body: await anonymousAccessService.getCapabilities(request) });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@ export function defineAnonymousAccessGetStateRoutes({
getAnonymousAccessService,
}: RouteDefinitionParams) {
router.get(
{ path: '/internal/security/anonymous_access/state', validate: false },
{
path: '/internal/security/anonymous_access/state',
security: {
authz: {
enabled: false,
reason: 'This route is used for anonymous access',
},
},
validate: false,
},
async (_context, _request, response) => {
const anonymousAccessService = getAnonymousAccessService();
const accessURLParameters = anonymousAccessService.accessURLParameters
Expand Down
7 changes: 7 additions & 0 deletions x-pack/plugins/security/server/routes/api_keys/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ export function defineCreateApiKeyRoutes({
router.post(
{
path: '/internal/security/api_key',
security: {
authz: {
enabled: false,
reason:
'This route delegates authorization to the scoped ES cluster client of the internal authentication service',
},
},
validate: {
body: schema.oneOf([
restApiKeySchema,
Expand Down
7 changes: 7 additions & 0 deletions x-pack/plugins/security/server/routes/api_keys/enabled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ export function defineEnabledApiKeysRoutes({
router.get(
{
path: '/internal/security/api_key/_enabled',
security: {
authz: {
enabled: false,
reason:
'This route delegates authorization to the scoped ES cluster client of the internal authentication service',
},
},
validate: false,
},
createLicensedRouteHandler(async (context, request, response) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ export function defineHasApiKeysRoutes({
router.get(
{
path: '/internal/security/api_key/_has_active',
security: {
authz: {
enabled: false,
reason: `This route delegates authorization to the scoped ES cluster client of the internal authentication service, and to Core's ES client`,
},
},
validate: false,
options: {
access: 'internal',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ export function defineInvalidateApiKeysRoutes({ router }: RouteDefinitionParams)
router.post(
{
path: '/internal/security/api_key/invalidate',
security: {
authz: {
enabled: false,
reason: `This route delegates authorization to Core's ES client`,
},
},
validate: {
body: schema.object({
apiKeys: schema.arrayOf(schema.object({ id: schema.string(), name: schema.string() })),
Expand Down
6 changes: 6 additions & 0 deletions x-pack/plugins/security/server/routes/api_keys/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ export function defineQueryApiKeysAndAggregationsRoute({
// on behalf of the user making the request and governed by the user's own cluster privileges.
{
path: '/internal/security/api_key/_query',
security: {
authz: {
enabled: false,
reason: `This route delegates authorization to the scoped ES cluster client of the internal authentication service, and to Core's ES client`,
},
},
validate: {
body: schema.object({
query: schema.maybe(schema.object({}, { unknowns: 'allow' })),
Expand Down
6 changes: 6 additions & 0 deletions x-pack/plugins/security/server/routes/api_keys/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ export function defineUpdateApiKeyRoutes({
router.put(
{
path: '/internal/security/api_key',
security: {
authz: {
enabled: false,
reason: `This route delegates authorization to the scoped ES cluster client of the internal authentication service`,
},
},
validate: {
body: schema.oneOf([
updateRestApiKeySchema,
Expand Down
37 changes: 34 additions & 3 deletions x-pack/plugins/security/server/routes/authentication/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ export function defineCommonRoutes({
router.get(
{
path,
security: {
authz: {
enabled: false,
reason: 'This route must remain accessible to 3rd-party IdPs',
},
},
// Allow unknown query parameters as this endpoint can be hit by the 3rd-party with any
// set of query string parameters (e.g. SAML/OIDC logout request/response parameters).
validate: { query: schema.object({}, { unknowns: 'allow' }) },
Expand Down Expand Up @@ -92,7 +98,17 @@ export function defineCommonRoutes({
]) {
const deprecated = path === '/api/security/v1/me';
router.get(
{ path, validate: false, options: { access: deprecated ? 'public' : 'internal' } },
{
path,
security: {
authz: {
enabled: false,
reason: `This route delegates authorization to Core's security service; there must be an authenticated user for this route to return information`,
},
},
validate: false,
options: { access: deprecated ? 'public' : 'internal' },
},
createLicensedRouteHandler(async (context, request, response) => {
if (deprecated) {
logger.warn(
Expand Down Expand Up @@ -135,10 +151,16 @@ export function defineCommonRoutes({
}

// Register the login route for serverless for the time being. Note: This route will move into the buildFlavor !== 'serverless' block below. See next line.
// ToDo: In the serverless environment, we do not support API login - the only valid authentication methodology (or maybe just method or mechanism?) is SAML
// ToDo: In the serverless environment, we do not support API login - the only valid authentication type is SAML
router.post(
{
path: '/internal/security/login',
security: {
authz: {
enabled: false,
reason: `This route provides basic and token login capbility, which is delegated to the internal authentication service`,
},
},
validate: {
body: schema.object({
providerType: schema.string(),
Expand Down Expand Up @@ -183,7 +205,16 @@ export function defineCommonRoutes({
if (buildFlavor !== 'serverless') {
// In the serverless offering, the access agreement functionality isn't available.
router.post(
{ path: '/internal/security/access_agreement/acknowledge', validate: false },
{
path: '/internal/security/access_agreement/acknowledge',
security: {
authz: {
enabled: false,
reason: `This route delegates authorization to the internal authentication service; there must be an authenticated user for this route to function`,
},
},
validate: false,
},
createLicensedRouteHandler(async (context, request, response) => {
// If license doesn't allow access agreement we shouldn't handle request.
if (!license.getFeatures().allowAccessAgreement) {
Expand Down
18 changes: 18 additions & 0 deletions x-pack/plugins/security/server/routes/authentication/oidc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ export function defineOIDCRoutes({
router.get(
{
path,
security: {
authz: {
enabled: false,
reason: 'This route must remain accessible to 3rd-party OIDC providers',
},
},
validate: {
query: schema.object(
{
Expand Down Expand Up @@ -176,6 +182,12 @@ export function defineOIDCRoutes({
router.post(
{
path,
security: {
authz: {
enabled: false,
reason: 'This route must remain accessible to 3rd-party OIDC providers',
},
},
validate: {
body: schema.object(
{
Expand Down Expand Up @@ -221,6 +233,12 @@ export function defineOIDCRoutes({
router.get(
{
path: '/api/security/oidc/initiate_login',
security: {
authz: {
enabled: false,
reason: 'This route must remain accessible to 3rd-party OIDC providers',
},
},
validate: {
query: schema.object(
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ export function defineSAMLRoutes({
router.post(
{
path,
security: {
authz: {
enabled: false,
reason: 'This route must remain accessible to 3rd-party SAML providers',
},
},
validate: {
body: schema.object(
{ SAMLResponse: schema.string(), RelayState: schema.maybe(schema.string()) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ export function defineGetPrivilegesRoutes({ router, authz }: RouteDefinitionPara
router.get(
{
path: '/api/security/privileges',
security: {
authz: {
enabled: false,
reason:
'This route is opted out from authorization because it returns only the global list of Kibana privileges',
},
},
validate: {
query: schema.object({
// We don't use `schema.boolean` here, because all query string parameters are treated as
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@ import type { RouteDefinitionParams } from '../..';

export function defineGetBuiltinPrivilegesRoutes({ router }: RouteDefinitionParams) {
router.get(
{ path: '/internal/security/esPrivileges/builtin', validate: false },
{
path: '/internal/security/esPrivileges/builtin',
security: {
authz: {
enabled: false,
reason: `This route delegates authorization to Core's scoped ES cluster client`,
},
},
validate: false,
},
async (context, request, response) => {
const esClient = (await context.core).elasticsearch.client;
const privileges = await esClient.asCurrentUser.security.getBuiltinPrivileges();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ export function defineDeleteRolesRoutes({ router }: RouteDefinitionParams) {
.addVersion(
{
version: API_VERSIONS.roles.public.v1,
security: {
authz: {
enabled: false,
reason: `This route delegates authorization to Core's scoped ES cluster client`,
},
},
validate: {
request: {
params: schema.object({ name: schema.string({ minLength: 1 }) }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ export function defineGetRolesRoutes({
.addVersion(
{
version: API_VERSIONS.roles.public.v1,
security: {
authz: {
enabled: false,
reason: `This route delegates authorization to Core's scoped ES cluster client`,
},
},
validate: {
request: {
params: schema.object({
Expand Down
Loading