2016-04-14 14 views
1

enter image description hereWie kann ich das XSS mit Django + jQuery reparieren?

Ich schrieb diese Codes, die mit folgenden Ajax für die Nachrichtenfunktion sind. Als ich

<script>alert("Django+Ajax");</script> 

das Formular ausfüllen und einreichen, erscheint die Warnung in meinem Browser. Ich möchte der Ausgabe entkommen, aber ich habe keine Ahnung, was zu tun ist. Würden Sie mir bitte einige Ratschläge geben?

message.html

<html> 
<head> 
    <style type="text/css"> 
     div#message_form { 
      display: none; 
      margin: 25px; 
      padding: 25px; 
      background: #eee; 
      width: 200px; 
      height: 180px; 
     } 
    </style> 
</head> 
<body> 

    <input type="button" id="message" value="message"> <br /> 
    <div id="message_form"> 
     <form id="post_message" method="POST" action=""> 
      {% csrf_token %} 
      title: {{ form.title }} <br /> 
      body: {{ form.body }} <br /> 
      <input type="submit" value="send"> 
      <input type="reset" value="reset"> 
     </form> 
    </div> 

    <div id="get_title"></div> 
    <div id="get_body"></div> 


    {% load staticfiles %} 
    <script type="text/javascript" src="{% static "myapp/js/jQuery.js" %}"></script> 
    <script type="text/javascript" src="{% static "myapp/js/django_ajax.js" %}"></script> 
    <script type="text/javascript"> 

    $(function() { 

     $('#message').on('click', function() { 
      $('#message_form').slideToggle(); 
     }); 

     $('#message_form').submit(function(e) { 
      e.preventDefault(); 
      var url = location.href; 
      var arr = url.split('/'); 
      $.ajax({ 
       type: 'POST', 
       url: '/myapp/deal_message/', 
       dataType: 'json', 
       data: { 
        'title': $('#title').val(), 
        'body': $('#body').val(), 
        'target_id': arr[arr.length-2], 
       }, 
       success: function(data, dataType) { 
        $('#get_title').append(data.title); <!-- ### HERE ### --> 
        $('#get_body').append(data.body); <!-- ### HERE ### --> 
        $('#post_message')[0].reset(); 
       }, 
       error: function(XMLHttpRequest, textStatus, errorThrown) { 
        alert('Error: ' + errorThrown); 
       }, 
      }); 
      return false; 
     }); 

    }); 

    </script> 
</body> 
</html> 

forms.py

class Message(forms.ModelForm): 

    class Meta: 
     model = Message 

     fields = ('title', 'body',) 
     widgets = { 
      'title': forms.TextInput(attrs={'id': 'title', 'placeholder': 'message title'}), 
      'body': forms.Textarea(attrs={'rows': 4, 'cols': 18, 'id': 'body', 'placeholder': 'message body'}), 
     } 
     labels = {field:field for field in fields} 
     help_texts = {} 
     error_messages = {} 

views.py

#@login_required(login_url='/') 
def message(request, owner_id): 
    errors = "" 

    from myapp.forms import Message 
    view = { 
     'errors': errors, 
     'form': Message, 
    } 
    template = 'myapp/message/message.html' 
    return render(request, template, view) 


def deal_message(request): 
    u""" """ 

    #import pdb; pdb.set_trace() 

    errors = "" 
    sender_id = [request.user.user_id if isinstance(request.user.user_id, int) else 0].pop() 
    try: 
     target_id = int(request.POST['target_id']) 
    except ValueError as ve: 
     errors = ve 


    def chat_exist(sender_id, target_id): 
     # 1 on 1 
     from myapp.models import Chat 
     from myapp.models import Chat_Member 

     try: 
      sender_chats = Chat_Member.objects.filter(user_id=sender_id).filter(chat__type=0) 
      target_chats = Chat_Member.objects.filter(user_id=target_id).filter(chat__type=0) 

      cid = set([o.chat_id for o in sender_chats]) & set([o.chat_id for o in target_chats]) 
      if len(cid) == 0: 
       new_chat = Chat() 
       new_chat.type = 0 
       new_chat.save() 

       #new_chat.member = Chat_Member() 
       c1 = Chat_Member(chat_id=new_chat.chat_id, user_id=sender_id) 
       c2 = Chat_Member(chat_id=new_chat.chat_id, user_id=target_id) 
       c1.save() 
       c2.save() 
       return new_chat.chat_id 
      else: 
       if len(cid) != 1: 
        raise 
       else: 
        return cid.pop() 
     except: 
      return 0 


    chat_id = int(chat_exist(sender_id, target_id)) 

    res = {} 

    from myapp.forms import Message 
    formset = Message 
    if request.method == 'POST':  
     form = formset(request.POST) 
     if form.is_valid(): 
      try: 
       res['title'] = form.cleaned_data['title'] 
       res['body'] = form.cleaned_data['body'] 
       res = json.dumps(res) 

       from myapp.models import Chat 
       from myapp.models import Message 

       new_message = Message() 
       new_message.user_id = sender_id 
       new_message.chat_id = chat_id 
       new_message.title = form.cleaned_data['title'] 
       new_message.body = form.cleaned_data['body'] 
       new_message.save() 

       new_chat = Chat(chat_id=chat_id) 
       new_chat.last_message = form.cleaned_data['body'][:30] 
       new_chat.save() 
      except: 
       errors = "DB Error" 
     else: 
      errors = "" 

    return HttpResponse(res, content_type="application/json; charset=UTF-8") 

jQuery: 2.2.0, Django: 1.9.1, Python: 3.5.1

+0

@Joost Danke, werde ich jetzt überprüfen. – yamachan

+0

@Joost Ich lese und probiere eine Weile. Ich schrieb 'return HttpResponse (escape (res), content_type =" anwendung/json; charset = UTF-8 "), ich weiß, es ist völlig falsch, aber wie soll ich schreiben? In welcher Datei sollte ich etwas, views.py oder message.html schreiben? – yamachan

+0

@Joost Vielen Dank. 'res ['title'] = escape (form.cleaned_data ['title'])' hat funktioniert !! Vielen Dank. – yamachan

Antwort

2

Sie müssen den HTML-Code, den Sie im JSON-Objekt ausgeben, umgehen. Normalerweise hätte Django das für dich in einer normalen Antwort getan, aber da du es in JSON einkapselst, ist es nicht so einfach.

Verwenden Sie die escape Funktion, wie in this question beschrieben, bevor Sie JSON kodieren, wie folgt:

from django.utils.html import escape 

# ... 

res['title'] = escape(form.cleaned_data['title']) 
res['body'] = escape(form.cleaned_data['body']) 
res = json.dumps(res) 
+0

Vielen Dank, Joost. Ich hoffe, dass diese Frage jemandem helfen wird, der mit demselben Problem stecken wird. – yamachan

2

Es gibt eine sehr einfache Möglichkeit, jede Art von XSS in Bezug auf Formular zu lösen, wenn Sie es nur für Sonderzeichen wie <>() + usw. validieren oder versuchen, die XSS-Zeichen zu entkommen. Weitere Details here

+0

Vielen Dank für Ihre Antwort. Ah, ja, aber wie soll ich mit jQuery schreiben? Ich schrieb '$ ('# get_title'). Append (data.title);', aber ich weiß nicht, wie ich JSON-Daten dorthin senden soll. Sorry, es ist einfach, aber ich weiß nicht wie mit Ajax. – yamachan

+0

Zum Beispiel würde '

{{ message.title|safe }}
' funktionieren, aber wie kann ich '{{message.title | safe}}' an Ajax senden? – yamachan

Verwandte Themen