Skip to content

serve_file_with_etag() returns HTTP 500 for a nonexistent file #7202

@cfm

Description

@cfm

Description

If serve_file_with_etag() is called on a nonexistent file, then:

  1. werkzeug.utils.send_file() raises a FileNotFoundError...
  2. that serve_file_with_etag() does not catch...
  3. so Flask returns HTTP 500 instead of 404.

Steps to Reproduce

  1. Register as a source and submit something.
  2. Delete that source's directory from /var/lib/securedrop/store.
  3. Log into the SecureDrop Client, since that will try to download all messages and replies.

Expected Behavior

No server-side errors. (The Client's handling of this case will be reported separately.)

Actual Behavior

An error of the form (shown here for a missing -reply.gz):

[Thu Jul 11 23:31:34.450385 2024] [wsgi:error] [pid 729:tid 126273215465216] [remote 127.0.0.1:57984]   File "/var/www/securedrop/journalist_app/api.py", line 188, in download_reply
[Thu Jul 11 23:31:34.450388 2024] [wsgi:error] [pid 729:tid 126273215465216] [remote 127.0.0.1:57984]     return utils.serve_file_with_etag(reply)
[Thu Jul 11 23:31:34.450391 2024] [wsgi:error] [pid 729:tid 126273215465216] [remote 127.0.0.1:57984]   File "/var/www/securedrop/journalist_app/utils.py", line 529, in serve_file_with_etag
[Thu Jul 11 23:31:34.450395 2024] [wsgi:error] [pid 729:tid 126273215465216] [remote 127.0.0.1:57984]     response = send_file(
[Thu Jul 11 23:31:34.450398 2024] [wsgi:error] [pid 729:tid 126273215465216] [remote 127.0.0.1:57984]   File "/opt/venvs/securedrop-app-code/lib/python3.8/site-packages/flask/helpers.py", line 612, in send_file
[Thu Jul 11 23:31:34.450401 2024] [wsgi:error] [pid 729:tid 126273215465216] [remote 127.0.0.1:57984]     return werkzeug.utils.send_file(
[Thu Jul 11 23:31:34.450405 2024] [wsgi:error] [pid 729:tid 126273215465216] [remote 127.0.0.1:57984]   File "/opt/venvs/securedrop-app-code/lib/python3.8/site-packages/werkzeug/utils.py", line 440, in send_file
[Thu Jul 11 23:31:34.450409 2024] [wsgi:error] [pid 729:tid 126273215465216] [remote 127.0.0.1:57984]     stat = os.stat(path)
[Thu Jul 11 23:31:34.450412 2024] [wsgi:error] [pid 729:tid 126273215465216] [remote 127.0.0.1:57984] FileNotFoundError: [Errno 2] No such file or directory: '/var/lib/securedrop/store/Z5MXOPLCO45X45BWRTVKVMETMUIGLM2HFSZNVGHRWX3M7BDG7S4TSRXDJZVAILYLEHN6MD2KXMQ4G2SMUXJBVWX6OJ6MA6IWOCMZLNY=/5-XXX_YYY-reply.gpg'

Comments

Note that the logic of this code-path explicitly skips checking of nonexistent files:

file_path = Storage.get_default().path(db_obj.source.filesystem_id, db_obj.filename)

if not self.verify(absolute):

# verifying a hypothetical path
if not os.path.exists(p):
return True

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions