[GH-ISSUE #487] Android app not sending username/password for attachments #372

Closed
opened 2026-05-07 00:23:35 +02:00 by BreizhHardware · 6 comments

Originally created by @jakobdalsgaard on GitHub (Nov 11, 2022).
Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/487

When sending a message with an attachment, picture for example, and this attachment is served from the ntfy server itself, then the request from the app to fetch the image is not sent with the credentials specified in the app for said host.

I run my own ntfy server behind nginx, with TLS and basic authentication; but I need to disable auth for the '/file/' path in the nginx for the android app to be able to fetch the attached image -- I would prefer preventing serving this content to the world by requiring the same password for these files as for any other access to the ntfy server.

I've tried to see if anyone else has seen this behaviour, but I could not find any issues submitted to github.

My ntfy server install is the amd64 debian package version 1.28.0 and the Android app reports 1.14.0 (play)

Originally created by @jakobdalsgaard on GitHub (Nov 11, 2022). Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/487 When sending a message with an attachment, picture for example, and this attachment is served from the ntfy server itself, then the request from the app to fetch the image is not sent with the credentials specified in the app for said host. I run my own ntfy server behind nginx, with TLS and basic authentication; but I need to disable auth for the '/file/' path in the nginx for the android app to be able to fetch the attached image -- I would prefer preventing serving this content to the world by requiring the same password for these files as for any other access to the ntfy server. I've tried to see if anyone else has seen this behaviour, but I could not find any issues submitted to github. My ntfy server install is the amd64 debian package version 1.28.0 and the Android app reports 1.14.0 (play)
BreizhHardware 2026-05-07 00:23:35 +02:00
  • closed this issue
  • added the
    question
    label
Author
Owner

@binwiederhier commented on GitHub (Nov 11, 2022):

The filename of the attachment is the message ID, which is 12 random characters (a-zA-Z0-9), which is (26+26+10)^12 = 62^12 possible file IDs. So unless you know the message ID (which you don't, because that implies that you know the message), you cannot guess the attachment URL. And that's why the username and password is not required for attachments.

I hope that explains it.

<!-- gh-comment-id:1311652518 --> @binwiederhier commented on GitHub (Nov 11, 2022): The filename of the attachment is the message ID, which is 12 random characters (a-zA-Z0-9), which is (26+26+10)^12 = 62^12 possible file IDs. So unless you know the message ID (which you don't, because that implies that you know the message), you cannot guess the attachment URL. And that's why the username and password is not required for attachments. I hope that explains it.
Author
Owner

@jakobdalsgaard commented on GitHub (Nov 11, 2022):

Unless you intercept a message, say an email -- then you don't have to guess - and you don't need username/password to get the image. A few comments:

  1. this is security through obscurity
  2. it's counterintuitive that I can configure the Android app to use username/password for an ntfy server, and then it does not apply said username/password on certain requests to said server.

I do understand, from your explanation, that is works as designed, and I'm thus questioning the design :-)

<!-- gh-comment-id:1311722095 --> @jakobdalsgaard commented on GitHub (Nov 11, 2022): Unless you intercept a message, say an email -- then you don't have to guess - and you don't need username/password to get the image. A few comments: 1) this is security through obscurity 2) it's counterintuitive that I can configure the Android app to use username/password for an ntfy server, and then it does not apply said username/password on certain requests to said server. I do understand, from your explanation, that is works as designed, and I'm thus questioning the design :-)
Author
Owner

@Ali2731 commented on GitHub (Nov 11, 2022):

thanks

<!-- gh-comment-id:1311875131 --> @Ali2731 commented on GitHub (Nov 11, 2022): thanks
Author
Owner

@binwiederhier commented on GitHub (Nov 12, 2022):

Thank you for your feedback. I appreciate you taking the time to investigate and comment.

However, I do not agree with your assessment. A secret URL with a long randomly generated identifier is not security through obscurity. In fact, it is common practice in the industry: Google Photos, GitHub, Discord, Slack, ... Everyone uses this method to serve user content such as images and other media. Here's an example from Google Photos from my personal photo collection. It's not a "shared link".

Security through obscurity implies that you can access a resource or component without knowing a secret, because you've discovered a way around it. The file ID is a secret (as mentioned above), and you cannot access the file without it.

<!-- gh-comment-id:1312477733 --> @binwiederhier commented on GitHub (Nov 12, 2022): Thank you for your feedback. I appreciate you taking the time to investigate and comment. However, I do not agree with your assessment. A secret URL with a long randomly generated identifier is not security through obscurity. In fact, it is common practice in the industry: Google Photos, GitHub, Discord, Slack, ... Everyone uses this method to serve user content such as images and other media. Here's an [example from Google Photos](https://lh3.googleusercontent.com/154E8q-vNqBTeKieWMy2sl__QATxg3r3aKPgSF2icGMs1Mk8eyMUvhBZaHsBibKimlYSNG61_Hq-D4-VuP7eLjODDFbexZtHIH04vhTRX626c7mkgDCtdr4TwOAIaLFhB52NMymT9RxVaK919L5pdAWKx4ptzRAyhitOJcZxlHs-3mjnISLO2eQCAT9gtPt_UywhNUL0sDeToWUcCmgT7BbshUqBYSJ935YR9RSHkitnLwW7zBVjbd3ad-HC56dpMqai-f9rL45qyPn1ZEdVCL6mPZOc-SY0O-KjA23WWCxI4bidIwV1Yxcj39_AYm6ccC2FAju9Z9lbST3ObF2q7CPaQRDQ8vOlsclhgS36gfL94Vt7NnpO5IvbNnpJlPW6_KF64O5tRSHTxg2ffh2QNPPkmNyK4VojuWtNJZypjyGWf7U1p-zlDvjCn4L13Q1sHeEbRL9VYQsN4-IQfzama4foM2w-epSfYA0cucKenn1NlNjebICHoT2dz_MylD5CbHBKhJmVvPfyMcf3rD9JGGFENWYh_SuaVwZcTnEF_7MGR9MWl2VVmmRRXmIwIGhFE8SWpdPNwiuXLznLWBG1jhGTeG94YCCr9BJjbLPYn2sVir7sSTsgAzhZGSz6COTtPnQafhGTMubP-Elnd1mFvf7U4a_ZgpkFFjv4BcXx_Wq4TNQRAzLO2dWoi6Hv-IDR5Vp10kStcYkYdnovD_YGURSsNtBEJ_vh8k9NPi90xYDL3DmVSOx1VfFgcjcAWEkWvaBmLKxpa7YANo0OorW3KL-o_m4De-bxiQsY2sjyiVeGnfTRC8vqZe9jboxka3rs9GWTIOViVWdOuxHILFSDbPQ36VDcQifL9JSP2ULDercq7vf2vYVC4VbFglEqGNf3SSNUrN31q6ULTI1xtcEudFs4MDqTd7kUBBLpjGLog3H9TU2E6cF3pyGS4szFOVarcoryv-vQrXacu8iAUKa6WQ=w163-h200-no?authuser=0) from my personal photo collection. It's not a "shared link". Security through obscurity implies that you can access a resource or component without knowing a secret, because you've discovered a way around it. The file ID is a secret (as mentioned above), and you cannot access the file without it.
Author
Owner

@binwiederhier commented on GitHub (Nov 13, 2022):

Closing this for now. But I'm happy to keep discussing.

<!-- gh-comment-id:1312710075 --> @binwiederhier commented on GitHub (Nov 13, 2022): Closing this for now. But I'm happy to keep discussing.
Author
Owner

@jakobdalsgaard commented on GitHub (Nov 13, 2022):

:-) you have some fair points; and this is definitely something that you have thought of - I'm good with that; though I do not fully agree with you. We don't have to.

<!-- gh-comment-id:1312711224 --> @jakobdalsgaard commented on GitHub (Nov 13, 2022): :-) you have some fair points; and this is definitely something that you have thought of - I'm good with that; though I do not fully agree with you. We don't have to.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/ntfy#372
No description provided.