Anurag Rana
Anurag Rana

Reputation: 1466

Django modelForm and html template - securiy concern

In Django, We use modelForms to save data to DB.

Model class:

# myapp/models.py
from django.db import models

class MyModel(models.Model):
    title = models.CharField(max_length=100)

ModelForm:

# myapp/forms.py
from django import forms
from .models import MyModel

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel

Now if I want to use this ModelForm or Model class to save data to DB from a form in html template then I must have name/ids of the input fields in html same as given in model class.

<tr><th><label for="id_title">Title:</label></th>
<td><input id="id_title" name="title" maxlength="100" type="text" /></td></tr>

Will this not pose a security risk? name of columns in DB are same as input fields in html?

Anyone can see the name of input fields. This is same as column name in DB. I think no one should know column , table or DB name.

Upvotes: 1

Views: 68

Answers (2)

Anurag Rana
Anurag Rana

Reputation: 1466

I found another solution to keep different names for column in DB and field name in html.
db_column.

name = models.CharField(max_length=128, db_column="myname")

This way, 'name' will be used in code everywhere but in table column name will be 'myname'.

Upvotes: 0

Andriy Ivaneyko
Andriy Ivaneyko

Reputation: 22021

Will this not pose a security risk? name of columns in DB are same as input fields in html?

I suppose if anyone would be able to query your database he would be able to view all tables and columns names in it, so hiding table and column names won't give any defense, it will give small inconvenience(or not).

However to avoid situations with exposing table name to frontend define db-table name attribute within your model meta:

# myapp/models.py
from django.db import models

class MyModel(models.Model):
    title = models.CharField(max_length=100)

    class Meta:
        db_table='some_other_name'

For hiding column names you can add prefix parameter to hide real model fields names (table columns) when you create a form instance:

MyModelForm(prefix='name_prefix')

Also, you can specify prefix in form definition:

class MyModelForm(forms.ModelForm):
    prefix = 'person'
    class Meta:
        model = MyModel

However that's still only prefix so to fully hide name you have to define MyModelForm.__init__ method and update each field.widget.attrs['name'] accordingly:

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = ['field_a',]

def __init__(self, *args, **kwargs):
    super(MyModelForm, self).__init__(*args, **kwargs)
    self.fields['field_a'].widget.attrs['name'] = 'custom_name'

Upvotes: 1

Related Questions