package dream
Source file origin_referer_check.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75(* This file is part of Dream, released under the MIT license. See LICENSE.md for details, or visit https://github.com/aantron/dream. Copyright 2021 Anton Bachin *) module Dream = Dream__pure.Inmost let log = Log.sub_log "dream.origin" (* TODO Rename all next_handler to inner_handler. *) let origin_referer_check inner_handler request = match Dream.method_ request with | `GET | `HEAD -> inner_handler request | _ -> let origin = match Dream.header "Origin" request with | Some "null" | None -> Dream.header "Referer" request | Some _ as origin -> origin in match origin with | None -> log.warning (fun log -> log ~request "Origin and Referer headers both missing"); Dream.empty `Bad_Request (* TODO Also recommend Uri to users. *) | Some origin -> match Dream.header "Host" request with | None -> log.warning (fun log -> log ~request "Host header missing"); Dream.empty `Bad_Request | Some host -> let origin_uri = Uri.of_string origin in let schemes_match = match Uri.scheme origin_uri with | Some "http" -> not (Dream.https request) | Some "https" -> Dream.https request | _ -> false in let host_host, host_port = match String.split_on_char ':' host with | [host; port] -> Some host, Some port | _ -> Some host, None in let origin_port = match Uri.port origin_uri with | None -> None | Some port -> Some (string_of_int port) in let hosts_match = Uri.host origin_uri = host_host and ports_match = origin_port = host_port in if schemes_match && hosts_match && ports_match then inner_handler request else begin log.warning (fun log -> log ~request "Origin-Host mismatch: '%s' vs. '%s'" origin host); Dream.empty `Bad_Request end