parent
2d6c61088d
commit
a6a75b643b
@ -0,0 +1,81 @@
|
|||||||
|
---
|
||||||
|
title: "The \"Quiz Your Friends\" XSS Exploit"
|
||||||
|
layout: post
|
||||||
|
---
|
||||||
|
|
||||||
|
## TODO write intro
|
||||||
|
|
||||||
|
## How I Found This Exploit
|
||||||
|
|
||||||
|
While filling in one of my friend's surveys I thought it would be
|
||||||
|
funny for them to know it is me without anyone else knowing.
|
||||||
|
We were young and had `Inspect Element`ed a few things together,
|
||||||
|
so it was a safe bet that an HTML joke would let them know.
|
||||||
|
|
||||||
|
So I typed in my name like so:
|
||||||
|
|
||||||
|
`BOLD_STEVE.JPG`
|
||||||
|
|
||||||
|
Now in theory this should have shown in in the leaderboard as: "<b>Bold Steve</b>"
|
||||||
|
However, to my horror and excitement, I saw this in the leaderboard:
|
||||||
|
|
||||||
|
`BOLD_STEVE_LEADERBOARD.JPG`
|
||||||
|
|
||||||
|
The text "Bold Steve" showed up **in bold** on the leaderboard.
|
||||||
|
This told me all I needed to know. To add a `<script>` tag was next.
|
||||||
|
|
||||||
|
#### Hacking:
|
||||||
|
|
||||||
|
So I went on my merry way thinking about ways to use malicious javascript.
|
||||||
|
Then, I thought that might be mean, so I decided to warn users instead.
|
||||||
|
I filled in the name with a script tag and a call to `alert()` to warn the user about this site.
|
||||||
|
|
||||||
|
`JAVASCRIPT_NAME.JPG`
|
||||||
|
|
||||||
|
I ran out of room before I could finish it. Hmmm.
|
||||||
|
What if I do "Inspect Element" and manually override the max-length attribute?
|
||||||
|
|
||||||
|
The unfortunate truth is: this worked as well!
|
||||||
|
|
||||||
|
Not only could I manually set the max-length by changing it in the HTML,
|
||||||
|
but there were no client-side OR server-side checks to make sure the name I was sending was less than or equal to 20 characters.
|
||||||
|
|
||||||
|
If Javascript checked it, it would have stopped me (although maybe not a professional).
|
||||||
|
If the server checked it, it could have stopped almost anyone.
|
||||||
|
|
||||||
|
##### Server-Side Validation
|
||||||
|
|
||||||
|
As a side note, here is a great reason why you should do most of your validation on the server side.
|
||||||
|
As a user, I can edit any of the HTML, CSS, or Javascript your server serves to me.
|
||||||
|
|
||||||
|
Imagine trying to fit in a script tag doing anything useful with 20 characters?
|
||||||
|
|
||||||
|
`<script src="http:">`
|
||||||
|
|
||||||
|
There's your 20 characters! No more! Good luck trying to do anything useful with this!
|
||||||
|
|
||||||
|
The Quiz My Friends server has *no such checks in place*.
|
||||||
|
Therefore, I can send an almost arbitrary load to them.
|
||||||
|
Being able to send something potentially very large (more than a few megabytes) is a vulnerability of its own.
|
||||||
|
Imagine being able to send entire executable progrmas as your "name" in one of these quizes?
|
||||||
|
|
||||||
|
|
||||||
|
## Executing An Exploit
|
||||||
|
|
||||||
|
Suppose we're on a vulnerable site like [Quiz Your Friends](https://www.quizyourfriends.com/)
|
||||||
|
and you decide you want to hack your friend's quiz!
|
||||||
|
How can this be done?
|
||||||
|
|
||||||
|
#### Creating A Quiz
|
||||||
|
|
||||||
|
Here is my quiz below:
|
||||||
|
|
||||||
|
`CREATING_QUIZ.IMG`
|
||||||
|
|
||||||
|
#### Setting A Name With an HTML Tag
|
||||||
|
|
||||||
|
Just like the image above, about how I found out about this vulnerability: go ahead and use an HTML tag in your name to test this out.
|
||||||
|
|
||||||
|
`BOLD_ITALIC_STEVE.JPG`
|
||||||
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
- institution: "Dartmouth College (Open Corseware)"
|
||||||
|
level: "Professional Certificate"
|
||||||
|
name: "C Programming with Linux"
|
||||||
|
years: "2020"
|
||||||
|
description: "A certification in C programming, the `gcc` compiler, and the `make` compilation system."
|
||||||
|
link: "https://credentials.edx.org/credentials/17b2f07e656d4d61a27153716c97a404/"
|
@ -1,9 +1,6 @@
|
|||||||
- name: "epub-with-pinyin"
|
- name: "epub-with-pinyin"
|
||||||
link: "https://github.com/TTWNO/epub-with-pinyin"
|
link: "https://github.com/TTWNO/epub-with-pinyin"
|
||||||
description: "A program which adds Mandarin Pinyin notation above Chinese characters in .epub files."
|
description: "A program which adds Mandarin Pinyin notation above Chinese characters in .epub files."
|
||||||
- name: "ttrpg.co"
|
|
||||||
link: "https://ttrpg.projects.tait.tech/"
|
|
||||||
description: "An work-in-progress accessible table-top-role-playing-game."
|
|
||||||
- name: "Chess"
|
- name: "Chess"
|
||||||
link: "https://github.com/TTWNO/chess"
|
link: "https://github.com/TTWNO/chess"
|
||||||
description: "A chess app written in C++"
|
description: "A chess app written in C++"
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
{% for types in site.data.links %}
|
||||||
|
<h2>{{ types.heading }}</h2>
|
||||||
|
<section class="contact-info">
|
||||||
|
{% for info in types.values %}
|
||||||
|
<p><span>{{ info.name }}</span> -
|
||||||
|
<a href="{{ info.value }}" class="mono">
|
||||||
|
{% if info.label != "INHERIT" %}
|
||||||
|
{{ info.label }}
|
||||||
|
{% else %}
|
||||||
|
{{ info.value }}
|
||||||
|
{% endif %}
|
||||||
|
</a></p>
|
||||||
|
{% endfor %}
|
||||||
|
</section>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
All my big projects are on my [homepage](/).
|
@ -0,0 +1,122 @@
|
|||||||
|
---
|
||||||
|
title: "How to Solve The Django Deployment Puzzle"
|
||||||
|
layout: post
|
||||||
|
---
|
||||||
|
|
||||||
|
A few days ago I had a Django project I wanted to put on a real server.
|
||||||
|
This project is still in its infancy, but I thought it would be nice to put it on my resume and show my friends.
|
||||||
|
Little did I know the headache coming my way.
|
||||||
|
Here are some tips to help you not make the same mistakes as me.
|
||||||
|
|
||||||
|
### ASGI Servers
|
||||||
|
|
||||||
|
Because my project used the ASGI (Asynchronous webServer Gateway Interface),
|
||||||
|
I needed to find a good production ASGI server to handle all the incoming requests.
|
||||||
|
The best thing I found was [uvicorn](http://www.uvicorn.org/).
|
||||||
|
It focuses on speed, which is a priority, especially when using the ASGI protocol.
|
||||||
|
|
||||||
|
To run uvicorn on the command line for testing purposes, use something like the following:
|
||||||
|
|
||||||
|
<pre class="terminal">
|
||||||
|
$ uvicorn --reload myapp.asgi:application
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
The `--reload` option says to reload the server if any of the files get updated.
|
||||||
|
This is not recommended in production.
|
||||||
|
Sadly, I thought this meant I would need to do a hard shutdown of the server process every time I wanted to update.
|
||||||
|
This turned out to not be the case.
|
||||||
|
|
||||||
|
### Workload Managers
|
||||||
|
|
||||||
|
There is another equine-named program called [gunicorn](https://gunicorn.org/)
|
||||||
|
which can hold a number of processes under its control.
|
||||||
|
An interesting feature of `gunicorn` is that it will gracefully switch from an old to a new deployment,
|
||||||
|
replacing the subprocesses one-by-one and eventually having only the new deployment active on all subprocesses.
|
||||||
|
The greatest part? Zero down time.
|
||||||
|
The server keeps any old processes open if there is communication with them,
|
||||||
|
then shift and new connections to the new deployment.
|
||||||
|
This was a very cool feature I wanted to take advantage of.
|
||||||
|
|
||||||
|
"Now hold on!" you might protest.
|
||||||
|
"gunicorn is a WSGI server!" ... oh you got me there!
|
||||||
|
Yes, that's right, `gunicorn` is paired with `uvicorn` to serve my files.
|
||||||
|
|
||||||
|
### systemd
|
||||||
|
|
||||||
|
Love it or hate it, the majority of Linux distributions use the `systemd` init system.
|
||||||
|
I decided it would be very convenient to have a .service file for my Django application to run automatically at boot.
|
||||||
|
`Systemd` allows me to do this with a file like the following one I stored in `/lib/systemd/system/lamegames.service`.
|
||||||
|
|
||||||
|
<pre class="file">
|
||||||
|
[Unit]
|
||||||
|
Description=Gunicorn/Uvicorn (lamegames.io)
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=/home/lame/lamegames.io
|
||||||
|
Type=simple
|
||||||
|
RemainAfterExit=yes
|
||||||
|
ExecStart=/home/lame/lamegames.io/env/bin/gunicorn lamegames.asgi:application -w 2 -k uvicorn.workers.UvicornWorker
|
||||||
|
ExecStop=/bin/kill -HUP $MAINPID
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
### nginx
|
||||||
|
|
||||||
|
NGINX (pronounced engine-X) is a performance web server designed for speed and simplicity.
|
||||||
|
For the front facing side of the site, I do need a production web server like nginx.
|
||||||
|
Gunicorn simply doesn't need all the features that nginx provides, but I do.
|
||||||
|
To configure my nginx installation, I used the following few directives to:
|
||||||
|
|
||||||
|
1. Redirect most traffic towards the gunicorn server.
|
||||||
|
2. Redirect statically served files (CSS, JS, images) to the directory specified in the STATIC_ROOT variable of my `settings.py` file.
|
||||||
|
3. Use TLS to enable https://
|
||||||
|
|
||||||
|
Serving the static files from nginx as opposed to the `gunicorn` server is necessary.
|
||||||
|
Gunicorn and other production A/WSGI web server will not set the proper MIME type over TLS.
|
||||||
|
This will cause your browser to not load the Javascript/CSS.
|
||||||
|
|
||||||
|
This is the important part of my nginx config.
|
||||||
|
|
||||||
|
<pre class="file">
|
||||||
|
server {
|
||||||
|
location / {
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
# these two lines ensure that WebSocket, and HTTP2 connection are forwarded correctly
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "Upgrade";
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_buffering off;
|
||||||
|
# this forwards all traffic to the local server on port 8000
|
||||||
|
proxy_pass http://localhost:8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
# This forwards all static requests to Django's STATIC_ROOT set in settings.py; it is generated using the collectstatic command.
|
||||||
|
location /static {
|
||||||
|
autoindex on;
|
||||||
|
alias /home/lame/lamegames.io/static_generated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
After all that, I was able to do the following:
|
||||||
|
|
||||||
|
<pre class="terminal">
|
||||||
|
# systemctl enable lamegames
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
This enabled my `gunicorn` server to run once the server started.
|
||||||
|
NGINX is that way be default.
|
||||||
|
|
||||||
|
And tada! You now have a working Django project on a production server!
|
||||||
|
|
||||||
|
#### Notes
|
||||||
|
|
||||||
|
* If using ws:// websockets, change them to wss:// for secure web sockets.
|
||||||
|
* Make sure to use channels.routing.get_default_application() instead of django.get_asgi_application() if your're wanting to use channels/redis WebSockets.
|
@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: "Home"
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tait Hoyem
|
||||||
|
|
||||||
|
<div id="img-wrapper">
|
||||||
|
<img id="main-img" src="/assets/img/banff.jpg" alt="A photot I took of the valley Banff, Alberta sits in">
|
||||||
|
<label for="main-img">Alberta, Canada</label>
|
||||||
|
</div>
|
||||||
|
### About
|
||||||
|
|
||||||
|
I am a student at the <a href="https://sait.ca/">Southern Alberta Insitute of Technology (SAIT)</a>.
|
||||||
|
|
||||||
|
My fascination lies primarily with operating system internals and systems-level tools.
|
||||||
|
My goal is to bring the everyday computing environment of Linux/BSD nerds to visually impaired users, and to ensure the saftey, privacy and security of the internet.
|
||||||
|
Some of my projects reflect this.
|
||||||
|
|
||||||
|
I have all of my code projects hosted on [my Github](https://github.com/TTWNO).
|
||||||
|
|
||||||
|
### Projects
|
||||||
|
|
||||||
|
**[epub-with-pinyin](https://github.com/TTWNO/epub-with-pinyin)** ---
|
||||||
|
I wrote a program to add Pinyin above Chinese characters in .epub files to assist myself and others learning Mandarin Chinese.
|
||||||
|
|
||||||
|
**[chess](https://github.com/TTWNO/chess)** ---
|
||||||
|
I wrote a command-line chess game in C++. It is compileable on almost any system.
|
||||||
|
|
||||||
|
**[tait.tech](https://github.com/TTWNO/tait.tech)** ---
|
||||||
|
All the code for my website is open source.
|
||||||
|
|
||||||
|
**[Napolean](https://github.com/TTWNO/Napolean)** ---
|
||||||
|
A work-in-progress suite of tools to be used in conjunction with a Raspberry Pi
|
||||||
|
and camera to produce text files from scanned books.
|
||||||
|
|
||||||
|
**[subnetting](https://github.com/TTWNO/subnetting)** ---
|
||||||
|
A one-night write of a tool to automatically calculate network subnet masks based on required hosts and base IP.
|
||||||
|
|
||||||
|
I also ocassionally put content on my [lbry channel](https://lbry.tv/@tait:7), and the [blog I host on this site](/blog/).
|
||||||
|
|
||||||
|
#### Ideas
|
||||||
|
|
||||||
|
Sometimes I have ideas that I haven't done anything with yet.
|
||||||
|
Those are [here](/ideas/).
|
||||||
|
|
||||||
|
### Contact
|
||||||
|
|
||||||
|
You can reach me via email at [tait@tait.tech](mailto:tait@tait.tech)
|
||||||
|
|
||||||
|
If you use PGP, [this is my public key](/public-key.asc)
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
layout: default
|
||||||
|
---
|
||||||
|
|
||||||
|
Here are my contact details if you would like to contact me professionally or personally.
|
||||||
|
|
||||||
|
{% include contact.html %}
|
Loading…
Reference in new issue