# Case Study: Multiple Convore Security/Privacy Problems
A website named [Convore](https://convore.com/) was released to the public
yesterday. It has the tagline:
> Convore is a quick way to instant message with groups of friends in real-time.
Join public or private groups and talk about anything!
As a curious hacker, I decided to give the website a once over to see if I could
find any security or privacy problems. I found several, some of which were quite
serious. I will write about them here so hopefully people will learn from
Convores mistakes.
**Responsible disclosure:** I gave Convore access to this list of issues and
allowed them to fix the critical ones before publishing. I initially intended to
disclose only the XSS flaw privately
and the rest publicly, but the CTO was quick to respond and deal with my report
so I decided to give them the chance to fix the rest of the issues as well
before publishing.
**1.) Not properly escaping output, leading to an XSS attack (Fixed)**
If you visit a topic and leave a comment which contains a URL, Convore replaces
that URL with an anchor tag. When I noticed this, I did a simple check to see if
they properly escape the contents of the anchor tag by writing this URL:
```text
http://google.com/?foo=%3Cscript%3Ealert%28document.cookie%29%3C/script%3E
```
The content that appeared in the HTML of the topic was this:
```html
https://www.grepular.com?foo=****
```
You will see that they didn't properly escape the text part of the anchor tag.
It should have looked like this:
```html
https://www.grepular.com?foo=**<script>alert(document.cookie)</script>**
```
This simple mistake meant that a malicious hacker could post a comment in a busy
group which would allow them to completely take over the accounts of everyone
who viewed the comment. This is called an XSS attack, and if it hadn't been
fixed it **would** have been abused. Definitely not something you want to happen
just after your site has launched.
**2.) Not properly validating untrusted input (Fixed)**
If you try to visit certain URLs that require you to be logged in such as the
settings page:
```text
https://convore.com/settings/account/
```
You get redirected to the login form, with a URL like this:
```text
https://convore.com/login/?next=/settings/account/
```
So I wondered to myself. Do they properly sanitise the "next" parameter? No,
they weren't. If I sent a user to this URL:
```text
https://convore.com/login/?next=https://www.grepular.com/
```
They would end up on my website. If they are already logged in, it would
redirect immediately. How could I use this? If I create a hidden image tag like
the following on my own website, I would be able to tell if a visitor to my
website is also logged in to convore.com:
```html
```
I wrote about this particular technique recently, here: [Abusing HTTP Status
Codes to Expose Private
Information](/Abusing_HTTP_Status_Codes_to_Expose_Private_Information). Another
way of using this technique (which doesn't work in IE/Opera, but works in most
other browsers) is as follows:
```html
```
This one worked because https://convore.com/live/ was returning a 200 status
code when logged in, and a 404 when not logged in. Firefox, Safari, Chrome and
other browsers don't care that the response didn't contain JavaScript, as long
as it was successful.
They initially fixed this issue by forcing the "next" parameter to begin with a
forward slash. Don't make the same mistake. This doesn't take into account
protocol relative URLs. The following two HTTP location headers are equivalent:
```text
Location: https://www.grepular.com/
Location: //grepular.com/
```
The second location header works because it recognises the URL as a protocol
relative URL because it begins with two slashes, and it prefixes the URL with
"https" because the request which triggered that response was HTTPS it's self.
So even after they rolled out the fix, I could still redirect to my own website
by creating URLs like this:
```text
https://convore.com/login/?next=//grepular.com/
```
This is the same reason you can create anchor tags like this:
```html
Grepular.com
```
I tried another trick, which they weren't susceptible to, but it's interesting
enough for me to write about it here. It's called HTTP header injection. They
take the contents of the "next" parameter above, and create a header using it
like this:
```text
Location: /the/url
```
So I tried to inject another header using "%0D%0A" which is the hex encoding for
a carriage return followed by a line feed. I tried going to this URL:
```text
https://convore.com/login/?next=/the/url/%0D%0ALocation%3A%20https%3A//grepular.com/
```
Hoping that they would then output the following:
```text
Location: /the/url/
Location: https://www.grepular.com/
```
It didn't work, but it's a technique you should probably be aware of. If it had
worked, it would have been another vector for an XSS attack because I could have
injected two newlines to break out of the headers, and then my own HTML.
**3.) Leaking information like crazy (Not fixed)** When you view a group, your
username and avatar are displayed on it for all to see, whether or not they are
logged in. There is no way to turn this off. As a website owner, I could set up
a public group, and then link to it on a webpage inside an iframe. Then when
anybody who happens to be logged into convore.com, visits my website, I will be
able to see them viewing my group at the same time. I could automate something
to take snapshots of my group page to try and link IPs against users. It doesn't
even need to be an iframe, an img tag would work too.
They have not addressed this issue, and I am not sure if they will. This is one
of those issues where you can disagree on whether or not it's a problem. All I
know is that I can create a cron job as follows to alert me via email when the
Convore CTO is online:
```bash
1-56/5 * * * * if [[ `wget -qO - --no-check-certificate https://convore.com/users/ericflo/|grep "yes"` != "" ]]; then echo "Convore CTO is online"; fi
```
We wouldn't tolerate this from Facebook. I wont use Convore personally until
there is an option to hide my online/offline status and hide which groups I am
viewing.
**4.) More information leaking, and a CSRF attack (Fixed)**
If I wanted a list of Convore users who view my website to be sent to me via
email, I could simply create an img tag on my webpage as follows:
```html
```
Yes, that would automatically, and in the background get a user to make a
request to join my private group. This is called a CSRF attack and can in many
cases be as dangerous as an XSS attack; I once found a CSRF attack in the
management interface of [Linode.com](https://www.linode.com/) which would allow
me to reboot other peoples servers.
Each time a user attempts to join a private group, an email is sent to the group
admin like this:
```text
From: convore@convore.com
To: my.conver.email.address@example.com
Subject: **their_username** has requested to join **private_group_name**
**their_username** has requested to join **private_group_name**.
To accept or decline this request, please visit the following link:
https://convore.com/pending/requests/
Cheers,
The Convore team
Is there anything else we can do? Let us know at https://convore.com/feedback/
```
This trick could also be used to make users sign up to all sorts of other groups
without their knowledge.
**5.) Reconnecting disconnected social networks (Another CSRF attack - Not
fixed)**
You can connect Facebook or Twitter to your account. It doesn't tell you at the
time, but this isn't just for login purposes, it's also for displaying links to
your Facebook/Twitter profiles on your public Convore profile. If you disconnect
a Facebook profile, it doesn't require any human intervention to be reconnected
afterwards. If you are logged in to Convore and Facebook at the same time and
visit a malicious page which contains this:
```html
```
Then your Facebook account will be re-connected to your Convore account without
your knowledge.
**6.) Incomplete SSL Setup (Fixed - Kind of)**
They use SSL/HTTPS across the entire website. They also use the "secure" flag
when setting cookies. This is brilliant; they've taken encryption over the
network seriously. One thing they hadn't done at the time I reported this issue
was implement
[HSTS](https://secure.wikimedia.org/wikipedia/en/wiki/HTTP_Strict_Transport_Security
"HTTP Strict Transport Security"). If your entire site is served over HTTPS, you
should look into implementing HSTS. They have now implemented it, but the way
they have done it is not particular useful as they've set the timeout to 500
seconds when it should really be days or weeks long. Perhaps they're in testing
mode?
As well as the HSTS HTTP header, I notice they now have a header like this:
```text
X-Frame-Options: DENY
```
I don't **think** that existed before so I'm assuming somebody else reported an
exploit which lead to the header being added. That header tells your browser
that the webpage can not be opened inside an iframe, and is very useful at
preventing a style of attack called
[Clickjacking](https://www.owasp.org/index.php/Clickjacking)
**7.) No private profiles (Not fixed)**
Your profile is public, and tells the World if you are logged in, and even what
groups you are currently viewing. You can not disable this.
**8.) No option to delete your account (Not fixed)**
Seriously... Why are people **still** making websites which don't provide the
option to cancel your account? This is not the sort of thing you can easily bolt
on later. You need to take this into consideration from the very beginning of
designing your database and building your site around it.
**What can I do about this?**
As a user, what can you do? Log out of websites you're not using. Don't log into
one website and then start using another one at the same time. Install the
Firefox [Request Policy](https://www.requestpolicy.com/) addon. Use
[NoScript](https://noscript.net/). And most important of all... Do not put
information on the Internet that you don't need to.
If you'd like me to perform a similar analysis on a site you're about to launch,
or an existing website, you can hire me through [Cardwell IT
Ltd.](http://cardwellit.com/)