Web Security

Máté Cserép

April 2018, Budapest

Big Picture

  • Today almost nobody is interested in "hacking a website"
  • They want to steal credit card information, get email addresses, impersonate banking websites, etc.
    • This means the web site is not the goal, but just the medium
    • One consequence: hacking should be very "silent"
      • Nobody should notice that it occurred, not even the owner
      • Rare but existing: fixing security problems after hacking to keep away others and prevent any problems (which means attention) for the admin!
  • Economy of scale: comparatively few software is used on the web (compared to websites, webservers)
    • One flaw found: Automatic reuse across a huge number of opportunities possible!

General problems

  • Huge number of “not-that-educated-in-security” webmaster
    “Getting it to run” is easy -> A new webmaster is born!
  • Law of Vulnerabilities: Even very old vulnerability (where patches
    are available!) will occur for a very long time
    • Even with old attacks one can still be successful!
    • First patch, then go online: old attacks will be tried as well!
  • Some attacks are extremely complex
    • One can’t do anything against it, except wait for a patch by the
      software vendor, switch software or shut down the server
  • World Wide Web is an automated system, 24/7 online
    • Automatic testing/attacks are possible without difficulty
    • Preventing them is very hard; detection and selective
      blocking/temporary lockouts are an option

Vulnerability life-cycle: Intuitive

Intrusions increase once users discover a vulnerability, and the rate continues to increase until the vendor releases (and system administrators install) a patch or workaround.

Vulnerability life-cycle: Possible

Type of attacks

  • Attacks against cryptography: incorrect implementation, bad key/certificate handling, systematic weaknesses (TLS protocol problem!), etc.
  • Information leakage: error messages, internal data sent to client, direct object reference, CSS hacking, etc.
  • Input validation problems: SQL injection, Cross site scripting, encoding validation, etc.
  • Incorrect code: buffer/heap overflow, malicious file execution, access control errors, etc.
  • Trusting the client: unvalidated redirect and forwards, client-side security, etc.

Completely new types of attacks are very rare!

Web Security Report 2013

OWASP Top 10
A1 Injection
A2 Broken Authentication and Session Management
A3 Cross-Site Scripting (XSS)
A4 Insecure Direct Object References 
A5 Security Misconfiguration 
A6 Sensitive Data Exposure
A7 Missing Function Level Access Control
A8 Cross-Site Request Forgery (CSRF)
A9 Using Known Vulnerable Components
A10 Unvalidated Redirects and Forwards 

Web Security Report 2017

OWASP Top 10
A1 Injection
A2 Broken Authentication and Session Management
A3 Sensitive Data Exposure
A4 XML External Entities (XXE)
A5 Broken Access Control
Merged from A4 and A7 in 2013 list
A6 Security Misconfiguration
A7 Cross-Site Scripting (XSS)
A8 Insecure Deserialization
A9 Using Known Vulnerable Components
A10 Insufficient Logging and Monitoring

Injection

Injection

  • Idea: an attacker sends some input to the server, which is incorrectly interpreted there
    • Data is provided, but is then executed as command(s)
  • Basic problem:
    • Some data originates from an untrusted source (=client)
    • This data is not clearly and completely separated from data originating from a trusted source (=server)
  • Typical examples: SQL/LDAP/XPath queries, OS commands, program arguments, etc.
  • Very common!
    • Mostly also very easy to prevent!
  • The impact may be extremely severe: typically DoS as well as complete modification of all data is possible

SQL injection

  • User input is used as part of the input to a database

  • Typically these are SQL databases today

    • But problem applies to all kinds of DBs,
      DB languages & inputs!

  • Typical examples: Login forms, search forms,
    other forms

  • Commands without permission can be executed

SQL injection

$mysqli->query("SELECT * FROM users WHERE username = '$username' AND password='$hash'");

Username: admin';--

Password: <anything>

SELECT * FROM users WHERE username = 'admin';-- AND password='<hash>'

Sample authentication query:

Username: '; DROP TABLE users;--

Password: <anything>

SELECT * FROM users WHERE username = ''; DROP TABLE users;-- AND password='<hash>'

Wildcards are also useful: %(multi-), _ (single-char)

SQL injection

With SQL injection one can:

  • Impersonate other users and / or gain elevated authentication
  • Delete data without permission
    • E.g. to cause damage or to remove traces
  • Modify data without permission
    • ​E.g modify users' email address and request password reminder afterwards
  • Insert data without permission
    • ​E.g. to gain further authorization

SQL injection

Possible without knowing the table or field names

Username: mate' AND 0<=(SELECT COUNT(*) FROM users);-

Password: <anything>

SELECT * FROM users 
    WHERE username = 'mate' AND 0<=(SELECT COUNT(*) FROM users);-- AND password='<hash>'

Succeeds only if table users exists and is in the current query.

Username: mate' AND users.username = 'mate';--

Password: <anything>

SELECT * FROM users 
    WHERE username = 'mate' AND users.username = 'mate';-- AND password='<hash>'

Succeeds only if table users exists.

SQL injection

Possible without seeing immediate results: blind injection

  • Time delays: query will take a long time if assumption is true
  • Conditional error: error message as a result of the test
    • SELECT 1/0 FROM users WHERE username='admin';
      Error only when such a user exists!

  • Conditional response: result page will be somehow different
  • Such attacks are difficult and time-consuming, but possible!
    • The attacker can usually try for as long as he wants, with automated software, and usually undetected!

SQL injection

  • Always sanitize and escape input
  • Parameterize queries
    • Do not construct queries as string by concatenation
    • Data is automatically escaped
    • Database libraries support this (MySQLi, PDO, etc.)
  • Define model / persistance layer
    • All database communication must go through it
    • E.g. utilize ORM frameworks and their query builders
  • Limit database permissions
    • Each application should have its own DB and user
    • DB users should have least required priviliges
    • DB itself should always be separate user with least privileges

Prevention

SQL injection

Car based

SQL injection

Paper based

XPath injection

xmlobj.selectNodes("//users/admins/[user/text()='$username' and pass/text()='$hash']");
//users/admins/[user/text()='admin' or 1=1 and pass/text()='<hash>']

Same as SQL, but different database: XML files/XML-DB

Disadvantage: Comments are not possible. The query must always be correct as a whole.

Sample original query:

Username: admin' or 1=1

Password: anything

Script injection

Data can also be sent to the application, which might later be interpreted as server-side code, e.g.  as JSP/ASP/PHP code.

  • This is rather rare, as normally the page is compiled/interpreted before user input is involved!
  • Can occur on badly designed dynamic content generation.

Log injection

Logging is very important, but also needs security

  • Attacker injects false log lines
    • Creating false traces or evidence against third persons!
    • Add “\r\n” into the offending input and text looking like a real log line (needs additional information how it should look like)
  • Attacker hides dangerous data?
    • Inserting a null-byte to terminate the logging there
  • Attacker injects scripts
    • When the administrator reviews the log through a browser (web-based administration is common!), the scripts could be executed within his browser through an XSS attack.
  • Automatic log analysis tools can be misused too
    • E.g. banning admin with too many bad login attempts

Mail header injection

The user can enter an email address, to which some data will be sent (recommendation etc.)

Possible input:

"sender@junk.com\nRCPT TO: rec1@org,rec2@org\n
DATA\nSpam message\n.\nQUIT\n"

By just printing the user input as the destination address this will result in a "strange" SMTP session!

Mail header injection

Basic idea:

  • Send data which is then interpreted as part of the protocol to perform
  • Whenever the user enters something which ends up in a protocol, something similar becomes possible

How to prevent:

  • Make sure that the data is ONLY data!
  • And doesn't contain linebreaks, tabs etc.
  • Use mailing libraries.

HTTP response splitting

A complex attack to get a browser to accept a custom-crafted input as a webserver response

  • Requirement: Web server with security problem, target (=browser) interacting with the webserver
  • Objective: get target to send a single HTTP request, which brings the server to answer with a single response, which is interpreted by the target as two separate HTTP responses.
  • Sample problematic code:
response.sendRedirect("/by_lang.php?lang="+request.getParameter("lang"));

HTTP response splitting

HTTP/1.1 302 Moved Temporarily
Date: Wed, 24 Dec 2003 12:53:28 GMT
Location: http://10.1.1.1/by_lang.jsp?lang=English
Server: WebLogic XMLX Module 8.1 SP1 Fri Jun 20 23:06:40 PDT 2003 271009 with
Content-Type: text/html
Connection: Close

<html><head><title>302 Moved Temporarily</title></head>
<body bgcolor="#FFFFFF">
<p>This document you requested has moved temporarily.</p>
<p>It's now at
<a href="http://10.1.1.1/by_lang.php?lang=English">
http://10.1.1.1/by_lang.php?lang=English</a>.</p>
</body></html>

Sending parameter "English":

Source of example based on:

Amit Klein: "Divide and Conquer" – HTTP Response Splitting,
Web Cache Poisoning Attacks, and Related Topics, 2004

HTTP response splitting

HTTP/1.1 302 Moved Temporarily
Date: Wed, 24 Dec 2003 15:26:41 GMT
Location: http://10.1.1.1/by_lang.php?lang=value
Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 19

<html>Attacking content</html>

Connection: Close
<html><head><title>302 Moved Temporarily</title></head>

Sending malicious parameter:

value CR LF HTTP-Headers CR LF CR LF HTTP-Headers CR LF CR LF Arbitrary content
value%0d%0a
Content-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0a
Content-Type:%20text/html%0d%0aContent-Length:%2019%0d%0a%0d%0a
<html>Attacking content</html>

Example:

Response:

Injection

Anything coming from the client might be used as a vehicle for injecting commands or scripts!

Cross-Site Scripting

XSS

Code injection by malicious users into someone else's web
application, to be viewed/executed by end users

The URL is perfectly fine!

  • Browser security features will not help here!
  • Bypasses access controls and same-origin-policy!
  • Encryption (TLS) and certificates will not help at all!

XSS

Server

Client
Attacker

Client
Target

1. Send in malicious input
Typically JavaScript

2. Request webpage

3. Response with malicious code inside

XSS

Reflected: Injecting a script which is “bounced” back

  • Could be reflected by a search result page, some quote, or an error message
  • Can be encoded in the URL
    • So it might be provided from site-externally!
    • Simple to exploit: just bring someone to click on this special link

 Stored: “store” the script on the site

  • Data entered by the user is stored in a DB and "reflected back“ whenever a certain page is accessed
  • Huge multiplication factor: 1 site -> thousands of users!

XSS

XSS can do the following:

  • All is performed as if the code came from a trusted site
  • It can steal cookies and session tokens
  • It can present a login-form
    • With the information entered being sent to the attacker!
  • It can read and change all data on this page
  • It can be used as a proxy, for DoS, or port mapping attacks on the local network or third-party sites

MySpace XSS worm, 2005: 1 million victims in <24 hours!

(Stored XSS, viewing an infected profile was enough.)

XSS

  • Never try to filter out offending content, it just won’t work!
  • Always escape everything you write to the user
    • Escaping the following characters significantly increases security: <, >, (, ), #, &, ", ‘, /
    • Result: no HTML can be embedded at all!
  • Always validate all user input
    • Whitelist: Only accept data exactly matching expected format
  • Cookies: tie to domain / IP address
    • Mark them as HttpOnly, so only server side modification is allowed by modern browsers.

Prevention

XSS

-1: Never insert JS code from another site into your page

  • No matter how you obtain it, as a URL parameter, request response, TCP connection, etc.

Prevention: Rules by OWASP

0: Never insert untrusted data except in allowed locations

  • Directly in a script <script> ... UNTRUSTED ... </script>
  • Inside HTML comments <!-- ... UNTRUSTED ... -->
  • In attribute names <div naUNTRUSTEDme="...">
  • In tag names <di UNTRUSTEDv id= ...>

XSS

Prevention: Rules by OWASP

1: HTML-escape data before putting it into element content

  • <p> ... UNTRUSTED ... </p>
  • Or any other HTML element
  • Minimum escape: & -> &amp; < -> &lt; > -> &gt; " -> &quot; ' -> &#x27; (&apos; is not recommended!) / -> &#x2f;

XSS

Prevention: Rules by OWASP

2: Attribute-escape data before putting it into attributes

  • Does not apply to href, src, style, event handlers: see Rule 3!
  • Double quoted: <div attr=" ... UNTRUSTED ... ">
  • Single quoted: <div attr=' ... UNTRUSTED ... '>
  • Unquoted: <div attr= ... UNTRUSTED ... >
    • Should not be used anyway!
  • What to escape: all ASCII codes below 256 -> &#x??;
    or named entity
    • Excluding alphanumeric characters (A-Z, a-z, 0-9)

3: JavaScript-escape data before putting it in JS data values

  • Especially: href, src, style, event handlers
  • Some functions are never safe (which takes a string and makes code from it / executes it)

XSS

Prevention: Rules by OWASP

4: CSS-escape data before putting it into style values

  • <style> selector { property : ... UNTRUSTED ...; } </style>
  • <style> selector { property : "... UNTRUSTED ..."; } </style>
  • <div style=property : ... UNTRUSTED ...;> text </div>
  • <div style=property : "... UNTRUSTED ...";> text </div>
  • What to escape: see Rule 2!

5: URL-escape data before putting it into URL parameters

  • <a href="http://site.com?param=...UNTRUSTED...">link</a>
  • What to escape: see Rule 2!

XSS

Prevention (PHP example)

Hello <?php echo $view->escape($name) ?>
var myMsg = "Hello <?php echo $view->escape($name, 'js') ?>";
Hello <?php echo htmlspecialchars ($name) ?>

HTML escaping with native PHP:

Most MVC frameworks have advanced solutions, e.g. with Symfony:

View templates can also support escaping, e.g. with Twig:

Hello {{ name }}
Hello {{ name|escape }} <!-- HTML escaped (htmlspecialchars) -->

JavaScript context escaping:

var myMsg = "Hello {{ name|escape('js') }}";

By default Symfony turns on autoescape for Twig.

XSS

Prevention (C# example)

By default, in a ASP.NET Core webpage using the Razor view engine HTML encodes all output with the @ syntax:

Hello @("<em>Mate</em>")!

Hello &lt;em&gt;M&#xE1;t&#xE9;&lt;/em&gt;!

We can deliberately request HTML encoded or raw HTML output with the HTML helper class:

Hello @Html.Raw(ViewBag.Name)!
var name = "@JavaScriptEncoder.Default.Encode(ViewBag.Name)";

JavaScript context escaping:

Cross Channel Scripting

Cross Channel Scripting

  • Involves two protocols
  • Example:
    • Create a torrent file with a real content +
      an additional attacking file
      • Filename is actually a script
      • <iframe onload="...">real-content.pdf</iframe>

    • Seed it to big trackers
    • Users download the file
    • When the content is shown in a webbrowser,
      e.g. in the UI of a NAS system, this script is executed

Cross-Site
Request Forgery

CSRF - Big Picture

Server

Attacker

Target

2. Send malicious code
E.g. a mail with a dangerous URL as an image

1. Login to site

3. Execute command as a logged in user

CSRF - How it works

  • An innocent third person is instrumented to carry out a specific attack against a web server.
  • The third party is lured to a webpage (or sent an email), on which he/she will click on a link ( HTTP request) or which employs JavaScript.
  • The script/link inherits the third party's identity and privilege, and executes an request

    • E.g. cookie, cached logon credentials, IP address, client-side SSL authentication, etc.

  • The server cannot distinguish this from a real request: All the necessary credentials and permissions are ok!

CSRF - Trivial example

  • The third party is logged into the web application
  • This application requires a login and stores a cookie on the clients computer, which is then used for session state
  • One legitimate action there is filling in a form (resulting in a GET request) to delete a record
    • GET /deleteRecord?id=15

  • The attacker sends an email with the following link (HTML):
    • <a href="http://www.app.com/deleteRecord?id=13">Click here for the free iPhone app</a>!

  • If the third party is logged into the application and clicks on the link, the cookie is sent automatically by the browser and a record is deleted
  • If the third party is not logged in, nothing happens (e.g. login page or error message shown)

CSRF - Types of attack

CSRF attacks can be instrumented in different forms:

  • Most dangerous: Attack stored on attacked website itself
    • Users will be logged in, users will go there willingly
  • Less dangerous: On a random website
    • One need to get users to view website and perhaps initiate some action
  • Least dangerous: In an email
    • One must get the user to click on a link in the email (involves some kind of social engineering!)

CSRF - Attack vectors

  • Images instead of links: will be requested automatically
    • Note: answer doesn’t need to be an image!
  • URL shorteners: to hide the actual target
    • Makes it easier to get people to click on it
    • Some services (try to) check for such attacks
  • URL spoofing: http://www.app.com@fakeapp.com
    • Link leads to site fakeapp.com, not www.app.com!
  • Put the links in hidden frames: result pages do not appear
  • Use JavaScript to construct URL arbitrarily
    • Same origin policy restricts possibilities

CSRF

Users are performing actions which they are authorized to do and must be able to do!

  • Still, some precautions exist!
  • Aim: users should only ever perform an action if they know that they are performing one, and which one.

Problem statement

CSRF - Prevention

  • Using secret and very secure cookies
    • The cookie is sent, because it should be sent there!
    • Applies also to all other credentials, since the problem is the voluntariness, not the origin!
  • Accepting only POST requests
    • Attackers can use scripts
    • Attackers can put hidden values in voluntarily submitted forms; while the third person thinks, that the form will do something completely different

What will not necessarily help

CSRF - Prevention

  • Multi-step transactions: requiring several clicks, forms, etc.
    • As long as the sequence is known or predictable, this won’t help, it just renders the attack more complex and longer.
    • E.g. series of hidden iframes submitted by JavaScript.
  • Checking the referer header: accept only input from your site
    • Does not help if attack stored on that page
    • What to do with empty referers?
      • These occur quite often (privacy!)
        E.g. none is sent over HTTPS
  • URL rewriting: putting the session ID into the URL
    • Opens up numerous other problems: Bookmarks don’t work any more, the (secret!) session ID is shown publicly

What will not necessarily help

CSRF - Prevention

  • For each page a new form field value (token/nonce) is generated
    • Only if this value is present and correct, the request originated from correct page and should be honoured
      • Note: will not protect against attacks stored on your site!
  • This token must be
    • Really random: else they can predict the value and add it
      (cryptographically secure random)
    • Tied to the session: else they fetch their own and substitute it
    • Expire soon: Limit exposure windows
    • Secured: use TLS for communication

By Token

CSRF - Prevention

  • Potential problems:
    • Open two forms in two tabs: will both still work?
    • Bookmarking result pages?
    • Back button?

  • Sometimes therefore only session-duration tokens

    • Like session ID, but sent with every link and form submission

  • Potential weakness: leaking the token, esp. in GET requests

  • Possible solution:

    • Send the token in POST requests only

    • Only ever use POST requests for data modifying operations

By Token

CSRF - Prevention

  • Use Captchas – for every single request
    • Similarly: Require login for each request
    • Similarly: Require one-time tokens for each request
  • This is very secure - but not exactly user-friendly!
    • Can be used for very important or dangerous actions
    • Can be used in a commit-rollback model
      (see online banking)

Further measurements

CSRF - Prevention

Users should:

  • always immediately log off after using the app
  • always use only a single app simultaneously
    • no tabbed browsing, no multiple browser windows
  • never switch applications (to email, another site, etc.)
  • always enter links manually/through bookmarks
  • always check the full link on link-shortening services
  • never cache usernames/passwords
  • never allow sites to remember you (long-duration cookies)
  • disable JavaScript (or use plugins like NoScript)

User-related prevention

Problem: this is not very dependable or user-friendly

  • This MUST be protected against by the web site
  • Users CAN mitigate the risk, but it is complex and burdensome

CSRF - Prevention

MVC frameworks

Controller:

public function newAction(Request $request)
{
    $form = $this->createFormBuilder() // adds CSRF token
        // ...
        ->getForm();

    $form->handleRequest($request); // validates CSRF token

    if ($form->isSubmitted() && $form->isValid()) {
        // perform some action...

        return $this->redirectToRoute('success_action');
    }

    return $this->render('form.html.twig', array(
        'form' => $form->createView(),
    ));
}
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }} {# adds CSRF field #}

View

Most MVC frameworks nowadays support integrate CSRF protection for forms. E.g. integrated into Symfony's form builder:

CSRF - Prevention

MVC frameworks

Controller:

public function newAction(Request $request)
{
    $token = $request->request->get('_csrf_token');
    $csrf_token = new CsrfToken('form_name', $token);

    if ($this->isCsrfTokenValid('token_id', $csrf_token )
    {
        // ... do something
    }
}
<form action="..." method="post">
    {# ... the normal fields #}

    <input type="hidden" name="_csrf_token"
        value="{{ csrf_token('token_id') }}"
    >

    <input type="submit">Submit</input>
</form>

View

Try no to subvert the integrated solution. If you must, it is your responsibility to handle CSRF protection:

CSRF - Prevention

MVC frameworks

Controller:

[HttpPost]
// only process POST request
[ValidateAntiForgeryToken]
// defence against XSRF
public IActionResult SomeAction(
  Int32 id, SomeViewModel vm)
{
  // ...
}
<form asp-action="Index" asp-route-id="@Model.Id">
  @* Field for XSRF token will be inserted here *@
  @* ... *@
</form>

View:

As another example, in ASP.NET Core MVC framework, forms are automatically extended with a CSRF token:

<form method="post" action="Something/Index/42">
  <input name="__RequestVerificationToken"
         type="hidden" value="{token}" />
  @* ... *@
</form>

Can be disabled with the asp-antiforgery server-side processed HTML attribute.

XSS + CSRF

An attack can use XSS to obtain the token needed to work around CSRF protection!

Sensitive Data Exposure

Error messages

  • Web applications usually report detailed information on errors encountered during their execution
    • This is a significant information leak!
    • No vulnerability itself, but allows deducing/exploiting others!
    • Attackers may gain a lot of information
      • Disk layout (paths), Database layout (tables, queries), Stack traces, "File not found" vs. "Access denied"
  • But this information is often indispensable for finding the problems (bug-fixing by programmers, but also help lines!)

Error messages - Bad practices

  • Local file/path names: allows predicting where a file would
    be physically (important for blind attacks!), OS, etc.
    • Backups, temporary files, configuration files, etc.
  • Server configuration
    • E.g. phpinfo() shows detailed information on what modules are installed, version numbers, paths, etc.
  • Environment values: Path, security settings, OS, etc.
  • Too exact time: can be important regarding cryptography
  • Query structure (SQL): table/column names, exploitable query structure, missing quotes, etc.
  • Comments left in the public part
    • <!-- TODO: Fix security issue here -->

Error messages - Bad practices

  • Error page with information in URL
    • http://www.insecure.com/errors.php?Error=Login%20failed
    • You can also inject some script + send the link to someone!
  • Stack traces: internal program structure
  • Support forums
    • There a lot of (internal!) information might be posted looking
      for help, e.g. full stack traces not visible from the outside, IP
      addresses, part of program code, etc.
    • Make sure to anonymise them properly – including yourself!

Error messages - Good practices

Error messages should include the following information:

  • That a problem occurred
  • Why the problem occurred
  • How to fix the problem

But in terms of the user, not of the developer!

  • No technical internals (why, how)
  • Better too little information than too much
    • Example: don’t tell that the password was wrong, instead "username/password could not be validated"

Error messages - Good practices

  • Provide two versions of error message display
    • For debugging turn all output options on
      • Or use a development environment with
        auto-break on errors, etc.
      • Show as much information as you need/want
    • For release turn all output options off!
      • Make sure to use a framework and a generic solution
      • Individual solutions will be forgotten somewhere
  • Ensure that public versions always use the release version
  • Use a logging framework
    • Allows centralized logging in various details

Error messages - Good practices

  • The output page may not include any offending user input or
    any internal data
    • XSS reflection vulnerability/information leak!
    • This may also include exception messages
  • Should always look exactly the same!
    • Small differences is again information disclosure!
    • E.g. on a password recovery page showing "password was
      sent"
       or "Username/Email was invalid" allows testing for valid account names or email addresses
  • Detailed information should be logged
  • Don’t provide internal contact information in messages
    • Or any information usable for social engineering

CSS hacking

Cascading Style Sheets: Describe how to show web content

  • This doesn’t sound very dangerous ...
  • But CSS may contain JavaScript code (e.g. in IE or FF)
    • <div style=xss:expression(alert('Attack!'))>Test</div>
  • Also CSS display alone might be interesting

CSS hacking: Clickjacking

  • On the page is a form
  • On top of the form is something different (CSS)
  • The user clicks on the top-most element, but in the moment of clicking it is removed and the user clicks on the form below (works also for key presses!)
    • Slight variation: In the moment of clicking a different layer is brought to the top, so the user clicks on this instead
    • Slight variation: completely cover the whole page with different content, except the small area with the submit button

UI redressing - How it works

CSS hacking: Clickjacking

  • Attacker can bring the user to "voluntarily" click on a
    button, e.g. ordering something, confirming a warning,
    sending the information in the form somewhere else, etc.
  • Real-world scenarios:
    • buy something
    • enable webcam/micro-phone
    • follow someone on Twitter
    • share links on Facebook
    • making a social network profile public
    • etc.

UI redressing - Results

CSS hacking: Clickjacking

  • Make sure your frame is the most top-level one
    • Continually all the time, not just at the beginning!
    • Use framebuster / framekillers scripts
      • There are ways around them
  • Send response headers to the browser, indicating that you
    don’t want to be framed
    • Implementation: Originated with IE8
      • Firefox: 3.6.9, Opera 10.50, Safari 4.0, Chrome 4.1.249
    • X-FRAME-OPTION header: DENY or SAMEORIGIN
    • Drawbacks:
      • Proxies might strip this header
      • No whitelisting possible

UI redressing - Prevention

CSS hacking: Tapjacking

Especially vulnerable: Mobile phones (tapjacking)

  • Older phones don’t support JS -> No framebusting scripts
  • Zooming: Allows to "blow up" buttons so they will definitely be targeted, wherever the user taps
  • Hiding/faking the URL bar: Scrolling the window removes the URL bar; put a "correct" image at that position
  • Create "popups", e.g. SMS notification through HTML
  • Many mobile browsers don’t delete session cookies on closing the browser -> servers use longer session timeouts

CSS history stealing

  • Investigate which URLs a user visited, e.g. for targeting exploits (which cookies to steal, what site to impersonate, etc.)
    • Works only for fixed lists of URLs
    • These can be as long (and each URL as complex) as desired
  • With JavaScript:
    • Load a document with thousands of URLs into a hidden iframe and inspect their style
    • If they were visited, their colour is different
    • Pass the list of visited domains back to the server (e.g. AJAX)
  • Without JavaScript:
    • Load links as above and mark each one with a different class
    • #menu a:visited span.class1 {
      background: url(save.php?visitedLink=1); }

Insufficient transport layer protection

  • Passwords may be secure and securely stored, but they are sent from the client to the server in cleartext
    • Or password reminder emails contain cleartext password
    • Monitoring the network traffic is not that difficult ...
      • You never know how your clients will access the server: they could be using an unencrypted WLAN, etc.
    • If monitoring is possible, modifications might also be an option: injection, man-in-the-middle attack, etc.
  • Typical problem: TLS is used for the login, but not afterwards
    • Result: the password is secure, but the session-ID/-cookie can be stolen easily
    • Impersonation of this user is possible

Insufficient transport layer protection

  • All authenticated traffic must use TLS
    • Home page: No
    • Login page: Yes
      • Login form itself must be SSL, not only the submission!
      • Otherwise a script could be injected to send the password to an attacker!
    • All pages after the login page until successful logout: Yes
  • Session cookies must have the "secure" flag set
  • The server should have an appropriate and valid certificate
  • SSL/TLS may cause performance issues, as it requires much more CPU power
    • For sites with many visitors this can be a real problem!

Prevention

Insufficient transport layer protection

  • This applies to the frontend: Client/Browser <–> Server
  • But check the backend too!
    • Is the webserver connected through a dedicated single cable to the DB server?
      • Or how would it be possible to listen in on this traffic?
    • Internal attacks by employees are always possible
      • If you fully trust them: What about an internal PC infected with malware, acting as a network sniffer?

Prevention

Insecure Direct
Object Reference

Broken Access Control

Insecure direct object reference

  • Precondition: Authorized system user
  • Attack: Changing a parameter which signifies some object
    • For which this user is not authorized!
  • Problem: user can still access this object

Insecure direct object reference

  • Basic idea:
    • Object access is verified on page generation
      • E.g. only those IDs are listed, which the user is authorized for
    • The object ID is passed as a form parameter
      • Actual name, key, number etc.
    • Validated whether user is generally authorized (=logged in)
    • It is NOT validated, whether the user may access this object when he/she actually accesses it!
  • Result: access to some object + knowledge of the ID =
    access to any object
    • Note: one can e.g. just try all possible IDs!

Insecure direct object reference

  • Some input is used to construct a path name, which should
    be underneath a certain parent directory
  • Basic issue: the user can specify a resource (the path)
    directly (through its name)
  • Example:

    • $path="/var/users/profiles/" . $_GET["user"];

    • Pass in "../../../etc/passwd"
    • Results in sending "/var/users/profiles/../../../etc/passwd"
      Which is actually "/etc/passwd", i.e. all passwords/users!

Path traversal example

Insecure direct object reference

  • Ensure protection for every user-accessible object
    • This includes every resource, not only programming-objects (documents, pictures, etc.)
  • When no direct user authentication is enforced, the problem can be mitigated: use long and random (cryptography) IDs
    • Makes it difficult (but not impossible!) to guess valid IDs

Prevention

Missing Function Level
Access Control

Broken Access Control

Malicious file execution

  • A file is placed on the web server (or already there) and executed at the request of the attacker
    • Typically a problem of PHP, but not tied to it
    • Even more dangerous: Remote malicious file execution
  • Basic problems:
    • Some unverified input is used for file or stream functions
      • Any kind of parameter which will be used as part of a filename
    • Uploaded files are not checked sufficiently
      • Upload images, but what if the image is called index.php?
  • Result: Remote code execution
    • Installing a rootkit, executing arbitrary code exactly as the web application can, call OS functions, etc.

Malicious file execution

  • An XML file is uploaded, which contains a remote DTD
    • This remote file is loaded by the XML parser and interpreted
    • Allows remotely exploiting flaws in XML processors
  • Include statements contain parameters
    • include $_REQUEST['filename’];

  • Uploaded files are written to the disk
    • Check to not overwrite something important
    • Make sure to use acceptable file names
  • Some commands can be uploaded
    • Upload a MS Office document and get it to being opened on the server
    • Macros will be executed!

Examples

Malicious file execution

  • Virus scanning
    • To make sure you won’t distribute anything dangerous
  • Size checks
    • Prevent DoS attacks as well
  • File type verification
    • Extension verification alone may not be sufficient!
    • Adding the correct extension may not be sufficient!
      • Send the filename "attack.php%00" -> "attack.php\0.jpg"
      • Results in the desired filename, as the zero byte (\0) is the string termination many languages!

Prevention

Malicious file execution

  • Use a mapping for determining files to execute
    • Don’t pass filenames to the client, but only their index in a server-side mapping
  • Use server-determined random names for uploads
    • Includes path sanitation/canonicalization/checks
    • Make sure everything is uploaded to a safe base directory
  • File system access control rights
    • Upload directory: Read & Write, No Execute

Prevention

Failure to restrict URL access

  • Some access protection (e.g. username+password) exists, but "protected" pages can be accessed by knowing their URL
    • "Secret" URLs (security by obscurity) are not a protection:
      • The login status must actually be verified!
    • Same applies to different authentication levels:
      If you are a normal user, can you access administrative pages when knowing their URL?

Failure to restrict URL access

  • Use a framework for authentication and authorization
    • Preferably role-based (or: groups) to reduce administration
    • Authorization should be in the business logic layer (controller); not in the presentation (view)!
  • Whitelist pages which can be accessed by default
    • Not blacklist the ones which require authentication

Prevention

XML External Entities

XML External Entities

  • By default, many older XML processors allow specification of an external entity, a URI that is dereferenced and evaluated during XML processing.
  • Attackers can exploit vulnerable XML processors if they can upload XML or include hostile content in an XML document, exploiting vulnerable code, dependencies or integrations.
  • These flaws can be used to extract data, execute a remote request from the server, scan internal systems, perform a denial-of-service attack, as well as execute other attacks.

XML External Entities

The attacker may extract data from the server:

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>

The attacker may probe the server's private network:

<!ENTITY xxe SYSTEM "https://192.168.1.1/private" >]>

The attacker may attempt a DOS attack by including an endless file:

<!ENTITY xxe SYSTEM "file:///dev/random" >]>

Examples

XML External Entities

  • Whenever possible, use less complex data formats such as JSON.
  • Patch or upgrade all XML processors and libraries in use by the application or on the underlying operating system. Use dependency checkers.
  • Disable XML external entity and DTD processing in all XML parsers in the application.
  • Implement positive ("whitelisting") server-side input validation, filtering, or sanitization to prevent hostile data within XML documents, headers, or nodes.
  • Verify that XML or XSL file upload functionality validates incoming XML using XSD validation or similar.

Prevention

Invalidated Redirects and Forwards

Invalidated
Redirects and Forwards

  • The user is redirected to another page, but the target of the redirection is not adequately verified (invalidated), so an arbitrary target can be specified
  • Typical uses:
    • Present users with a link to a reputable site, but use the redirect problem on that site to send them to an attacking site
    • <a href="http://www.good.com/redirect.php?url=www.evil.com">Go to good.com</a>

    • Trying to get the users' trust to enter some data (phishing)
  • Often combined with exploits where viewing a page (which users would hardly visit by intention!) is sufficient for infection

Invalidated
Redirects and Forwards

  • Do not use redirect and forwards
    • If you need to direct to another page, do this on the server and just render a different content
  • Do not use any parameters when redirecting
    • Use a server-internal state for deciding the target
    • The server and only the server should decide the destination!
  • If unavoidable
    • Sanitize/canonicalize the parameter to check whether it is valid (e.g. only relative paths, etc.)
    • Check that the user is authorized for the destination
    • Use a mapping value instead of URLs or path elements

Prevention

Broken Authentication and
Session Management

Session management

  • Session hijacking
    • Impersonate someone by stealing their original session
  • Session fixation
    • Impersonate someone by "sharing" your initial session with them (without their knowledge)
  • Session prediction

Session hijacking

  • Stealing the victim's session ID through an exploit
    • For example with an XSS attack
  • Impersonating the victim
    • The victim can be a targeted user with elevated permissions, like an admin

Session fixation

Server

Attacker

Target

2. Send session ID to victim, e.g. in a URL

3. Log in
Using this session ID

1. Start new session
Receive a session ID

4. Use site
With shared session of the victim

Session fixation

Basic idea:

  • You get the victim to use a specific session ID
  • As you know this ID, you can access the web application exactly as the user could do

Prevention:

  • Invalidate session before checking
    username + password
  • MUST assign new session ID on success
  • CAN assign new session ID on failure

CAPTCHA Re-Riding

Basic idea and premises (often existing!):

  • Access control through CAPTCHA, e.g. for creating accounts
  • One manual solution can be reused for several requests
  • Captcha is generated and solution stored in session
  • Solution is not removed from session during its verification

Exploit:

  • Solve CAPTCHA manually
  • Intercept this request with a proxy
  • Submit request several times, replacing the user name, id (and all other unique values) with new values

Prevention: remove CAPTCHA solution from session
after verification

Session state on client

  • The session state should always be only on the server side
    • But what about load balancing and event-based servers?
    • Can we store the session state on the client – securely?
  • Yes, but only partially!
    • Everything should be stored on the server (too)
    • We send the session state to the client
      (Potentially encrypted and compressed.)
    • The client sends it back with the request to use
    • We recreate the session from the request and answer it
      • If recreating the session failed, e.g. because of tampering on the client, we retrieve the version stored on the server or start a new session
      • Advantage: stored on server is only a backup and might take long to access, but usually we take the fast one from the client

Session state on client

Ensuring integrity of session information sent from client

  • Digital signature: create session data, sign it, send to client,
    verify signature when received
    • Works, but requires a lot of computing power, so can be slow
  • Hash value: create hash from session data, send to client,
    receive session state, calculate hash and compare to stored
    • We need to store only the hash value, but falsifying might be relatively easily possible (NOT recommended)

Session state on client

Ensuring integrity of session information sent from client

  • Cryptographic hash value: create session data, concatenate
    secret value, create hash value from result, send/receive
    data+hash to/from client, concatenate secret value to data
    received, create hash, check for identity with submitted hash
    • We don’t even have to store the hash value on the server
    • Falsification is extremely difficult
      (secret would have to be recreated from hash!)
    • Load balancing: all systems must share secret – Nothing else!
    • E.g. Yii 2 has this solution integrated by default
  • This protects the state from tampering
    • The data is visible and readable to the client
    • Never put confidential information into the client state!

Security Misconfiguration

Insecure cryptographic storage

If you do some encryption, the data is probably quite important

A bit of encryption is worse than no encryption
False sense of security!

Insecure cryptographic storage

  • Do not implement your own cryptographic library
  • Never invent your own algorithm
    • Use only known good algorithms
    • Make sure the algorithm can be changed (securely!) easily
  • Enforce password/key strength and use salting
    • Cryptographically-secure random number generators should be used
  • Protect important data against unauthorized access

Insecure cryptographic storage

Example: insecure password storage

Password

Password

Password

Hash

No cryptography

Cryptographically
insecure hash function

In case of a database intrusion and password table leakage the information can be easily utilized:

  • e.g. Google for "md5 rainbow table" to reverse engineer all md5 hashes 

Insecure cryptographic storage

Example: secure password storage

Password

Hash

Hash 1..N times

Salt

User

CSPRNG

Salt

Store

Use strong hashing algorithms, like SHA-512.

Bombs

  • A kind of Denial of Service (DoS) attack
    • Against CPU, memory, storage space, etc.
  • ZIP/XML bombs: Submitting content which, when checked or to be rendered, consumes huge amounts of resources
    • XML file with an entity -> this entity expands to ten further entities, which again expand to ... -> Exponential growth!
    • Example: 4.5 PetaB file can be compressed to 42 kB ZIP
    • Alternatives: requiring huge amount of time, disk, memory, downloading huge external data, connecting to other company-internal servers, etc.

XML Bomb

<?xml version="1.0"?>
<!DOCTYPE lolz [ <!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;"> ]>
<lolz>&lol9;</lolz>
  • Well-formed, valid, etc.
    • Actual size: <1 kB
    • Expanded: 100.000.000 times “lol”
  • Alternative: including external references
    • <!ENTITY data SYSTEM "http://www.evil.com/bomb.htm">
    • Will connect to this website on each parsing
    • Can also be a movie (=huge) somewhere!

Bombs

Ensure that the resources any web request may use are
limited in various ways

  • Time
  • Size
  • Memory
  • External

Prevention

Cryptographic problems

  • Deriving PRNG seed mt_rand from PHPSESSID
  • PHPSESSID =
    md5(client IP . timestamp . microseconds1 . php_combined_lcg())
    • php_combined_lcg() has two seeds
      • S1=timestamp XOR (microseconds2 << 11)
      • S2=pid XOR (microseconds3 << 11)
    • Values:
      • client IP: Attacker knows it
      • timestamp: Disclosed in HTTP header; own clock (NTP!)
      • microseconds1: 0-1000000
      • microseconds2: microseconds1 + 0…3
      • microseconds3: microseconds2 + 1…4
      • pid: Process id of current process; 0…32768

Weak random number generation

Cryptographic problems

  • Result: Brute-force is possible: only PID and microseconds!
    • Doable: Amazon EC2 GPU instance: 7,5 min
      (So the session is most likely still alive ...)
  • Reason: cryptographically insecure random number generation
    • rand() is insecure
    • mt_rand() is insecure
    • random_int() is secure (available since PHP 7)
      • or use third-party library

Weak random number generation

Using Known Vulnerable Components

Using Known Vulnerable Components

Using obsolote, vulnerably third-party libraries, because:

  • Developer is not aware of patch
    • Does not follow releases
    • No automatic security update mechanism is enforced
  • Developer is aware of patch
    • ​Updating would imply "too much" cost
  • Library is not maintained

Using Known Vulnerable Components

Prevention:

  • Use package manager and regularly update used packages with security updates.
    • E.g. Composer for PHP (used also by Symfony).
    • Utilize version constraints to keep main version.
  • Drawback: retesting of the application.
    • Automatize testing.

Social Engineering

Social Engineering

Kevin D. Mitnick: The Art of Deception

Perfect security?

DNS redirect attack

  • Attack domain name registry
    (either by technological or by social engineering).
  • Modify the DNS records of an existing webapplication to own, fake addresses.
  • Copy the website (and possibly also the web services!) of the original company to make visitors believe they are still on the correct website.
    • Enough to copy the public interface, e.g. show maintenance error messages after authentication.
    • With a convincing UI and a valid SSL, visitors will have no chance to realize they are being scammed.

DNS redirect attack

  • NIC.br, the top level, national Brazilian domain registrar was hacked in 2016.
  • A DNS redirect attack was carried out against a major Brazilian bank (all 36 domains).
  • Customers were redirected to a pre-established fake website hosted in the Google Cloud with valid SSL.
    • ​Personal information, bank account numbers and cleartext passwords were compromised.
    • Even ATM machines sent security sensitive information (card numbers and PIN codes) to the hijacked services.
  • ​The hackers owned the domains for 5 hours!

Web Security

By Cserép Máté

Web Security

Injection, XSS, CSRF, Sensitive Data Exposure, CSS hacking, Broken Access Control, Insecure Direct Object Reference, Missing Function Level Access Control, XML External Entities, Invalidated Redirects and Forwards, Broken Authentication and Session Management, Security Misconfiguration, Using Known Vulnerable Components

  • 535