Opened 16 years ago
Closed 13 years ago
#10147 closed Bug (needsinfo)
Possible wrong check in django.utils._os
Reported by: | Moorthy RS | Owned by: | nobody |
---|---|---|---|
Component: | File uploads/storage | Version: | 1.0 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Design decision needed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I have a model that accepts an Image. And I have specified the upload_dir to /home/myproject/media/upload. And whenever I try to save an image, it gives an error "SuspiciousOperation: Attempted access to /home/myproject/media/upload/image.png denied". Problem appears only when used with Apache, but with the development server, there were no errors. I searched and found that the only suggestion was a possible missing or extra "/" separator. I tried specifying without and with the leading slash, but with no luck.
I debugged around and found this code, responsible for the error:
if not final_path.startswith(base_path) \ or final_path[base_path_len:base_path_len+1] not in ('', sep): raise ValueError('the joined path is located outside of the base path' ' component')
I found base_path was a "/" and final_path was "/home/myproject/media/upload". And hence "final_path.startswith(base_path)" returns true and "final_path[base_path_len:base_path_len+1] returns 'h' which IS not in empty string or sep. So the if condition should fail, but it was succeeding. I changed the code to this snippet (by adding appropriate paranthesis like "if not (condition)") and it started working correctly!
if not (final_path.startswith(base_path) \ or final_path[base_path_len:base_path_len+1] not in ('', sep)): raise ValueError('the joined path is located outside of the base path' ' component')
I am a newbie in python (and as well in django), but I see the lack of paranthesis has got the precedence going wrong, and an unexpected result.
This needs to be corrected, as indicated above.
Change History (5)
follow-up: 2 comment:1 by , 16 years ago
Has patch: | unset |
---|
comment:2 by , 16 years ago
Replying to kmtracey:
Your proposed change is to make that [not (A or B)], which is not the same thing at all. Consider how it would work with some paths other than base_path="/", as compared to the original:
Typo here, the proposed change is to [not (A or not B)], still not the same thing.
comment:3 by , 16 years ago
Triage Stage: | Unreviewed → Design decision needed |
---|
comment:4 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → Bug |
comment:5 by , 13 years ago
Easy pickings: | unset |
---|---|
Resolution: | → needsinfo |
Status: | new → closed |
UI/UX: | unset |
I think we need more info from the original poster to know if it is indeed MEDIA_ROOT = /
causing this, or something else.
rsmoorthy, if you can provide more information (responding to kmtracy's questions) then please feel free to re-open.
Thanks!
No, the problem is not caused by missing parentheses. Consider the comment above that code block, which explains what the check is doing:
So, the code wishes to proceed with the all-clear if: [A and B]
Negating that to check for the error condition is: [not (A and B)], or equivalently [(not A) or (not B)], which is how it is coded.
Your proposed change is to make that [not (A or B)], which is not the same thing at all. Consider how it would work with some paths other than base_path="/", as compared to the original:
The problem you have found has to do with how the code behaves specifically when base_path="/", which is not really a normal case, so I'm not entirely sure what should be done about it. Apparently you have MEDIA_ROOT set to "/"? That means you are saying it is OK for web users to upload files anywhere in the file system. Are you sure you want to be doing that?