After completing the first 2 specifications in the last post, this week focus is on completing the 3rd spec - a wiki search functionality.
▶️ 3rd Specification ↑top
Search: Allow the user to type a query into the search box in the sidebar to search for an encyclopedia entry.
- If the query matches the name of an encyclopedia entry, the user should be redirected to that entry’s page.
- If the query does not match the name of an encyclopedia entry, the user should instead be taken to a search results page that displays a list of all encyclopedia entries that have the query as a substring. For example, if the search query were
Py
, thenPython
should appear in the search results. - Clicking on any of the entry names on the search results page should take the user to that entry’s page.
▶️ Django Learning ↑top
Before jumping🦘 into what I have learnt, below is a demo of the 3rd spec.
1️⃣ View must return an HttpResponse ↑top
The error❌ "The view didn't return an HttpResponse object. It returned None instead" is shown when a search query GET request is sent to the server.
- The
index()
function shown below is the function the server routes to when the GET request is received.
def index(request):
if request.GET.get('q'):
search(request, request.GET['q'])
else:
return render(request, "encyclopedia/index.html", {
"entries": util.list_entries()
})
# ...
# ...
def search(request, query):
fuzzy_match = []
# ...
# ...
return render(request, "encyclopedia/result.html", {
"query": query,
"results": fuzzy_match
})
As with many mistakes, when revisited it looks incredible obvious. This time the root cause is lack of a
return
statement when calling
search()
. This stackoverflow question points me to the right direction when I was debugging this issue.
2️⃣ Django Cross-Site Scripting protection (XSS👿) ↑top
When working on rendering the query string in the scenario that no result matches the query string, I noticed the possibility of XSS.
A simple illustration that I had in mind is a query as shown below:
http://127.0.0.1:8000/?q="</li></ul><script>alert("test")</script>
OR simply enter the text below into the search box
"</li></ul><script>alert("test")</script>
XSS vulnerability in action 👾
Fortunately Django has
autoescape
(documentation) on by default😇. Thus the demo above will not be possible.
It can be made possible to confirm the possibility of XSS by explicitly turning off
autoescape
.
{% autoescape off %}
{{ untrusted user controlled input text to be rendered }}
{% endautoescape %}
▶️ Conclusion ↑top
That's all for this post, next up - creating and editing wiki pages!
P/S: On related note regarding XSS, I imagine it will not be possible for XSS to occur by using the wiki page creation too. Will certainly keep you posted if it turns out otherwise 😉