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

Nuclei transparently capitalizes and cannonicalizes headers #5288

Closed
denandz opened this issue Jun 12, 2024 · 6 comments · Fixed by #5445
Closed

Nuclei transparently capitalizes and cannonicalizes headers #5288

denandz opened this issue Jun 12, 2024 · 6 comments · Fixed by #5445
Assignees
Labels
Investigation Something to Investigate Type: Bug Inconsistencies or issues which will cause an issue or problem for users or implementors.
Milestone

Comments

@denandz
Copy link
Contributor

denandz commented Jun 12, 2024

Nuclei version:

v3.8.2

Current Behavior:

Nuclei cannonicalizes headers sent to back end servers. Lower case headers become capitalized and cannonicalized. This prevents nuclei from being able to test bugs which require a specific capitalization of a header name.

Expected Behavior:

User specified headers should remain lowercase

Steps To Reproduce:

nuclei --proxy http://127.0.0.1:8081 -H "some-lowercase-header: foo" -u http://127.0.0.1:8000

And what actually gets sent:

GET /login.jsp HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36
Accept-Encoding: gzip
Connection: close
Content-Type: application/x-www-form-urlencoded
Some-Lowercase-Header: foo

Anything else:

This is due to a know issue in Golang's net/http, where headers are transparently modified as they are read/written from the Headers object (golang/go#37834)

@denandz denandz added the Type: Bug Inconsistencies or issues which will cause an issue or problem for users or implementors. label Jun 12, 2024
@dogancanbakir dogancanbakir self-assigned this Jun 13, 2024
@dogancanbakir dogancanbakir added the Investigation Something to Investigate label Jun 13, 2024
@jimen0
Copy link
Contributor

jimen0 commented Jun 15, 2024

Although it would be nice to have nuclei preserve the header capitalization it must be noted HTTP/1.1 headers are case insensitive. See https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.

Each header field consists of a case-insensitive field name followed
by a colon (":"), optional leading whitespace, the field value, and
optional trailing whitespace.

For HTTP/2 the standard specifies all headers must be converted to lower case. See https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.

Just as in HTTP/1.x, header field names are strings of ASCII
characters that are compared in a case-insensitive fashion.  However,
header field names MUST be converted to lowercase prior to their
encoding in HTTP/2.  A request or response containing uppercase
header field names MUST be treated as malformed ([Section 8.1.2.6](https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.6)).

Then on https://datatracker.ietf.org/doc/html/rfc9113#section-8.2.

Field names MUST be converted to lowercase when constructing an HTTP/2 message.

I wouldn't expect the Go issue be resolved with a change as it is currently compliant with the RFCs. This might need forking Go's http2. See https://github.com/golang/net/blob/9617c6335bca5e4e80949a5b1dbe43273260e8a3/http2/write.go#L331-L349.

@denandz
Copy link
Contributor Author

denandz commented Jun 15, 2024

Sure, the RFC's are clear on what compliant behaviour looks like.

The issue is that non-RFC compliant implementations exist, and Nuclei is currently unable to scan them due to Golang's net/http forcing header canonicalization.

@ehsandeep
Copy link
Member

@denandz for non-RFC compliant you can make use of unsafe: true that uses https://github.com/projectdiscovery/rawhttp instead of net/http

Docs: https://docs.projectdiscovery.io/templates/protocols/http/unsafe-http

example template:

id: basic-raw-example
info:
  name: Test RAW Template
  author: pdteam
  severity: info

http:
  - raw:
      - |+
        GET / HTTP/1.1
        Host: {{Hostname}}
        Origin: {{BaseURL}}
        Connection: close
        User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko)
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
        some-lowercase-header: foo

    unsafe: true
    matchers:
      - type: word
        words:
          - "Test is test matcher text"

Example nuclei with no header canonicalization:

echo https://example.com | nuclei -t test.yaml -debug-req

                     __     _
   ____  __  _______/ /__  (_)
  / __ \/ / / / ___/ / _ \/ /
 / / / / /_/ / /__/ /  __/ /
/_/ /_/\__,_/\___/_/\___/_/   v3.2.8

		projectdiscovery.io

[INF] Current nuclei version: v3.2.8 (latest)
[INF] Current nuclei-templates version: v9.8.9 (latest)
[WRN] Scan results upload to cloud is disabled.
[INF] New templates added in latest release: 1
[INF] Templates loaded for current scan: 1
[WRN] Loading 1 unsigned templates for scan. Use with caution.
[INF] Targets loaded for current scan: 1
[INF] [basic-raw-example] Dumped HTTP request for https://example.com/

GET / HTTP/1.1
Host: example.com
Origin: https://example.com
Connection: close
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
some-lowercase-header: foo

[INF] No results found. Better luck next time!

@dogancanbakir
Copy link
Member

@denandz,
Could you please confirm if what @ehsandeep shared works for you?

@dogancanbakir dogancanbakir added the Status: Abandoned This issue is no longer important to the requestor and no one else has shown an interest in it. label Jul 2, 2024
@dogancanbakir dogancanbakir closed this as not planned Won't fix, can't repro, duplicate, stale Jul 2, 2024
@denandz
Copy link
Contributor Author

denandz commented Jul 2, 2024

Closing an issue as abandoned after a week is pretty brutal there @dogancanbakir

@ehsandeep's suggestion of unsafe: true method works for specific templates, sure. Headers added via -H at runtime; however, get cannonicalized.

@dogancanbakir
Copy link
Member

I don't want to be mean! I close issues quickly to keep things moving, but I'm always happy to reopen them with new information or an update. Thanks for the update!

@dogancanbakir dogancanbakir reopened this Jul 2, 2024
@dogancanbakir dogancanbakir removed the Status: Abandoned This issue is no longer important to the requestor and no one else has shown an interest in it. label Jul 2, 2024
@ehsandeep ehsandeep added this to the nuclei v3.3.1 milestone Jul 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Investigation Something to Investigate Type: Bug Inconsistencies or issues which will cause an issue or problem for users or implementors.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants