"Numeric methods" through Cloudflare Proxy?

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
1 Like