[ 
https://issues.apache.org/jira/browse/NIFI-15692?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18067770#comment-18067770
 ] 

Ivan Majsinger edited comment on NIFI-15692 at 3/23/26 5:40 PM:
----------------------------------------------------------------

h3. RECOMMENDED RESPONSE TO DAVID

Hi David,

Thank you for reviewing this. After working with the network team, we 
identified the actual root cause.

*This is NOT a reverse proxy configuration issue - it's an invalid HTTP header.*

The {{getRawFile()}} method sends {{Accept: **}} \{*}which is *invalid per RFC 
7231 (HTTP/1.1 Semantics){*}. The correct header is {{{}Accept: *{*}/*{*}{}}}.

When GitLab is behind a WAF (Web Application Firewall) that validates HTTP 
headers - a security best practice in enterprise environments - the WAF 
correctly rejects this malformed header with 403 Forbidden.

*Why other NiFi operations work:*
 * {{{}createContent(){}}}, {{{}deleteFile(){}}}, {{getFile()}} → send correct 
{{Accept: *{*}/*{*}}} ✓
 * Only {{getRawFile()}} → sends invalid {{Accept: *}} ✗

This is why verification passes but flow registration fails.

*Why the fix won't be "easily lost":*

The fix improves compatibility with:
 * Enterprise environments with WAF
 * Security-hardened GitLab deployments
 * Any environment with HTTP header validation (increasingly common)

This is not a niche edge case - it affects any production environment with 
proper security controls.

*Why the fix is correct:*

Using {{getFile()}} + Base64 decode:
 # Sends correct {{Accept: */*}} header (RFC 7231 compliant)
 # Uses standard GitLab API endpoint
 # Returns identical content
 # No performance impact
 # Works with both security-hardened and standard environments

*Reproducible test case:*
{code:bash}
# Invalid header (what NiFi currently sends):
curl -H "Accept: *" https://any-gitlab/api/v4/.../raw
# Blocked by WAF with strict HTTP validation

# Valid header (what the fix sends):
curl -H "Accept: */*" https://any-gitlab/api/v4/.../raw
# Works everywhere
{code}
*Alternative:*

If you prefer, the issue could be fixed in gitlab4j-api library itself. 
However, that would:
 # Take longer to reach NiFi users
 # Require NiFi to upgrade the dependency
 # Leave current NiFi versions broken in security-hardened environments

The proposed fix is simple, safe, and provides immediate value.

*Would you like me to provide a pull request with the fix?*

Best regards,  
Ivan
----
P.S. The error message "Apache Server at ... Port 80" is misleading - it's the 
WAF's error response template, not an indication of a redirect. The WAF blocks 
the request before it reaches GitLab.


was (Author: JIRAUSER312697):
h3. RECOMMENDED RESPONSE TO DAVID

Hi David,

Thank you for reviewing this. After working with the network team, we 
identified the actual root cause.

*This is NOT a reverse proxy configuration issue - it's an invalid HTTP header.*

The \{{getRawFile()}} method sends \{{Accept: *}} which is *invalid per RFC 
7231 (HTTP/1.1 Semantics)*. The correct header is \{{Accept: */*}}.

When GitLab is behind a WAF (Web Application Firewall) that validates HTTP 
headers - a security best practice in enterprise environments - the WAF 
correctly rejects this malformed header with 403 Forbidden.

*Why other NiFi operations work:*
* \{{createContent()}}, \{{deleteFile()}}, \{{getFile()}} → send correct 
\{{Accept: */*}} ✓
* Only \{{getRawFile()}} → sends invalid \{{Accept: *}} ✗

This is why verification passes but flow registration fails.

*Why the fix won't be "easily lost":*

The fix improves compatibility with:
* Enterprise environments with WAF
* Security-hardened GitLab deployments
* Any environment with HTTP header validation (increasingly common)

This is not a niche edge case - it affects any production environment with 
proper security controls.

*Why the fix is correct:*

Using \{{getFile()}} + Base64 decode:
# Sends correct \{{Accept: */*}} header (RFC 7231 compliant)
# Uses standard GitLab API endpoint
# Returns identical content
# No performance impact
# Works with both security-hardened and standard environments

*Reproducible test case:*

{code:bash}
# Invalid header (what NiFi currently sends):
curl -H "Accept: *" https://any-gitlab/api/v4/.../raw
# Blocked by WAF with strict HTTP validation

# Valid header (what the fix sends):
curl -H "Accept: */*" https://any-gitlab/api/v4/.../raw
# Works everywhere
{code}

*Alternative:*

If you prefer, the issue could be fixed in gitlab4j-api library itself. 
However, that would:
# Take longer to reach NiFi users
# Require NiFi to upgrade the dependency
# Leave current NiFi versions broken in security-hardened environments

The proposed fix is simple, safe, and provides immediate value.

*Would you like me to provide a pull request with the fix?*

Best regards,  
Ivan

----

P.S. The error message "Apache Server at ... Port 80" is misleading - it's the 
WAF's error response template, not an indication of a redirect. The WAF blocks 
the request before it reaches GitLab.

> GitLabRepositoryClient.deleteContent() fails with 403 when GitLab is behind 
> reverse proxy due to getRawFile() usage
> -------------------------------------------------------------------------------------------------------------------
>
>                 Key: NIFI-15692
>                 URL: https://issues.apache.org/jira/browse/NIFI-15692
>             Project: Apache NiFi
>          Issue Type: Bug
>          Components: Extensions
>    Affects Versions: 2.7.2
>            Reporter: Ivan Majsinger
>            Assignee: Pierre Villard
>            Priority: Major
>          Time Spent: 50m
>  Remaining Estimate: 0h
>
> h3. Problem
> GitLabFlowRegistryClient fails to register flow snapshots when GitLab is 
> behind an Apache reverse proxy. The verification passes all checks, but 
> "Start Version Control" fails with 403 Forbidden.
> h3. Root Cause
> The \{{deleteContent()}} method in \{{GitLabRepositoryClient.java}} uses 
> \{{getRawFile()}} which hits the 
> \{{/api/v4/projects/.../repository/files/.../raw}} endpoint. This endpoint is 
> handled differently by some reverse proxies, causing a redirect to HTTP port 
> 80 where authentication fails.
> {code:java}
> // Current implementation (line ~266)
> public InputStream deleteContent(...) {
>     return execute(() -> {
>         final InputStream content = 
> gitLab.getRepositoryFileApi().getRawFile(...); // FAILS HERE
>         gitLab.getRepositoryFileApi().deleteFile(...);
>         return content;
>     });
> }
> {code}
> h3. Error
> {code}
> org.gitlab4j.api.GitLabApiException: 
> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
> <html><head><title>403 Forbidden</title></head><body>
> <h1>Forbidden</h1>
> <p>You don't have permission to access this resource.</p>
> <address>Apache Server at [hostname] Port 80</address>
> </body></html>
>     at 
> org.gitlab4j.api.RepositoryFileApi.getRawFile(RepositoryFileApi.java:422)
>     at org.apache.nifi.gitlab.GitLabRepositoryClient.lambda$deleteContent$8
> {code}
> h3. Proposed Fix
> Use \{{getFile()}} instead of \{{getRawFile()}}. The \{{getFile()}} method 
> uses the standard \{{/api/v4/projects/.../repository/files/...}} endpoint 
> (without \{{/raw}}) which returns Base64-encoded content and works correctly 
> behind reverse proxies.
> {code:java}
> // Proposed fix
> public InputStream deleteContent(...) {
>     return execute(() -> {
>         RepositoryFile file = 
> gitLab.getRepositoryFileApi().getFile(projectPath, resolvedPath, branch);
>         byte[] content = Base64.getDecoder().decode(file.getContent());
>         gitLab.getRepositoryFileApi().deleteFile(...);
>         return new ByteArrayInputStream(content);
>     });
> }
> {code}
> h3. Related
> - gitlab4j-api issue: https://github.com/gmessner/gitlab4j-api/issues/282
> h3. Environment
> - NiFi 2.7.0
> - GitLab behind Apache reverse proxy



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to