<!--toc--> |
|
## Introduction |
|
Security is one of the major concerns in development of web applications as they are instantly exposed to the world that is full of potential attackers. |
|
Writing web applications today is very similar to walking |
over a minefield. If you don't have proper tools and knowledge you are most likely going to loose a "virtual lag". |
|
## State of Mind |
|
There are several golden rules in writing secure web applications: |
|
1. Never trust users input. |
2. Think - "How can I attack my application" |
3. Learn common vulnerabilities and methods of their prevention so you at least would not do the mistakes others did. |
|
So when it comes to writing web applications always remember that there *is* somebody who would actually try |
to something bad to your site and you are lucky if you |
will discover this. |
|
What is even more important that at some point, your |
_will_ make a mistake and your web site |
_will_ be cracked and you'll have to do a hard work |
to restore it. So keep backups and even more important |
check your [restore procedures](http://www.joelonsoftware.com/items/2009/12/14.html) work. |
|
## SQL Injections |
|
This is one of the most basic problems that |
web developer should be familiar with. |
|
Have you ever written code like: |
|
std::string query= |
"SELECT 1 from users " |
"WHERE username='" + username +"' AND " |
" password='" + password "'; |
|
mysql_query(conn,query.c_str()); |
... |
|
What is the problem? |
|
Assume that password value is |
|
' OR ''=' |
|
So the query would look like |
|
SELECT 1 from users |
WHERE username='user' AND |
password='' OR ''='' |
|
Which would always return 1... |
|
So you get authenticated for knowing SQL `:-)` and not |
having proper password |
|
If you had ever did it then you should never do |
web development till you read this article: |
|
[SQL Injection](http://en.wikipedia.org/wiki/SQL_injection) |
|
How do you prevent SQL injections? |
|
Use prepared statements. [CppDB library](http://art-blog.no-ip.info/sql/cppdb/) provides all tools you need. |
|
Just rewrite the example above" |
|
sql << "SELECT 1 FROM users " |
"WHERE username=? AND password=?" |
<< username << password; |
|
Now the values of ? would be _properly_ substituted |
with correct values with their real equivalent. |
|
The query as value would be physically separated. |
|
## Sessions |
|
HTTP protocol is stateless so in order to keep |
a track of the users on our web site we store |
an information in the session. For example: |
|
session().set("username",username); |
|
Now we can know who is the user. Now if we have |
the `username` in the session we know what he can |
do for example. |
|
There are two ways to store the data in the session: |
|
1. Store all the data at the server side saving a unique |
session id at the client side in cookie. |
2. Store all the data at the client side in a cookie and |
we ensure its validity by digitally signing it. |
|
See: [CppCMS Configuration: session](http://art-blog.no-ip.info/wikipp/en/page/cppcms_1x_config#session) |
|
This cookie is very valuable information as if attacker |
gets this cookie he can impersonate himself to this |
particular user. |
|
### What to store in the session? |
|
It is ok to store some not-so valuable information |
like user name user id and may be some properties |
then can affect user itself. |
|
However there are several things you should not |
keep in session: user permissions and rights. |
|
Remember that each user can have more then one active |
session. Consider you store his rights in the session, |
now we want to drop his right and we can't as we don't |
know which sessions belong to the user. |
|
|
### Session handling is cookie based |
|
In CppCMS session handing is cookie based and |
only cookie based, so trust CppCMS and don't |
reinvent your own methods. |
|
There are many popular methods to store session |
id that have design flaws. For example, consider |
a popular method of keeping session id in the query string: |
|
http://www.mybank.com/?sid=1234564435 |
|
Now publish a link `http://attckers_site.com/` on the |
`www.mybank.com` web site. The innocent user |
clicks on this link the attacker get user's session id |
in the Referrer HTTP header. |
Now attacker can go to `www.mybank.com` add `?sid=1234564435` to the URL and transfer all |
users money to his account. |
|
So don't reinvent the wheel, use CppCMS session |
mechanism that handles this in safely for you. |
|
### Client side storage considerations (Replay attack) |
|
Client side storage is very useful as it allows to |
keep all the data at the client side without need |
of keeping tack of file system or using DB for |
the session storage. |
|
This is especially critical for high performance |
applications. |
|
However client side storage has one important |
security problem - we have no way to invalidate it |
by anything else then timeout. |
|
Consider a situation were we playing a game where |
on each level we need to select a one answer from 4. |
|
Now consider user had made a mistake. Now he is not |
pleased and he restores his previous cookie and now |
goes to the same level again - returns back in time. |
|
There is no way to reset his session to level 1 because |
he always can go back in time. |
|
So client side storage in very good thing to use but |
you should be very careful with it. |
|
### Hiding session data. |
|
Sometimes it is useful to store some data in the |
session the way the user would not know what it contains. |
|
There is no problem when you are using server side storage, |
however when you use client side storage you need |
to encrypt the data. |
|
CppCMS provides an option to use encryption such that |
the data stored on the client side would be [automatically |
encrypted](http://art-blog.no-ip.info/wikipp/en/page/cppcms_1x_config#session.client.cbc) |
|
Use it if you don't want user to see the data you |
store in its session. |
|
### Session expiration |
|
There are two basic methods used for session expiration: fixed and renew. See [session.expire](http://art-blog.no-ip.info/wikipp/en/page/cppcms_1x_config#session.expire) |
|
1. `fixed` - the session would expire in fixed period of time since its creation. Use this for all critical parts. Because if the session is hijacked it would limit the amount |
of time the attacker can spend on the web site. |
2. `renew` - the session is automatically renewed on every visit. It is very user friendly policy, but it allows |
to keep the session virtually forever. |
|
Now when bad things happen and we want to invalidate |
all existing sessions. |
|
- Server side storage: just clear the directory that |
keeps the sessions. By default it is `/tmp/cppcms_sessions/` |
- Client side storage: change the secret key of the |
the hmac signature. |
|
### Session Fixation |
|
This is a kind of attack that is used for impersonating |
other users. |
|
Consider example: |
|
1. Attacker goes to a bank side and receives a session id - special cookie. |
2. Attacker injects this cookie to the innocent user using |
some kind of XSS attack (see below). |
3. User logs in into bank, because the had received the |
cookie he already has the session id and this session id |
receives some additional rights like to do operations |
on the bank account. |
4. Attacker goes to the bank site using the same cookie |
stored in the user's browser and performs any kind |
of operations user can do. |
|
How to prevent this? |
|
cppcms::session_interface::reset_session(); |
|
By calling this function during the critical operations |
like user log-in the session id would be replaced with |
a new one: |
|
if(authentication_ok()) { |
session().reset_session(); |
session().set("user_id",id); |
} |
|
This simple operation would prevent session fixation attacks. |
|
|
## Cross Site Scripting (XSS) |
|
Cross Site Scripting in one of the most dangerous problems |
[Cross Site Scripting](http://en.wikipedia.org/wiki/Cross-site_scripting) in one of the most dangerous problems |
web developers should deal with. |
|
Most web application deal with content, sometimes it |
may be very rich HTML content. Allowing user to |
set his own HTML content as-is provides lots of |
tool for attacking web site via injecting JavaScript |
and for example storing uses session cookies, |
and escalating user privileges to much higher ones, |
defacing web sites and much more |
|
Many dangerous things can be done even without |
writing Java Script code but only using simple |
CSS: Clickjacking, defacing and more. |
CSS: [Clickjacking](http://en.wikipedia.org/wiki/Clickjacking), [defacement](http://en.wikipedia.org/wiki/Website_defacement) and more. |
|
So if you want to display a rich content you are |
most likely need to apply some XSS filters to prevent |
bad things. |
|
### No HTML |
|
First and most basic rule... Do not allow user to |
write HTML content on the web site. |
|
This is done by template system by default. Any value |
that is displayed on the web site is escaped by default |
such that HTTP attributes like `<` are |
converted to the save values like `<`. |
|
However you should notice two things: |
|
1. This does not makes it safe if you, |
for example write the value inside `href` attribute. |
|
Consider: |
|
<a href="<%= users_site %>">Hope page</a> |
|
If `users_site` value that is provided by |
attacker is not verified he can insert value |
like |
|
javascript:alert('XSS') |
|
And execute his code upon click. |
must not |
|
|
### XSS Filter |
|
|
However sometimes |
|
CppCMS provides XSS filters that allow to filter HTML |
content using strict white list rules. |
Then can be found under [`cppcms::xss`](http://art-blog.no-ip.info/cppcms_ref_v0_99/namespacecppcms_1_1xss.html) namespace. |
|
The filter uses a predefined set of rules that define |
what HTML tags and attributes can be used. |
|
XSS rules can be written using simple JSON format and |
then loaded and used. |
|
|
The web developer should carefully select the tags |
ones allow to use for content. Special care should be |
given for url and style attributes. |
|
Starting from CppCMS 0.99.10 it is possible to create |
policy file using simple JSON format. |
|
For example, this JSON file defiles the simple rule that |
can be used with basic TinyMCE WYSIWYG editor: |
|
{ |
"encoding" : "UTF-8", |
"entities" : [ "nbsp" ], |
"tags" : { |
"opening_and_closing" : [ |
"p", |
"ul","ol","li", |
"strong", "em", |
"span", |
"a" |
], |
"stand_alone" : [ "br" , "hr" ] |
}, |
"attributes" : [ |
{ |
"tags" : [ "a" ], |
"attributes" : [ "href" ], |
"type" : "absolute_uri" |
}, |
{ |
"tags" : [ "span" ], |
"attributes" : [ "style" ], |
"type" : "regex", |
"expression" : |
"(\\s*text-decoration\\s*:\\s*(underline|line-through)\\s*;)*" |
} |
] |
} |
|
It can be loaded from file by simple calling: |
|
|
cppcms::xss::rules rules(path_to_file); |
|
And then content can be filtered as: |
|
safe = cppcms::xss:filter(unsafe,rules); |
|
It would validate the input and remove all tags and |
properties that do not fit this policy. |
|
|
### CSS Styles |
|
## Cross Site Request Forgery (CSRF) |
## Cryptographic Tools |
### crypto namespace |
### Random numbers generation |
## Character Set Considerations |
## C and C++ Security |
### General Notes |
### Buffer Overflow |
### Integer Overflow |
### Dangling pointers |
## What happens if we still fail? |
### Running as limited user |
### Pre-`fork`ing |
### `chroot`ing |
## Links |
|
- [Ruby On Rails Security Guide](http://guides.rubyonrails.org/security.html) |
- [Open Web Application Security Project](https://www.owasp.org/index.php/Main_Page) |
- [XSS Cheat Sheet](http://ha.ckers.org/xss.html) |