Skip to content

NIFI-15967 Adjust Proxy Header Validation for Replicated Requests#11273

Merged
pvillard31 merged 3 commits into
apache:mainfrom
exceptionfactory:NIFI-15967
May 22, 2026
Merged

NIFI-15967 Adjust Proxy Header Validation for Replicated Requests#11273
pvillard31 merged 3 commits into
apache:mainfrom
exceptionfactory:NIFI-15967

Conversation

@exceptionfactory
Copy link
Copy Markdown
Contributor

Summary

NIFI-15967 Adjusts the implementation of proxy header validation to support authenticated and replicated requests between NiFi cluster nodes.

Proxy host header validation applies only when the application is enabled for HTTPS, so the implementation checks for the presence of X509 Peer Certificates in the TLS Session. This occurs after a successful TLS handshake, and the presence of the client certificates in the TLS Session indicates that mutual TLS authentication completed as expected. To differentiate requests, the implementation looks for the presence of the custom request-replicated header, which the application sets when constructing forwarded requests. Without both of these qualifiers, standard proxy host header validation occurs, checking the values configured in the nifi.web.proxy.host property, as implemented in NIFI-15953.

Tracking

Please complete the following tracking steps prior to pull request creation.

Issue Tracking

Pull Request Tracking

  • Pull Request title starts with Apache NiFi Jira issue number, such as NIFI-00000
  • Pull Request commit message starts with Apache NiFi Jira issue number, as such NIFI-00000
  • Pull request contains commits signed with a registered key indicating Verified status

Pull Request Formatting

  • Pull Request based on current revision of the main branch
  • Pull Request refers to a feature branch with one commit containing changes

Verification

Please indicate the verification steps performed prior to pull request creation.

Build

  • Build completed using ./mvnw clean install -P contrib-check
    • JDK 21
    • JDK 25

Licensing

  • New dependencies are compatible with the Apache License 2.0 according to the License Policy
  • New dependencies are documented in applicable LICENSE and NOTICE files

Documentation

  • Documentation formatting appears as expected in rendered files

// Requests not authenticated with Client Certificates require header validation
if (peerCertificate == null) {
processProxyHostHeaders(request);
} else {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this branch also require the peer certificate to match a known cluster node identity (or come from the cluster-only trust store), so that a non-node user holding a valid client certificate cannot bypass proxy host validation simply by adding the request-replicated header?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered that additional approach, but it places additional constraints on information that is not necessarily available. The current approach places inherent security constraints with mTLS, and also fits within current configuration boundaries.

public class ProxyHeaderValidatorCustomizer implements HttpConfiguration.Customizer {
private static final String MISDIRECTED_REQUEST_REASON = "Invalid Proxy Host Requested";

private static final String REQUEST_REPLICATED_HEADER = "request-replicated";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we reference RequestReplicationHeader.REQUEST_REPLICATED.getHeader() (possibly after moving that enum, or just this single constant, into nifi-web-servlet-shared next to ProxyHeader) so the header value is defined in exactly one place?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I looked at options and ended up creating a new ReplicationHeader with just this new enum and put it in nifi-framework-core, as that appeared to be a better location given the cluster-focused nature of this header.


private static final String HOST_HEADER = "Host";

private static final String REQUEST_REPLICATED_HEADER = "request-replicated";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question on the test side: can REQUEST_REPLICATED_HEADER here share the canonical constant rather than redefining the literal?

final ConnectionMetaData connectionMetaData = request.getConnectionMetaData();
final Connection connection = connectionMetaData.getConnection();
final EndPoint endPoint = connection.getEndPoint();
final EndPoint.SslSessionData sslSessionData = endPoint.getSslSessionData();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any code path under a successful isSecure() where connection.getEndPoint() or endPoint.getSslSessionData() could be null (for example during a protocol upgrade), and if so should we guard the chain rather than risk an NullPointerException inside the customizer?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, but no, at this point in the Connection handling, the SslSessionData can never be null.

- Removed RequestReplicationHeader.REQUEST_REPLICATED in favor of new enum
Copy link
Copy Markdown
Contributor

@pvillard31 pvillard31 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates @exceptionfactory - there are some test failures to address

@exceptionfactory
Copy link
Copy Markdown
Contributor Author

Thanks for the updates @exceptionfactory - there are some test failures to address

Thanks @pvillard31, I pushed an update to adjust the filtering method in ReplicationHeaderUtils to maintain current behavior.

Copy link
Copy Markdown
Contributor

@pvillard31 pvillard31 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, latest LGTM and can be merged after successful checks.

@pvillard31 pvillard31 merged commit e6baf38 into apache:main May 22, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants