This is obviously some type of security feature to prevent someone from
climbing up a directory. You have ".." in your string for the file path
somewhere.

What is the value of "dir_name" when the exception is raised? It should be
in the traceback somewhere. Should help narrow down where it's coming from.
Most likely a mistake you made in your settings file concating strings
related to where Django should upload files.

On Thu, Feb 3, 2022, 2:12 PM Joalbert Palacios <[email protected]> wrote:

> Hi group,
>
> I have been updating my django version so as to cover the last security
> patch with django version 3.2  (current version 3.2.12).
>
> Unfortunately, after this update the following exception occurs during
> execution of testing:
>
> Detected path traversal attempt in '/home/joalbert/Documents/Remesas
> App/RemesasServer/media/payments/images/temp_qHaTViL.png'
> Bad Request: /webapp/payment
>
> I have read
> https://stackoverflow.com/questions/69745412/django-and-suspiciousfileoperationdetected-path-traversal-attempt
> and followed but not works in my case, maybe I misunderstood something, I
> would appreciate any help regarding how to fix those exception.
>
> I read django code and find the errors is in the following section:
>
> def get_available_name(self, name, max_length=None):
>
> """
>
> Return a filename that's free on the target storage system and
>
> available for new content to be written to.
>
> """
>
> name = str(name).replace('\\', '/')
>
> dir_name, file_name = os.path.split(name)
>
> if '..' in pathlib.PurePath(dir_name).parts:
>
> raise SuspiciousFileOperation("Detected path traversal attempt in '%s'" %
> dir_name)
>
> Here it is my code in the sections that code goes by to send response to
> client.
>
> *Model.py:*
> class Payment(models.Model):
> STATUS = ((0, _("Draft")), (1, _("Aproved")), (2 , _("Rejected")), (3,
> _("Released")))
> order_number_id = models.OneToOneField(Exchange_Order,
> on_delete=models.CASCADE, related_name="order_payment")
> user_id =models.ForeignKey(User, verbose_name=_('user'), on_delete=
> models.CASCADE, related_name="payment_user_id")
> capture = models.FileField(verbose_name=_('image'),
> upload_to="payments/images", max_length=1024)
> payment_date = models.DateTimeField(verbose_name=_('date'),
> default=datetime.now().replace(tzinfo=timezone.utc))
> status = models.PositiveSmallIntegerField(verbose_name=_('status'),
> default=0, choices=STATUS)
> reason = models.ForeignKey(Reasons,verbose_name=_('reason'),
> on_delete=models.CASCADE, related_name="payment_reason",
> null=True, blank=True)
>
> def __str__(self) -> str:
> return f"{self.order_number_id} {self.user_id.username}
> {self.payment_date}"
> class Meta: #new
> verbose_name = _("Payment from Client to 'Activo Digital'")
> verbose_name_plural = _("Payments from Client to 'Activo Digital'")
>
> *forms.py*
> class Payment_All_Form(forms.ModelForm):
> class Meta:
> model = Payment
> fields = "__all__"
> views.py (only post method is included for clarity)
> class PaymentSessionView(LoginRequiredMixin, CreateView):
> queryset = Payment.objects.all()
> form_class = Payment_Form
> http_method_names = ['get', 'post']
> template_name="clienteServidor/webapp/payment.html"
>
> @method_decorator(User_Detail_Permission_Web)
> def post(self, request, *args, **kwargs):
> models = Exchange_Order.objects.filter(status=0, user_id=request.user)
> # En caso de que no haya ordenes abiertas
> if not models.exists():
> context =self._add_context_data()
> context["existant"] ="No hay orden abierta"
> context["form"] = Payment_Form()
> return render(request,self.template_name, context)
> # Procesar pago para ordenes abiertas
> forms = []
> data_list = []
> order_ids = []
> for model in models:
> my_data = self._complete_data(request, model.id)
> data_list.append(my_data)
> order_ids.append(f"Orden: {model.id}")
> forms.append(Payment_All_Form(my_data,request.FILES))
> # Chequear que todas las formas sean validas
> are_valids = []
> for form in forms:
> are_valids.append(form.is_valid())
> # If any invalid
> if False in are_valids:
> for index, items in enumerate(are_valids):
> if not items:
> form = forms[index]
> context = self._add_context_data()
> context["form"] = form
> return render(request,self.template_name, context)
> for index, model in enumerate(models):
> if index == 0:
> forms[index].save()
> else:
> data_list[index]["order_number_id"]=model
> data_list[index]["user_id"]=request.user
> datum = {k:v for k,v in data_list[index].items() if
> k!="csrfmiddlewaretoken"}
> payment = Payment(**datum)
> payment.save()
> model.status=1
> model.grouped_orders = order_ids
> model.save()
> my_message ="Orden Nro "+ str(model.id) + (" fue procesada exitosamente,
> les estaremos notificando"
> " por correo cuando el pago sea validado y procesado en el destino.")
> messages.add_message(request, messages.INFO, my_message)
> return HttpResponseRedirect(reverse_lazy("transaction_web"))
>
> Settings.py:
> MEDIA_ROOT = "./media/"#os.path.join(BASE_DIR, 'media')
> MEDIA_URL = '/media/'
>
> I hope sincerely that you could have any answer how to fix it. I really
> appreciate your help regarding this issue.
>
> Sincerely,
> Joalbert
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/35a15616-92fc-41d4-97b3-8fb3061ec881n%40googlegroups.com
> <https://groups.google.com/d/msgid/django-users/35a15616-92fc-41d4-97b3-8fb3061ec881n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CAF-Y%3De5AfqxZMjdT6P4XozpqSLwECe6zM9XOUb23PG%2BjhH1K2w%40mail.gmail.com.

Reply via email to