factor out dangerous request checking logic
This commit is contained in:
parent
2d8bb2c5da
commit
41167b128f
|
@ -20,6 +20,12 @@ defmodule Egalaxyd.FileRetrieval do
|
|||
"""
|
||||
defp normalized_path(path) do
|
||||
# Make sure the path is an absolute path to a file in the current working directory
|
||||
|
||||
if request_references_forbidden_secrets?(path) || request_attempts_to_escape?(path) do
|
||||
Logger.notice("Client sent dangerous query")
|
||||
{:error, :bad_request}
|
||||
end
|
||||
|
||||
# TODO: Adjust file base path via config option
|
||||
prefixed_path = if String.starts_with?(path, File.cwd!), do: path, else: (File.cwd! <> path)
|
||||
|
||||
|
@ -35,4 +41,18 @@ defmodule Egalaxyd.FileRetrieval do
|
|||
{:ok, prefixed_path}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@doc "Check request to ensure secrets are not requests, if the setting is enabled"
|
||||
defp request_references_forbidden_secrets?(path) do
|
||||
keyfile = ConfigSentinel.getopt(:keyfile)
|
||||
certfile = ConfigSentinel.getopt(:certfile)
|
||||
(not ConfigSentinel.getopt(:allow_secrets)) && ((String.match?(path, ~r/#{keyfile}/)) || (String.match?(path, ~r/#{certfile}/)))
|
||||
end
|
||||
|
||||
@doc "Check request to ensure directory traversal is not attempted, if the setting is enabled"
|
||||
defp request_attempts_to_escape?(path) do
|
||||
(not ConfigSentinel.getopt(:allow_updir)) && String.match?(path, ~r/\.\./)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -54,14 +54,6 @@ defmodule Geminex.RequestParser do
|
|||
req.scheme != "gemini" || (req.port != 1965 && req.port != nil) ->
|
||||
# TODO: use the config option here
|
||||
response("53 protocol refused\r\n") # this is a gemini server!
|
||||
request_references_forbidden_secrets?(req.path) ->
|
||||
# Settings disallow requesting secrets and the path seems to reference them
|
||||
Logger.notice("Client requested forbidden secret")
|
||||
response("59 bad request\r\n")
|
||||
request_attempts_to_escape?(req.path) ->
|
||||
# Settings disallow directory backtracking and the request path seems to attempt this
|
||||
Logger.notice("Client requested directory backtrack")
|
||||
response("59 bad request\r\n")
|
||||
true ->
|
||||
# todo: mime typing
|
||||
case retrieve_file_contents(req.path) do
|
||||
|
@ -93,23 +85,12 @@ defmodule Geminex.RequestParser do
|
|||
Logger.info("Response: #{resp}")
|
||||
{:reply, resp, []}
|
||||
end
|
||||
|
||||
@doc "Check request to ensure secrets are not requests, if the setting is enabled"
|
||||
defp request_references_forbidden_secrets?(path) do
|
||||
keyfile = ConfigSentinel.getopt(:keyfile)
|
||||
certfile = ConfigSentinel.getopt(:certfile)
|
||||
(not ConfigSentinel.getopt(:allow_secrets)) && ((String.match?(path, ~r/#{keyfile}/)) || (String.match?(path, ~r/#{certfile}/)))
|
||||
end
|
||||
|
||||
@doc "Check request to ensure directory traversal is not attempted, if the setting is enabled"
|
||||
defp request_attempts_to_escape?(path) do
|
||||
(not ConfigSentinel.getopt(:allow_updir)) && String.match?(path, ~r/\.\./)
|
||||
end
|
||||
|
||||
defp retrieve_file_contents(path) do
|
||||
case Egalaxyd.FileRetrieval.retrieve_file_contents(path) do
|
||||
{:error, :enoent} -> {:error, "51 not found\r\n"}
|
||||
{:error, :enametoolong} -> {:error, "59 bad request: Request too long\r\n"}
|
||||
{:error, :bad_request} -> {:error, "59 bad request"}
|
||||
{:error, other_error} ->
|
||||
Logger.error other_error
|
||||
{:error, "50 internal server error\r\n"}
|
||||
|
|
Loading…
Reference in New Issue