# DEF CON 2022 - Secure Code Review
django-ecommerce
We assessed commit [`#260952e75344a88a2b4af56a357ec457fa354542`](https://github.com/justdjango/django-ecommerce/tree/260952e75344a88a2b4af56a357ec457fa354542)
[Clone here](https://github.com/justdjango/django-ecommerce.git)
---
# Notes for you/your team
## Behavior
* What does it do? (business purpose)
* simple e-commerce website
* Who does it do this for? (internal / external customer base)
* for external clients to buy stuff
* What kind of information will it hold?
* Client (address, country), Order, Refund, Payment (stripe_charge_id), Items (general products information)
* What are the different types of roles?
* Admin and Clients
* What aspects concern your client/customer/staff the most?
## Tech Stack
* Framework & Language - Rails/Ruby, Django/Python, mux/Golang
* Django 2.2.14
* oauthlib 3.0.1 - SSO lib for oauth
* pillow 6.2.2 - python imaging library
* python-openid 3.1.0 - SSO lib for openid
* django-allauth-0.39.1 - universal auth
* This version is vulnerable to account takeover
* Jquery 3.3.1
* 3rd party components, Examples:
* certifi==2019.3.9 - provides mozilla root certs to validate certs
* [stripe integration for payments](https://github.com/justdjango/django-ecommerce/blob/260952e75344a88a2b4af56a357ec457fa354542/README.md#L68-L69) - api key stored in the .env in the `settings.py` files
Vulnerabilities in `requirements.txt`:
Found 53 known vulnerabilities in 6 packages
|Name | Version| ID | Fix Versions|
|--------------------| -------| -------------------| --------------------|
|django | 2.2.14 | PYSEC-2021-9 | 2.2.18,3.0.12,3.1.6|
|django | 2.2.14 | PYSEC-2020-33 | 2.2.16,3.0.10,3.1.1|
|django | 2.2.14 | PYSEC-2021-8 | 2.2.22,3.1.10,3.2.2|
|django | 2.2.14 | PYSEC-2022-2 | 2.2.26,3.2.11,4.0.1|
|django | 2.2.14 | PYSEC-2021-98 | 2.2.24,3.1.12,3.2.4|
|django | 2.2.14 | PYSEC-2021-7 | 2.2.21,3.1.9,3.2.1|
|django | 2.2.14 | PYSEC-2021-6 | 2.2.20,3.0.14,3.1.8|
|django | 2.2.14 | PYSEC-2021-439 | 2.2.25,3.1.14,3.2.10|
|django | 2.2.14 | PYSEC-2021-99 | 2.2.24,3.1.12,3.2.4|
|django | 2.2.14 | PYSEC-2020-34 | 2.2.16,3.0.10,3.1.1|
|django | 2.2.14 | PYSEC-2022-3 | 2.2.26,3.2.11,4.0.1|
|django | 2.2.14 | PYSEC-2022-1 | 2.2.26,3.2.11,4.0.1|
|django | 2.2.14 | PYSEC-2022-20 | 2.2.27,3.2.12,4.0.2|
|django | 2.2.14 | PYSEC-2022-19 | 2.2.27,3.2.12,4.0.2|
|django | 2.2.14 | PYSEC-2022-190 | 2.2.28,3.2.13,4.0.4|
|django | 2.2.14 | PYSEC-2022-191 | 2.2.28,3.2.13,4.0.4|
|django-debug-toolbar| 1.10.1 | PYSEC-2021-10 | 1.11.1,2.2.1,3.2.1|
|pillow | 6.2.2 | PYSEC-2020-78 | 7.1.0|
|pillow | 6.2.2 | PYSEC-2020-79 | 7.0.0|
|pillow | 6.2.2 | PYSEC-2020-76 | 7.1.0|
|pillow | 6.2.2 | PYSEC-2021-137 | 8.2.0|
|pillow | 6.2.2 | PYSEC-2021-138 | 8.2.0|
|pillow | 6.2.2 | PYSEC-2021-70 | 8.1.0|
|pillow | 6.2.2 | PYSEC-2021-331 | 8.3.0|
|pillow | 6.2.2 | PYSEC-2021-41 | 8.1.1|
|pillow | 6.2.2 | PYSEC-2020-80 | 7.1.0|
|pillow | 6.2.2 | PYSEC-2021-71 | 8.1.0|
|pillow | 6.2.2 | PYSEC-2021-69 | 8.1.0|
|pillow | 6.2.2 | PYSEC-2021-38 | 8.1.1|
|pillow | 6.2.2 | PYSEC-2021-139 | 8.2.0|
|pillow | 6.2.2 | PYSEC-2021-94 | 8.2.0|
|pillow | 6.2.2 | PYSEC-2021-39 | 8.1.1|
|pillow | 6.2.2 | PYSEC-2021-36 | 8.1.1|
|pillow | 6.2.2 | PYSEC-2020-77 | 7.1.0|
|pillow | 6.2.2 | PYSEC-2021-40 | 8.1.1|
|pillow | 6.2.2 | PYSEC-2021-37 | 8.1.1|
|pillow | 6.2.2 | PYSEC-2021-317 | 8.3.2|
|pillow | 6.2.2 | PYSEC-2021-35 | 8.1.1|
|pillow | 6.2.2 | PYSEC-2021-93 | 8.2.0|
|pillow | 6.2.2 | PYSEC-2021-42 | 8.1.1|
|pillow | 6.2.2 | PYSEC-2021-92 | 8.2.0|
|pillow | 6.2.2 | PYSEC-2022-10 | 9.0.0|
|pillow | 6.2.2 | PYSEC-2022-9 | 9.0.0|
|pillow | 6.2.2 | PYSEC-2022-8 | 9.0.0|
|pillow | 6.2.2 | PYSEC-2022-168 | 9.0.1|
|pillow | 6.2.2 | GHSA-jgpv-4h4c-xhw3| 8.1.2|
|pillow | 6.2.2 | GHSA-4fx9-vc88-q2xc| 9.0.0|
|urllib3 | 1.24.3 | PYSEC-2021-108 | 1.26.5|
|urllib3 | 1.24.3 | PYSEC-2020-148 | 1.25.9|
|sqlparse | 0.2.4 | PYSEC-2021-333 | 0.4.2|
|urllib3 | 1.24.2 | PYSEC-2021-108 | 1.26.5|
|urllib3 | 1.24.2 | PYSEC-2019-132 | 1.24.3|
|urllib3 | 1.24.2 | PYSEC-2020-148 | 1.25.9|
* Datastore
* sqlite3
## Brainstorming / Risks
* possible the access carts or orders of other users?
* possible to check out without paying?
* check cookie attributes
## Checklist of things to review
### Risks
- [ ] It is possible to do user/client enumeration on the forgot password page
- [ ] Pillow seems to be vulnerable lib - https://security.snyk.io/package/pip/pillow/6.2.2
- [ ] Found several vuln libraries that need to be validated 
- [ ] By using python safety found 49 vulns 
- [ ] stripe_charge_id - might be a credit card number - https://github.com/justdjango/django-ecommerce/blob/276f74ddf3514f5128225b9e7cfeb34f64e6c374/core/migrations/0001_initial.py#L83
- [ ] No unity tests (Authn, AuthZ, etc)
- [ ] on checkout the shipping address [form doesn't validate addr2??](https://github.com/justdjango/django-ecommerce/blob/260952e75344a88a2b4af56a357ec457fa354542/core/views.py#L98-L117)
- [x] [**Finding** The add_to_cart view uses a GET request and it does not perform CSRF protection.](https://github.com/justdjango/django-ecommerce/blob/260952e75344a88a2b4af56a357ec457fa354542/core/views.py#L372-L400). The template uses a simple `a` tag for the action: `<a href="{{ object.get_add_to_cart_url }}`. `remove_from_cart` and `remove_single_item_from_cart`
- [ ] Lacking external libs integrity checks (SRI) - https://github.com/justdjango/django-ecommerce/blob/276f74ddf3514f5128225b9e7cfeb34f64e6c374/templates/base.html#L12-L15
### Authentication
### Authorization
### Auditing/Logging
- [ ]
### Injection
* I see no references to `*.objects.raw`
### Cryptography
- [ ]
### Configuration
- [ ]
## Mapping / Routes
- [ ] `/admin/ admin.site.urls)`
- [ ] `/accounts/* allauth.urls`
- [ ] `/accounts/login/ allauth.account.views.LoginView`
- [ ] `/accounts/signup/ allauth.account.views.SignupView`
- [ ] `/accounts/logout/ allauth.account.views.LogoutView`
- [ ] `/accounts/password/set/ allauth.account.views.PasswordSetView`
- [ ] `/accounts/password/change/ allauth.account.views.PasswordChangeView`
- core:
- [ ] `/checkout/ CheckoutView.as_view(), name='checkout'`
- [ ] `/order-summary OrderSummaryView.as_view(), name='order-summary'`
- [ ] `product/<slug>/ ItemDetailView.as_view(), name='product'`
- [ ] `/add-to-cart/<slug>/ add_to_cart, name='add-to-cart'`
- [ ] `/add-coupon/ AddCouponView.as_view(), name='add-coupon'`
- [ ] `/remove-from-cart/<slug>/ remove_from_cart, name='remove-from-cart'`
- [ ] `/remove-item-from-cart/<slug>/', remove_single_item_from_cart,
name='remove-single-item-from-cart'`
- [ ] `/payment/<payment_option>/ PaymentView.as_view(), name='payment'`
- [ ] `/request-refund/', RequestRefundView.as_view(), name='request-refund'`
## Mapping / Authorization Decorators
- [ ] `@login_required`, applied to `add_to_cart`, `remove_from_cart`, `remove_single_item_from_cart`. It is not applied to: `CheckoutView`,
`PaymentView`, `HomeView`, `OrderSummaryView`, `ItemDetailView`, `get_coupon`, `AddCouponView`, `RequestRefundView`. Not sure why you must be logged in to add things to your cart, but not to check out.
* The checkout view gets the order associated with the current user. any issues with cookie attributes or handling could expose other user details (shipping/billing address)
## Mapping / Files
- [ ] requirements.txt
- [ ] djecommerce/settings/{base.py, development.py, production.py}
- [ ]