---
# System prepended metadata

title: DEF CON 2022 - Secure Code Review

---

# 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 ![](https://i.imgur.com/H5vbh6x.png)
- [ ] By using python safety found 49 vulns ![](https://i.imgur.com/LSSfbUk.png)
- [ ] 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}
- [ ] 
