CVE-2022-2134 (Python, published 2022-06-20T15:15Z)
Description: value: Allocation of Resources Without Limits or Throttling in GitHub repository inventree/inventree prior to 0.8.0.
Severity: MEDIUM (CVSS v3 base score: 6.5)
Weakness: CWE-770 \u2014 Allocation of Resources Without Limits or Throttling
The product allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on the size or number of resources that can be allocated, in violation of the intended security policy for that actor.
Repository: https://github.com/inventree/inventree
Files changed:
InvenTree/InvenTree/fields.py
InvenTree/InvenTree/settings.py
InvenTree/InvenTree/static/css/color-themes/dark-reader.css
InvenTree/InvenTree/static/css/inventree.css
InvenTree/InvenTree/urls.py
InvenTree/build/migrations/0008_auto_20200201_1247.py
InvenTree/build/migrations/0014_auto_20200425_1243.py
InvenTree/build/migrations/0035_alter_build_notes.py
InvenTree/build/models.py
InvenTree/company/migrations/0010_auto_20200201_1231.py
InvenTree/company/migrations/0032_auto_20210403_1837.py
InvenTree/company/migrations/0045_alter_company_notes.py
InvenTree/company/models.py
InvenTree/order/migrations/0015_auto_20200201_2346.py
InvenTree/order/migrations/0020_auto_20200420_0940.py
InvenTree/order/migrations/0044_auto_20210404_2016.py
InvenTree/order/migrations/0053_salesordershipment.py
InvenTree/order/migrations/0070_auto_20220620_0728.py
InvenTree/order/models.py
InvenTree/part/migrations/0026_auto_20200131_1022.py
InvenTree/part/migrations/0029_auto_20200223_0901.py
InvenTree/part/migrations/0048_auto_20200902_1404.py
InvenTree/part/migrations/0061_auto_20210103_2313.py
InvenTree/part/migrations/0079_alter_part_notes.py
InvenTree/part/models.py
InvenTree/part/test_api.py
InvenTree/stock/migrations/0018_auto_20200202_0103.py
InvenTree/stock/migrations/0020_auto_20200206_1213.py
InvenTree/stock/migrations/0034_auto_20200426_0602.py
InvenTree/stock/migrations/0077_alter_stockitem_notes.py
InvenTree/stock/models.py
requirements.txt
Commit message: Remove reliance on django-markdownx (#3231)

* Remove reliance on django-markdownx

- We are now rendering notes on the client side using easymde
- No longer any need to utilize the markdownx integration
- Adds character limit for notes fields`

* Adjust legacy migrations - remove references to markdownx

* Fix bug for company notes field

Vulnerable code:
from datetime import datetime
    'markdownx',                            # Markdown editing
# Markdownx configuration
# Ref: https://neutronx.github.io/django-markdownx/customization/
MARKDOWNX_MEDIA_PATH = datetime.now().strftime('markdownx/%Y/%m/%d')

.markdownx .row {
    border-color: rgb(31, 31, 92);
}
.markdownx-editor {
    border-color: rgb(31, 31, 92);
}
.markdownx-preview {
    border-color: rgb(31, 31, 92);
}
.markdownx .row {
    margin: 5px;
    padding: 5px;
    border: 1px solid #cce;
    border-radius: 4px;
}

.markdownx-editor {
    width: 100%;
    border: 1px solid #cce;
    border-radius: 3px;
    padding: 10px;
}

.markdownx-preview {
    border: 1px solid #cce;
    border-radius: 3px;
    padding: 10px;
}


    # 3rd party endpoints
    re_path(r'^markdownx/', include('markdownx.urls')),
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Extra build notes'),
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Extra build notes', verbose_name='Notes'),
from markdownx.models import MarkdownxField

    notes = MarkdownxField(
        verbose_name=_('Notes'),
        blank=True, help_text=_('Extra build notes')
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True),
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, verbose_name='Notes'),
from markdownx.models import MarkdownxField
    notes = MarkdownxField(blank=True, verbose_name=_('Notes'))
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes'),
import markdownx.models
                ('notes', markdownx.models.MarkdownxField(blank=True, help_text='Order notes')),
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes', verbose_name='Notes'),
            field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes', verbose_name='Notes'),
import order.models

import markdownx.models

                ('notes', markdownx.models.MarkdownxField(blank=True, help_text='Shipment notes', verbose_name='Notes')),
from markdownx.models import MarkdownxField
from InvenTree.fields import InvenTreeModelMoneyField, RoundingDecimalField
    notes = MarkdownxField(blank=True, verbose_name=_('Notes'), help_text=_('Order notes'))
    notes = MarkdownxField(
        blank=True,
        verbose_name=_('Notes'),
        help_text=_('Shipment notes'),
    )
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(help_text='Part notes - supports Markdown formatting'),
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting'),
import markdownx

            field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting', null=True),
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting', null=True, verbose_name='Notes'),
from markdownx.models import MarkdownxField
from InvenTree.fields import InvenTreeURLField
    notes = MarkdownxField(
        blank=True, null=True,
        verbose_name=_('Notes'),
        help_text=_('Part notes - supports Markdown formatting')
    )
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Stock Item Notes'),
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Stock Item Notes', null=True),
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Stock Item Notes', null=True, verbose_name='Notes'),
from markdownx.models import MarkdownxField
from InvenTree.fields import InvenTreeModelMoneyField, InvenTreeURLField
    notes = MarkdownxField(
        blank=True, null=True,
        verbose_name=_("Notes"),
        help_text=_('Stock Item Notes')
    )
django-markdownx==3.0.1                 # Markdown form fields

Fixed code:


class InvenTreeNotesField(models.TextField):
    """Custom implementation of a 'notes' field"""

    # Maximum character limit for the various 'notes' fields
    NOTES_MAX_LENGTH = 50000

    def __init__(self, **kwargs):
        """Configure default initial values for this field"""
        kwargs['max_length'] = self.NOTES_MAX_LENGTH
        kwargs['verbose_name'] = _('Notes')
        kwargs['blank'] = True
        kwargs['null'] = True

        super().__init__(**kwargs)
from django.db import migrations, models
            field=models.TextField(blank=True, help_text='Extra build notes'),
            field=models.TextField(blank=True, help_text='Extra build notes', verbose_name='Notes'),
# Generated by Django 3.2.13 on 2022-06-20 07:28

import InvenTree.fields
from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('build', '0034_alter_build_reference_int'),
    ]

    operations = [
        migrations.AlterField(
            model_name='build',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Extra build notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
    ]
    notes = InvenTree.fields.InvenTreeNotesField(
        help_text=_('Extra build notes')
from django.db import migrations, models
            field=models.TextField(blank=True),
            field=models.TextField(blank=True, verbose_name='Notes'),
# Generated by Django 3.2.13 on 2022-06-20 11:23

import InvenTree.fields
from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('company', '0044_auto_20220607_2204'),
    ]

    operations = [
        migrations.AlterField(
            model_name='company',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Company Notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
    ]
import InvenTree.fields
    notes = InvenTree.fields.InvenTreeNotesField(help_text=_("Company Notes"))
from django.db import migrations, models
            field=models.TextField(blank=True, help_text='Order notes'),
                ('notes', models.TextField(blank=True, help_text='Order notes')),
            field=models.TextField(blank=True, help_text='Order notes', verbose_name='Notes'),
            field=models.TextField(blank=True, help_text='Order notes', verbose_name='Notes'),
                ('notes', models.TextField(blank=True, help_text='Shipment notes', verbose_name='Notes')),
# Generated by Django 3.2.13 on 2022-06-20 07:28

import InvenTree.fields
from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('order', '0069_auto_20220524_0508'),
    ]

    operations = [
        migrations.AlterField(
            model_name='purchaseorder',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Order notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
        migrations.AlterField(
            model_name='salesorder',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Order notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
        migrations.AlterField(
            model_name='salesordershipment',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Shipment notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
    ]
from InvenTree.fields import (InvenTreeModelMoneyField, InvenTreeNotesField,
                              RoundingDecimalField)
    notes = InvenTreeNotesField(help_text=_('Order notes'))
    notes = InvenTreeNotesField(help_text=_('Shipment notes'))
from django.db import migrations, models
            field=models.TextField(help_text='Part notes - supports Markdown formatting'),
from django.db import migrations, models
            field=models.TextField(blank=True, help_text='Part notes - supports Markdown formatting'),
            field=models.TextField(blank=True, help_text='Part notes - supports Markdown formatting', null=True),
            field=models.TextField(blank=True, help_text='Part notes - supports Markdown formatting', null=True, verbose_name='Notes'),
# Generated by Django 3.2.13 on 2022-06-20 07:28

import InvenTree.fields
from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('part', '0078_auto_20220606_0024'),
    ]

    operations = [
        migrations.AlterField(
            model_name='part',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Part notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
    ]
from InvenTree.fields import InvenTreeNotesField, InvenTreeURLField
    notes = InvenTreeNotesField(help_text=_('Part notes'))
    def test_part_notes(self):
        """Unit tests for the part 'notes' field"""

        # Ensure that we cannot upload a very long piece of text
        url = reverse('api-part-detail', kwargs={'pk': 1})

        response = self.patch(
            url,
            {
                'notes': 'abcde' * 10001
            },
            expected_code=400
        )

        self.assertIn('Ensure this field has no more than 50000 characters', str(response.data['notes']))

from django.db import migrations, models
            field=models.TextField(blank=True, help_text='Stock Item Notes'),
from django.db import migrations, models
            field=models.TextField(blank=True, help_text='Stock Item Notes', null=True),
            field=models.TextField(blank=True, help_text='Stock Item Notes', null=True, verbose_name='Notes'),
# Generated by Django 3.2.13 on 2022-06-20 07:28

import InvenTree.fields
from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('stock', '0076_alter_stockitem_status'),
    ]

    operations = [
        migrations.AlterField(
            model_name='stockitem',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Stock Item Notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
    ]
from InvenTree.fields import (InvenTreeModelMoneyField, InvenTreeNotesField,
                              InvenTreeURLField)
    notes = InvenTreeNotesField(help_text=_('Stock Item Notes'))