Why?
I read the RFC7230 “Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing” and RFC7231 “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content” at last week end.
And I found that HTTP has great flexibility about “Reqeust Method”.
Definition of Request Method
The RFC7231 says:
HTTP was originally designed to be usable as an interface to distributed object systems. The request method was envisioned as applying semantics to a target resource in much the same way as invoking a defined method on an identified object would apply semantics. The method token is case -sensitive because it might be used as a gateway to object-based systems with case-sensitive method names.
That hears so good.
For example, We can rewrite POST /tags/the_category
as CreateTag /the_category
.
What characters can be used?
The “method” is defined as (in RFC7231):
method = token
And the “token” is defined as (in RFC7230):
token = 1*tchar
tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
/ "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
/ DIGIT / ALPHA
; any VCHAR, except delimiters
*
(Single asterisk) method is reserved as wildcard (Any Method) for Access-Control-Allow-Methods
, but otherwise methods are allowed for any usecases.
For example, We can rewrite POST /posts/12345/vote
as + /posts/12345
.
In Cloudflare’s Proxy
Oh no. Cloudflare ruined all our expectations.
Allowed characters (returned 301 Moved Permanently
):
- All upper case ALPHA
[A-Z]
-
for c in $(echo ABCDEFGHIJKLMNOPQRSTUVWXYZ | fold -w1); do curl -s -X "$c" cloudflare.com --write-out "%{http_code}: $c \n" --output /dev/null done
-
- hyphen
-
- underscore
_
Sadly, All other defined characters are not allowed.
Not allowed characters (returned 400 Bad Request
):
- All lower case ALPHA
[a-z]
-
for c in $(echo abcdefghijklmnopqrstuvwxyz | fold -w1); do curl -s -X "$c" cloudflare.com --write-out "%{http_code}: $c \n" --output /dev/null done
-
- All DIGITS
[0-9]
-
for c in $(echo 0123456789 | fold -w1); do curl -s -X "$c" cloudflare.com --write-out "%{http_code}: $c \n" --output /dev/null done
-
- exclam
!
- hash
#
- dollar
$
- percent
%
- amp
&
- plus
+
- dot
.
- carret
^
- backtick
`
- pipe
|
- childa
~
- single quote
'
- asterisk
*
What application triggers that problem?
I encoutered the problem when I was creating an application for next april fool.
HTTP ALU.
That is a 𝒓𝒆𝒗𝒐𝒍𝒖𝒕𝒊𝒐𝒏𝒂𝒓𝒚 mining-resistant cloud computing resource.
Each CPU instruction are executed by each HTTP requests.
The instruction register
passed by the “Request Method” and some registers (a
, d
, *a
) paassed by Header. (That are encoded as binary that like 00011011
.)
And we can got a output register
in response and condition jump flag
(j
) in Header.
> 0001011111111000 /nandgame HTTP/1.1
> Host: alu.yr32.net
> User-Agent: curl/8.5.0
> Accept: */*
> X-a: 0
> X-d: 0
> X-*a: 0
>
< HTTP/1.1 200 OK
< content-type: text/plain; charset=utf-8
< x-j: false
< content-length: 16
< vary: origin, access-control-request-method, access-control-request-headers
< access-control-allow-origin: *
< date: Tue, 02 Apr 2024 21:27:01 GMT
<
1111111111111111
* Closing connection
Actual behaviour through Cloudflare Proxy
* Host alu.yr32.net:80 was resolved.
* IPv6: 2606:4700:3036::ac43:d107, 2606:4700:3035::6815:55ba
* IPv4: 104.21.85.186, 172.67.209.7
* Trying [2606:4700:3036::ac43:d107]:80...
* Connected to alu.yr32.net (2606:4700:3036::ac43:d107) port 80
> 0001011111111000 /nandgame HTTP/1.1
> Host: alu.yr32.net
> User-Agent: curl/8.5.0
> Accept: */*
> a: 0
> X-d: 0
> X-*a: 0
>
< HTTP/1.1 400 Bad Request
< Server: cloudflare
< Date: Wed, 03 Apr 2024 09:40:42 GMT
< Content-Type: text/html
< Content-Length: 155
< Connection: close
< CF-RAY: -
<
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>cloudflare</center>
</body>
</html>
* Closing connection