VYPR
High severityNVD Advisory· Published Feb 17, 2026· Updated Feb 17, 2026

Apache NiFi: Missing Authorization of Restricted Permissions for Component Updates

CVE-2026-25903

Description

Apache NiFi 1.1.0 through 2.7.2 are missing authorization when updating configuration properties on extension components that have specific Required Permissions based on the Restricted annotation. The Restricted annotation indicates additional privileges required to add the annotated component to the flow configuration, but framework authorization did not check restricted status when updating a component previously added. The missing authorization requires a more privileged user to add a restricted component to the flow configuration, but permits a less privileged user to make property configuration changes. Apache NiFi installations that do not implement different levels of authorization for Restricted components are not subject to this vulnerability because the framework enforces write permissions as the security boundary. Upgrading to Apache NiFi 2.8.0 is the recommended mitigation.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Apache NiFi 1.1.0–2.7.2 lacks authorization checks for updating restricted components, allowing lower-privileged users to modify properties after a privileged user adds them.

Vulnerability

Apache NiFi versions 1.1.0 through 2.7.2 contain a missing authorization vulnerability when updating configuration properties on extension components that are annotated as Restricted [1][4]. The Restricted annotation requires additional privileges to add the component to the flow, but once added, the framework does not re-check those privileges during property updates. This allows a user with lower privileges to modify the component's configuration after it has been added by a more privileged user [1][4].

Exploitation

An attacker with only write permissions to the flow—but not the specific Restricted permissions—can alter the configuration properties of a previously added restricted component. No authentication bypass or network position beyond normal API access is required; the missing check occurs in the authorization logic for property updates [2]. The vulnerability affects all installations that enforce distinct authorization levels for Restricted components [1].

Impact

A lower-privileged user can effectively re-configure a restricted component, potentially altering data processing behavior, exfiltrating data, or disrupting operations. This is a privilege escalation within the NiFi authorization model, as the attacker gains the ability to modify components they should not be able to control [1][4].

Mitigation

Upgrading to Apache NiFi 2.8.0 is the recommended mitigation, as it includes the fix that re-evaluates Restricted permissions during component updates [2]. Installations that do not differentiate authorization for Restricted components are not vulnerable, since write permissions act as the sole security boundary [1].

AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.nifi:nifi-web-apiMaven
>= 1.1.0, < 2.8.02.8.0

Affected products

2
  • Apache/Nifillm-fuzzy
    Range: >= 1.1.0, <= 2.7.2
  • Apache Software Foundation/Apache NiFiv5
    Range: 1.1.0

Patches

1
119f8881fbc3

NIFI-15567 Streamlined Component Authorizable Evaluation Methods

https://github.com/apache/nifiexceptionfactoryFeb 7, 2026via ghsa
10 files changed · +229 164
  • nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeComponentReference.java+86 0 added
    @@ -0,0 +1,86 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +package org.apache.nifi.authorization;
    +
    +import org.apache.nifi.authorization.resource.Authorizable;
    +import org.apache.nifi.authorization.user.NiFiUser;
    +import org.apache.nifi.authorization.user.NiFiUserUtils;
    +import org.apache.nifi.web.api.dto.BundleDTO;
    +
    +import java.util.Map;
    +
    +public final class AuthorizeComponentReference {
    +    /**
    +     * Authorize configuration of specified Component Type including restrictions and referenced Controller Services
    +     *
    +     * @param authorizer Authorizer responsible for handling decisions
    +     * @param authorizableLookup Authorizable Lookup for resolving referenced Controller Services
    +     * @param componentType Component Type to be evaluated
    +     * @param componentBundle Component Bundle to be evaluated
    +     * @param properties Component configuration properties or null when not available for evaluation
    +     * @param parameterContext Parameter Context or null when not available for evaluation
    +     */
    +    public static void authorizeComponentConfiguration(
    +            final Authorizer authorizer,
    +            final AuthorizableLookup authorizableLookup,
    +            final String componentType,
    +            final BundleDTO componentBundle,
    +            final Map<String, String> properties,
    +            final Authorizable parameterContext
    +    ) {
    +        ComponentAuthorizable authorizable = null;
    +        try {
    +            authorizable = authorizableLookup.getConfigurableComponent(componentType, componentBundle);
    +            authorizeComponentConfiguration(authorizer, authorizableLookup, authorizable, properties, parameterContext);
    +        } finally {
    +            if (authorizable != null) {
    +                authorizable.cleanUpResources();
    +            }
    +        }
    +    }
    +
    +    /**
    +     * Authorize configuration of specified Component including restrictions and referenced Controller Services
    +     *
    +     * @param authorizer Authorizer responsible for handling decisions
    +     * @param authorizableLookup Authorizable Lookup for resolving referenced Controller Services
    +     * @param componentAuthorizable Component Authorizable to be evaluated
    +     * @param properties Component configuration properties required
    +     * @param parameterContext Parameter Context or null when not available for evaluation
    +     */
    +    public static void authorizeComponentConfiguration(
    +            final Authorizer authorizer,
    +            final AuthorizableLookup authorizableLookup,
    +            final ComponentAuthorizable componentAuthorizable,
    +            final Map<String, String> properties,
    +            final Authorizable parameterContext
    +    ) {
    +        final NiFiUser user = NiFiUserUtils.getNiFiUser();
    +
    +        if (componentAuthorizable.isRestricted()) {
    +            componentAuthorizable.getRestrictedAuthorizables().forEach(restrictionAuthorizable ->
    +                    restrictionAuthorizable.authorize(authorizer, RequestAction.WRITE, user)
    +            );
    +        }
    +
    +        AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, componentAuthorizable, authorizer, authorizableLookup);
    +
    +        if (parameterContext != null) {
    +            AuthorizeParameterReference.authorizeParameterReferences(properties, authorizer, parameterContext, user);
    +        }
    +    }
    +}
    
  • nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/authorization/AuthorizeParameterReference.java+0 22 modified
    @@ -28,10 +28,6 @@
     import org.apache.nifi.parameter.ParameterParser;
     import org.apache.nifi.parameter.ParameterTokenList;
     import org.apache.nifi.web.NiFiServiceFacade;
    -import org.apache.nifi.web.api.dto.ControllerServiceDTO;
    -import org.apache.nifi.web.api.dto.FlowSnippetDTO;
    -import org.apache.nifi.web.api.dto.ProcessorConfigDTO;
    -import org.apache.nifi.web.api.dto.ProcessorDTO;
     
     import java.util.List;
     import java.util.Map;
    @@ -105,24 +101,6 @@ public static void authorizeParameterReferences(final ComponentAuthorizable auth
             }
         }
     
    -    public static void authorizeParameterReferences(final FlowSnippetDTO flowSnippet, final Authorizer authorizer, final Authorizable parameterContextAuthorizable, final NiFiUser user) {
    -        for (final ProcessorDTO processorDto : flowSnippet.getProcessors()) {
    -            final ProcessorConfigDTO configDto = processorDto.getConfig();
    -            if (configDto == null) {
    -                continue;
    -            }
    -
    -            authorizeParameterReferences(configDto.getProperties(), authorizer, parameterContextAuthorizable, user);
    -        }
    -
    -        for (final ControllerServiceDTO serviceDto : flowSnippet.getControllerServices()) {
    -            authorizeParameterReferences(serviceDto.getProperties(), authorizer, parameterContextAuthorizable, user);
    -        }
    -
    -        // Note: there is no need to recurse here because when a snippet is instantiated, if there are any components in child Process Groups, a new Process Group will be created
    -        // without any Parameter Context, so there is no need to perform any authorization beyond the top-level group where the instantiation is occurring.
    -    }
    -
         /**
          * If any parameter is referenced by the given component node, will authorize user against the given group's Parameter context
          * @param destinationGroup the group that the component is being moved to
    
  • nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java+21 67 modified
    @@ -40,6 +40,7 @@
     import jakarta.ws.rs.core.Response;
     import jakarta.ws.rs.core.StreamingOutput;
     import org.apache.commons.lang3.StringUtils;
    +import org.apache.nifi.authorization.AuthorizeComponentReference;
     import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
     import org.apache.nifi.authorization.Authorizer;
     import org.apache.nifi.authorization.ComponentAuthorizable;
    @@ -69,6 +70,7 @@
     import org.apache.nifi.web.api.concurrent.StandardUpdateStep;
     import org.apache.nifi.web.api.concurrent.UpdateStep;
     import org.apache.nifi.web.api.dto.BulletinDTO;
    +import org.apache.nifi.web.api.dto.BundleDTO;
     import org.apache.nifi.web.api.dto.ClusterDTO;
     import org.apache.nifi.web.api.dto.ComponentStateDTO;
     import org.apache.nifi.web.api.dto.ConfigVerificationResultDTO;
    @@ -126,6 +128,7 @@
     import java.util.Collections;
     import java.util.Date;
     import java.util.List;
    +import java.util.Map;
     import java.util.Set;
     import java.util.UUID;
     import java.util.concurrent.TimeUnit;
    @@ -322,22 +325,10 @@ public Response createParameterProvider(
                     lookup -> {
                         authorizeController(RequestAction.WRITE);
     
    -                    ComponentAuthorizable authorizable = null;
    -                    try {
    -                        authorizable = lookup.getConfigurableComponent(requestParameterProvider.getType(), requestParameterProvider.getBundle());
    -
    -                        if (authorizable.isRestricted()) {
    -                            authorizeRestrictions(authorizer, authorizable);
    -                        }
    -
    -                        if (requestParameterProvider.getProperties() != null) {
    -                            AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestParameterProvider.getProperties(), authorizable, authorizer, lookup);
    -                        }
    -                    } finally {
    -                        if (authorizable != null) {
    -                            authorizable.cleanUpResources();
    -                        }
    -                    }
    +                    final String componentType = requestParameterProvider.getType();
    +                    final BundleDTO bundle = requestParameterProvider.getBundle();
    +                    final Map<String, String> properties = requestParameterProvider.getProperties();
    +                    AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, componentType, bundle, properties, null);
                     },
                     () -> serviceFacade.verifyCreateParameterProvider(requestParameterProvider),
                     (parameterProviderEntity) -> {
    @@ -485,22 +476,10 @@ public Response createReportingTask(
                     lookup -> {
                         authorizeController(RequestAction.WRITE);
     
    -                    ComponentAuthorizable authorizable = null;
    -                    try {
    -                        authorizable = lookup.getConfigurableComponent(requestReportingTask.getType(), requestReportingTask.getBundle());
    -
    -                        if (authorizable.isRestricted()) {
    -                            authorizeRestrictions(authorizer, authorizable);
    -                        }
    -
    -                        if (requestReportingTask.getProperties() != null) {
    -                            AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestReportingTask.getProperties(), authorizable, authorizer, lookup);
    -                        }
    -                    } finally {
    -                        if (authorizable != null) {
    -                            authorizable.cleanUpResources();
    -                        }
    -                    }
    +                    final String componentType = requestReportingTask.getType();
    +                    final BundleDTO bundle = requestReportingTask.getBundle();
    +                    final Map<String, String> properties = requestReportingTask.getProperties();
    +                    AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, componentType, bundle, properties, null);
                     },
                     () -> serviceFacade.verifyCreateReportingTask(requestReportingTask),
                     (reportingTaskEntity) -> {
    @@ -649,22 +628,10 @@ public Response createFlowAnalysisRule(
                     lookup -> {
                         authorizeController(RequestAction.WRITE);
     
    -                    ComponentAuthorizable authorizable = null;
    -                    try {
    -                        authorizable = lookup.getConfigurableComponent(requestFlowAnalysisRule.getType(), requestFlowAnalysisRule.getBundle());
    -
    -                        if (authorizable.isRestricted()) {
    -                            authorizeRestrictions(authorizer, authorizable);
    -                        }
    -
    -                        if (requestFlowAnalysisRule.getProperties() != null) {
    -                            AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestFlowAnalysisRule.getProperties(), authorizable, authorizer, lookup);
    -                        }
    -                    } finally {
    -                        if (authorizable != null) {
    -                            authorizable.cleanUpResources();
    -                        }
    -                    }
    +                    final String componentType = requestFlowAnalysisRule.getType();
    +                    final BundleDTO bundle = requestFlowAnalysisRule.getBundle();
    +                    final Map<String, String> properties = requestFlowAnalysisRule.getProperties();
    +                    AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, componentType, bundle, properties, null);
                     },
                     () -> serviceFacade.verifyCreateFlowAnalysisRule(requestFlowAnalysisRule),
                     (flowAnalysisRuleEntity) -> {
    @@ -819,9 +786,8 @@ public Response updateFlowAnalysisRule(
                         authorizeController(RequestAction.WRITE);
     
                         final ComponentAuthorizable authorizable = lookup.getFlowAnalysisRule(id);
    -
    -                    // authorize any referenced services
    -                    AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestFlowAnalysisRuleDTO.getProperties(), authorizable, authorizer, lookup);
    +                    final Map<String, String> componentProperties = requestFlowAnalysisRuleDTO.getProperties();
    +                    AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, authorizable, componentProperties, null);
                     },
                     () -> serviceFacade.verifyUpdateFlowAnalysisRule(requestFlowAnalysisRuleDTO),
                     (revision, flowAnalysisRuleEntity) -> {
    @@ -2501,22 +2467,10 @@ public Response createControllerService(
                     lookup -> {
                         authorizeController(RequestAction.WRITE);
     
    -                    ComponentAuthorizable authorizable = null;
    -                    try {
    -                        authorizable = lookup.getConfigurableComponent(requestControllerService.getType(), requestControllerService.getBundle());
    -
    -                        if (authorizable.isRestricted()) {
    -                            authorizeRestrictions(authorizer, authorizable);
    -                        }
    -
    -                        if (requestControllerService.getProperties() != null) {
    -                            AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerService.getProperties(), authorizable, authorizer, lookup);
    -                        }
    -                    } finally {
    -                        if (authorizable != null) {
    -                            authorizable.cleanUpResources();
    -                        }
    -                    }
    +                    final String componentType = requestControllerService.getType();
    +                    final BundleDTO bundle = requestControllerService.getBundle();
    +                    final Map<String, String> properties = requestControllerService.getProperties();
    +                    AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, componentType, bundle, properties, null);
                     },
                     () -> serviceFacade.verifyCreateControllerService(requestControllerService),
                     (controllerServiceEntity) -> {
    
  • nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java+4 5 modified
    @@ -39,8 +39,8 @@
     import jakarta.ws.rs.core.MediaType;
     import jakarta.ws.rs.core.Response;
     import org.apache.commons.lang3.StringUtils;
    +import org.apache.nifi.authorization.AuthorizeComponentReference;
     import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
    -import org.apache.nifi.authorization.AuthorizeParameterReference;
     import org.apache.nifi.authorization.Authorizer;
     import org.apache.nifi.authorization.ComponentAuthorizable;
     import org.apache.nifi.authorization.RequestAction;
    @@ -730,10 +730,9 @@ public Response updateControllerService(
                         final ComponentAuthorizable authorizable = lookup.getControllerService(id);
                         authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
     
    -                    // authorize any referenced services
    -                    AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerServiceDTO.getProperties(), authorizable, authorizer, lookup);
    -                    AuthorizeParameterReference.authorizeParameterReferences(requestControllerServiceDTO.getProperties(), authorizer, authorizable.getParameterContext(),
    -                            NiFiUserUtils.getNiFiUser());
    +                    final Map<String, String> properties = requestControllerServiceDTO.getProperties();
    +                    final Authorizable parameterContext = authorizable.getParameterContext();
    +                    AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, authorizable, properties, parameterContext);
                     },
                     () -> serviceFacade.verifyUpdateControllerService(requestControllerServiceDTO),
                     (revision, controllerServiceEntity) -> {
    
  • nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ParameterProviderResource.java+4 2 modified
    @@ -42,6 +42,7 @@
     import jakarta.ws.rs.core.Response;
     import org.apache.commons.lang3.StringUtils;
     import org.apache.nifi.authorization.AuthorizableLookup;
    +import org.apache.nifi.authorization.AuthorizeComponentReference;
     import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
     import org.apache.nifi.authorization.Authorizer;
     import org.apache.nifi.authorization.ComponentAuthorizable;
    @@ -645,8 +646,9 @@ public Response updateParameterProvider(
                         final ComponentAuthorizable authorizable = lookup.getParameterProvider(id);
                         authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
     
    -                    // authorize any referenced services
    -                    AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestParameterProviderDTO.getProperties(), authorizable, authorizer, lookup);
    +                    final Authorizable parameterContext = authorizable.getParameterContext();
    +                    final Map<String, String> componentProperties = requestParameterProviderDTO.getProperties();
    +                    AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, authorizable, componentProperties, parameterContext);
                     },
                     () -> serviceFacade.verifyUpdateParameterProvider(requestParameterProviderDTO),
                     (revision, parameterProviderEntity) -> {
    
  • nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessGroupResource.java+12 42 modified
    @@ -45,6 +45,7 @@
     import jakarta.ws.rs.core.UriBuilder;
     import org.apache.commons.lang3.StringUtils;
     import org.apache.nifi.authorization.AuthorizableLookup;
    +import org.apache.nifi.authorization.AuthorizeComponentReference;
     import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
     import org.apache.nifi.authorization.AuthorizeParameterProviders;
     import org.apache.nifi.authorization.AuthorizeParameterReference;
    @@ -80,6 +81,7 @@
     import org.apache.nifi.web.Revision;
     import org.apache.nifi.web.api.concurrent.AsyncRequestManager;
     import org.apache.nifi.web.api.concurrent.RequestManager;
    +import org.apache.nifi.web.api.dto.BundleDTO;
     import org.apache.nifi.web.api.dto.ConnectionDTO;
     import org.apache.nifi.web.api.dto.ControllerServiceDTO;
     import org.apache.nifi.web.api.dto.DropRequestDTO;
    @@ -136,6 +138,7 @@
     import java.io.IOException;
     import java.io.InputStream;
     import java.net.URI;
    +import java.util.Collections;
     import java.util.HashMap;
     import java.util.HashSet;
     import java.util.List;
    @@ -1313,28 +1316,11 @@ public Response createProcessor(
                         processGroup.authorize(authorizer, RequestAction.WRITE, user);
     
                         final Authorizable parameterContext = groupAuthorizable.getProcessGroup().getParameterContext();
    -                    final ProcessorConfigDTO configDto = requestProcessor.getConfig();
    -                    if (parameterContext != null && configDto != null) {
    -                        AuthorizeParameterReference.authorizeParameterReferences(configDto.getProperties(), authorizer, parameterContext, user);
    -                    }
    -
    -                    ComponentAuthorizable authorizable = null;
    -                    try {
    -                        authorizable = lookup.getConfigurableComponent(requestProcessor.getType(), requestProcessor.getBundle());
    -
    -                        if (authorizable.isRestricted()) {
    -                            authorizeRestrictions(authorizer, authorizable);
    -                        }
    -
    -                        final ProcessorConfigDTO config = requestProcessor.getConfig();
    -                        if (config != null && config.getProperties() != null) {
    -                            AuthorizeControllerServiceReference.authorizeControllerServiceReferences(config.getProperties(), authorizable, authorizer, lookup);
    -                        }
    -                    } finally {
    -                        if (authorizable != null) {
    -                            authorizable.cleanUpResources();
    -                        }
    -                    }
    +                    final ProcessorConfigDTO config = requestProcessor.getConfig();
    +                    final Map<String, String> properties = config == null ? Collections.emptyMap() : config.getProperties();
    +                    final String componentType = requestProcessor.getType();
    +                    final BundleDTO bundle = requestProcessor.getBundle();
    +                    AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, componentType, bundle, properties, parameterContext);
                     },
                     () -> serviceFacade.verifyCreateProcessor(requestProcessor),
                     processorEntity -> {
    @@ -2541,26 +2527,10 @@ public Response createControllerService(
                         processGroup.authorize(authorizer, RequestAction.WRITE, user);
     
                         final Authorizable parameterContext = groupAuthorizable.getProcessGroup().getParameterContext();
    -                    if (parameterContext != null) {
    -                        AuthorizeParameterReference.authorizeParameterReferences(requestControllerService.getProperties(), authorizer, parameterContext, user);
    -                    }
    -
    -                    ComponentAuthorizable authorizable = null;
    -                    try {
    -                        authorizable = lookup.getConfigurableComponent(requestControllerService.getType(), requestControllerService.getBundle());
    -
    -                        if (authorizable.isRestricted()) {
    -                            authorizeRestrictions(authorizer, authorizable);
    -                        }
    -
    -                        if (requestControllerService.getProperties() != null) {
    -                            AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerService.getProperties(), authorizable, authorizer, lookup);
    -                        }
    -                    } finally {
    -                        if (authorizable != null) {
    -                            authorizable.cleanUpResources();
    -                        }
    -                    }
    +                    final String componentType = requestControllerService.getType();
    +                    final BundleDTO bundle = requestControllerService.getBundle();
    +                    final Map<String, String> properties = requestControllerService.getProperties();
    +                    AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, componentType, bundle, properties, parameterContext);
                     },
                     () -> serviceFacade.verifyCreateControllerService(requestControllerService),
                     controllerServiceEntity -> {
    
  • nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java+4 5 modified
    @@ -39,8 +39,8 @@
     import jakarta.ws.rs.core.MediaType;
     import jakarta.ws.rs.core.Response;
     import org.apache.commons.lang3.StringUtils;
    +import org.apache.nifi.authorization.AuthorizeComponentReference;
     import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
    -import org.apache.nifi.authorization.AuthorizeParameterReference;
     import org.apache.nifi.authorization.Authorizer;
     import org.apache.nifi.authorization.ComponentAuthorizable;
     import org.apache.nifi.authorization.RequestAction;
    @@ -946,10 +946,9 @@ public Response updateProcessor(
                         authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, user);
     
                         final ProcessorConfigDTO config = requestProcessorDTO.getConfig();
    -                    if (config != null) {
    -                        AuthorizeControllerServiceReference.authorizeControllerServiceReferences(config.getProperties(), authorizable, authorizer, lookup);
    -                        AuthorizeParameterReference.authorizeParameterReferences(config.getProperties(), authorizer, authorizable.getParameterContext(), user);
    -                    }
    +                    final Map<String, String> properties = config == null ? Collections.emptyMap() : config.getProperties();
    +                    final Authorizable parameterContext = authorizable.getParameterContext();
    +                    AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, authorizable, properties, parameterContext);
                     },
                     () -> serviceFacade.verifyUpdateProcessor(requestProcessorDTO),
                     (revision, processorEntity) -> {
    
  • nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java+5 2 modified
    @@ -39,6 +39,7 @@
     import jakarta.ws.rs.core.MediaType;
     import jakarta.ws.rs.core.Response;
     import org.apache.commons.lang3.StringUtils;
    +import org.apache.nifi.authorization.AuthorizeComponentReference;
     import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
     import org.apache.nifi.authorization.Authorizer;
     import org.apache.nifi.authorization.ComponentAuthorizable;
    @@ -84,6 +85,7 @@
     import java.time.Instant;
     import java.util.Collections;
     import java.util.List;
    +import java.util.Map;
     import java.util.Set;
     import java.util.concurrent.TimeUnit;
     import java.util.function.Consumer;
    @@ -536,8 +538,9 @@ public Response updateReportingTask(
                         final ComponentAuthorizable authorizable = lookup.getReportingTask(id);
                         authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
     
    -                    // authorize any referenced services
    -                    AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestReportingTaskDTO.getProperties(), authorizable, authorizer, lookup);
    +                    final Authorizable parameterContext = authorizable.getParameterContext();
    +                    final Map<String, String> componentProperties = requestReportingTaskDTO.getProperties();
    +                    AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, authorizable, componentProperties, parameterContext);
                     },
                     () -> serviceFacade.verifyUpdateReportingTask(requestReportingTaskDTO),
                     (revision, reportingTaskEntity) -> {
    
  • nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebConfigurationContext.java+11 19 modified
    @@ -31,7 +31,7 @@
     import org.apache.nifi.action.component.details.FlowChangeExtensionDetails;
     import org.apache.nifi.action.details.FlowChangeConfigureDetails;
     import org.apache.nifi.admin.service.AuditService;
    -import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
    +import org.apache.nifi.authorization.AuthorizeComponentReference;
     import org.apache.nifi.authorization.AuthorizeParameterReference;
     import org.apache.nifi.authorization.Authorizer;
     import org.apache.nifi.authorization.ComponentAuthorizable;
    @@ -48,6 +48,7 @@
     import org.apache.nifi.controller.ControllerService;
     import org.apache.nifi.controller.reporting.ReportingTaskProvider;
     import org.apache.nifi.controller.service.ControllerServiceProvider;
    +import org.apache.nifi.parameter.ParameterContext;
     import org.apache.nifi.util.NiFiProperties;
     import org.apache.nifi.web.api.ApplicationResource.ReplicationTarget;
     import org.apache.nifi.web.api.dto.AllowableValueDTO;
    @@ -424,12 +425,9 @@ public ComponentDetails updateComponent(final NiFiWebConfigurationRequestContext
                     final ComponentAuthorizable authorizable = lookup.getProcessor(id);
                     authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
     
    -                // authorize any referenced service
    -                AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup);
    -
    -                // authorize any parameter references
    -                AuthorizeParameterReference.authorizeParameterReferences(properties, authorizer, authorizable.getParameterContext(), user);
    -                AuthorizeParameterReference.authorizeParameterReferences(annotationData, authorizer, authorizable.getParameterContext(), user);
    +                final ParameterContext parameterContext = authorizable.getParameterContext();
    +                AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, authorizable, properties, parameterContext);
    +                AuthorizeParameterReference.authorizeParameterReferences(annotationData, authorizer, parameterContext, user);
                 });
     
                 ProcessorEntity entity;
    @@ -609,12 +607,9 @@ public ComponentDetails updateComponent(final NiFiWebConfigurationRequestContext
                     final ComponentAuthorizable authorizable = lookup.getControllerService(id);
                     authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
     
    -                // authorize any referenced service
    -                AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup);
    -
    -                // authorize any parameter references
    -                AuthorizeParameterReference.authorizeParameterReferences(properties, authorizer, authorizable.getParameterContext(), user);
    -                AuthorizeParameterReference.authorizeParameterReferences(annotationData, authorizer, authorizable.getParameterContext(), user);
    +                final ParameterContext parameterContext = authorizable.getParameterContext();
    +                AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, authorizable, properties, parameterContext);
    +                AuthorizeParameterReference.authorizeParameterReferences(annotationData, authorizer, parameterContext, user);
                 });
     
                 ControllerServiceEntity entity;
    @@ -757,8 +752,7 @@ public ComponentDetails updateComponent(final NiFiWebConfigurationRequestContext
                     final ComponentAuthorizable authorizable = lookup.getReportingTask(id);
                     authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
     
    -                // authorize any referenced service
    -                AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup);
    +                AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, authorizable, properties, null);
                 });
     
                 ReportingTaskEntity entity;
    @@ -902,8 +896,7 @@ public ComponentDetails updateComponent(final NiFiWebConfigurationRequestContext
                     final ComponentAuthorizable authorizable = lookup.getParameterProvider(id);
                     authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
     
    -                // authorize any referenced service
    -                AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup);
    +                AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, authorizable, properties, null);
                 });
     
                 ParameterProviderEntity entity;
    @@ -1046,8 +1039,7 @@ public ComponentDetails updateComponent(final NiFiWebConfigurationRequestContext
                     final ComponentAuthorizable authorizable = lookup.getParameterProvider(id);
                     authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
     
    -                // authorize any referenced service
    -                AuthorizeControllerServiceReference.authorizeControllerServiceReferences(properties, authorizable, authorizer, lookup);
    +                AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, lookup, authorizable, properties, null);
                 });
     
                 FlowRegistryClientEntity entity;
    
  • nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/authorization/AuthorizeComponentReferenceTest.java+82 0 added
    @@ -0,0 +1,82 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +package org.apache.nifi.authorization;
    +
    +import org.apache.nifi.authorization.resource.Authorizable;
    +import org.apache.nifi.web.api.dto.BundleDTO;
    +import org.junit.jupiter.api.Test;
    +import org.junit.jupiter.api.extension.ExtendWith;
    +import org.mockito.Mock;
    +import org.mockito.junit.jupiter.MockitoExtension;
    +
    +import java.util.Map;
    +import java.util.Set;
    +
    +import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.ArgumentMatchers.eq;
    +import static org.mockito.Mockito.never;
    +import static org.mockito.Mockito.verify;
    +import static org.mockito.Mockito.when;
    +
    +@ExtendWith(MockitoExtension.class)
    +class AuthorizeComponentReferenceTest {
    +    private static final String COMPONENT_TYPE = ComponentAuthorizable.class.getName();
    +
    +    private static final BundleDTO COMPONENT_BUNDLE = new BundleDTO();
    +
    +    @Mock
    +    private Authorizer authorizer;
    +
    +    @Mock
    +    private AuthorizableLookup authorizableLookup;
    +
    +    @Mock
    +    private ComponentAuthorizable componentAuthorizable;
    +
    +    @Mock
    +    private Authorizable restrictedAuthorizable;
    +
    +    @Mock
    +    private Authorizable parameterContext;
    +
    +    @Test
    +    void testAuthorizeComponentConfigurationComponentType() {
    +        when(authorizableLookup.getConfigurableComponent(eq(COMPONENT_TYPE), eq(COMPONENT_BUNDLE))).thenReturn(componentAuthorizable);
    +
    +        AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, authorizableLookup, COMPONENT_TYPE, COMPONENT_BUNDLE, Map.of(), parameterContext);
    +
    +        verify(componentAuthorizable).cleanUpResources();
    +    }
    +
    +    @Test
    +    void testAuthorizeComponentConfigurationComponentAuthorizable() {
    +        AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, authorizableLookup, componentAuthorizable, Map.of(), parameterContext);
    +
    +        verify(componentAuthorizable, never()).cleanUpResources();
    +    }
    +
    +    @Test
    +    void testAuthorizeComponentConfigurationRestricted() {
    +        when(componentAuthorizable.isRestricted()).thenReturn(true);
    +        when(componentAuthorizable.getRestrictedAuthorizables()).thenReturn(Set.of(restrictedAuthorizable));
    +
    +        AuthorizeComponentReference.authorizeComponentConfiguration(authorizer, authorizableLookup, componentAuthorizable, null, null);
    +
    +        verify(restrictedAuthorizable).authorize(eq(authorizer), eq(RequestAction.WRITE), any());
    +        verify(componentAuthorizable, never()).cleanUpResources();
    +    }
    +}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.