HTML5 - AppCheck-NG

HTML 5
HTML 5
• HTML 5 introduced a host of new APIs and features such
as:
•
•
•
•
•
•
•
•
Cross origin messaging (postMessage)
Extended Cross Origin Resource Sharing (CORS)
HTML Geolocation
HTML Drag and Drop
HTML Local Storage
HTML Application Cache
HTML Web Workers
HTML SSE
HTML 5
• Our focus is on features that introduce a potential security
vulnerability.
• For the purpose of this presentation we will concentrate
on Cross Origin Communication through both
postMessage and CORS.
Tech Recap
Authentication & Session
Cookies
Technical Recap: Auth
• Typical user authentication process:
Username & Password
Session ID
Set-cookie: ASPSESSIONIDCQQABSAT=KJAFFLJCAF..
Technical Recap: Auth
• Upon successful authentication the application allocates a
session token (cookie) to the user.
• Subsequent requests include this session token within the
cookie header to allow the server to identify the user.
cookie:
ASPSESSIONIDCQQABSAT=KJAFFLJCAFND
NEGBICHJFPHM
Technical Recap: Auth
• Session ID’s are valuable to the attacker since they can be
used to access the users account for the duration of the
active session.
• Browsers will automatically submit the cookie to the target
application for each request.
• Requests triggered to the target application from a
malicious web page will contain the session token, though
the same origin policy prevents the malicious web page
from reading the response.
Tech Recap: SOP
• The cookie containing the Session ID can usually be read
using JavaScript loaded in the same origin.
• The HttpOnly flag helps prevent this by making the
cookie for network use only.
The Same-origin policy
Tech Recap: SOP
• Classically, browsers constrain bi-directional network
requests to the “same-origin”.
• In simple terms, this means a script running within a given
page can only make HTTP requests and process responses
between hosts that have the same;
Protocol, Port and Hostname
http://www.example.com/
Compared URL
Outcome
Reason
http://www.example.com/dir/page.html
Success
Same protocol and host
http://www.example.com/dir2/other.html
Success
Same protocol and host
http://www.example.com:81/dir/other.html
Failure
Same protocol/host but different port
https://www.example.com/dir/other.html
Failure
Different protocol
http://en.example.com/dir/other.html
Failure
Different host
http://example.com/dir/other.html
Failure
Different host (exact match required)
http://v2.www.example.com/dir/other.html
Failure
Different host (exact match required)
Tech Recap: SOP
Cookie: SESSION…
Blocked by SOP
A malicious website can trigger a
request to a trusted site, but it cannot
read out the response (unless CORS
permits it)
Tech Recap: SOP
• JavaScript also adheres to the same rules when working
with frames loaded in the page and sensitive data such as
cookies.
• i.e. An IFRAME loaded in the page cannot be read from or
written to unless it lives within the same origin
Tech Recap: SOP
Parent and child have the same origin;
http://frames.appcheck-ng.com:8000/
Tech Recap: SOP
Parent and child have different origins, access is denied;
Parent:
http://frames.appcheck-ng.com:8000/
Child:
http://frames_two.appcheck-ng.com:8000/
Tech Recap: SOP
However, sometimes cross domain communication is
desirable or required by the business.
Tech Recap: SOP
• Applications that span multiple domains may need to
share data but do not have the ability to share the same
server side session information.
Tech Recap: SOP
• Components loaded from sites such as YouTube.com or
FaceBook.com need to communicate with their parent to
embed media content and provide social media features.
Tech Recap: SOP
• Before HTML 5, a number of hacks were implemented to
allow communication between origins.
• Two common techniques include JSONp and passing data
to a child IFRAME via the URI fragment
• JSONp although convenient, has no built in security and
confidentiality had to be manually enforced through the
use of server side anti-CSRF tokens.
• JSONp: http://en.wikipedia.org/wiki/JSONP
Tech Recap: SOP
• HTML5 Addresses this problem through postMessage and
Cross Origin Resource Sharing (CORS)
window.postMessage()
postMessage
• postMessage is an API provided by the browser that allows
message to be sent between origins.
Sending Message From:
http://www.appcheck-ng.com
Data: Hello Word
Message Received From:
http://www.appcheck-ng.com
Data: Hello Word
postMessage
• Our parent page registers an event listener to process
messages it receives.
• An alert box is displayed if we receive a message.
Receiving the message
• When a message is received, the message “Event” is
passed to receiveMessage()
• recieveMessage() reads the event.origin and
event.data values to display in an alert box
Sending the message
• Our child IFRAME sends a message to its parent:
postMessage
postMessage security
• Post message security within the receiving page is based
on the validation of the event.origin property.
• It is the responsibility of developer to securely validate the
origin of the event before processing the message payload
(event.data)
• Messages can be sent to the receiving page from both
embedded IFRAMES and by opening the page using
window.open()
window.open()
• Example:
var c = window.open("http://www.google.com","child");
c.postMessage("Hello Google","*");
• In most cases we wont control IFRAMES loaded in the page
and therefore window.open() is more useful to the
attacker.
Sender Security
• When sending a message containing sensitive data, the
developer must ensure it is being sent to the expected
location.
postMessage(MESSAGE, TARGET)
• A wildcard value * can be used to send to all origins:
postMessage("Hello", "*")
Vulnerabilities
• postMessage vulnerabilities broadly fit into
two categories:
• Pages that disclose sensitive information by
posting data to the “*” wildcard target, or an
target that the attacker can control.
• Pages that process data from any origin
insecurely, allowing Cross Site Scripting Attacks
Case Study
• To understand postMessage vulnerabilities lets work through a
case study example based on a real world vulnerability.
“…. AppCheck has decided to integrate its social media site Facepalm into
it’s online shop allowing users to receive notification messages within the
site.
Facepalm was acquired by AppCheck and runs on different infrastructure
and on different domains;
http://shop.appcheck-ng.com
http://messages.facepalm.com”
Case Study.
• To receive notifications the user must first be
authenticated to Facepalm
Case Study
• Notifications from Facepalm are integrated into the
AppCheck Shop (shop.appcheck-ng.com)
Receiver side (Shop)
• Facepalm provides a JavaScript import to allow embedding
of message notifications within external domains.
• A message handler “receiveMessage()” is added as
before:
window.addEventListener("message", receiveMessage, false);
Facepalm IFRAME Message
• Message Sent from the Facepalm IFRAME
parent.postMessage(
{"username": "gary",
"messages": [
{"message": "Your order has been
dispatched",
"title": "Amazon Order Shipped
#2089128387 Bloodborne
PS4"
}]
},"*")
• The receiveMessage() function reads in this message
and populates the page. First setting the username:
{"username": "gary",
function receiveMessage(event){
data = event.data;
...
name_div.innerHTML = "<b>Welcome: </b>"+ data.username;
...
• Next, the script iterates over messages embedding them
within the page;
{"title": "Amazon Order Shipped
#2089128387 Bloodborne.
messages = data.messages;
for (var i = 0; i < msg_length; i++) {
message = messages[i];
msg_html += "<h2>" + message['title'] + "</h2>";
msg_html += message.message;
}
messages_div.innerHTML = msg_html;
Final result
Vulnerabilities
• There are two vulnerabilities here.
• First, the script embedded within our shop does not check
the origin of the message event before writing message
data to the page.
Since data from our message is set using innerHTML, the
attacker is able to embed any data including JavaScript.
Exploit Example
Demo
Cross Origin Message
Demo
• The second vulnerability is that the Facepalm frame
discloses sensitive information to any site that frames it.
parent.postMessage(
{"username": "gary",
"messages": [
{"message": "Your order has been
dispatched",
"title": "Amazon Order Shipped
#2089128387 Bloodborne
PS4"
}]
},"*")  Posts to all targets
Exploit Example 2
• A common vulnerable pattern found on a postMessage
enabled sites is the use of a parameter to define the target
origin.
Example:
http://messages.facepalm.com/postmessage/
inner_frame?origin=http://www.google.com/
Resulting in:
parent.postMessage({msg},"http://www.google.com/");
Detecting postMessage
• AppCheck NG Tracks postMessage usage using our custombuilt web browser engine
• Vulnerabilities such as those outlined in this presentation
are detected through static analysis of the handler code.
AppCheck NG
All messages are captured
and verbose technical
information is reported to
aid manual review.
AppCheck NG
• Detection of postMessage security flaws
Defence
• Defending against postMessage flaws:
• Validate message origin to ensure it originated from a trusted
location (event.origin).
• Ensure messages containing sensitive data are directed to a
specific trusted origin.
Defence
• When anonymous messages are by design, ensure data is strictly
validated.
• Avoid passing data from anonymous messages to functions that alter
the DOM in an unsafe way. Example:
document.write({message_data})
.innerHTML / .outerHTML = {message_data}
location.href = {message_data}
$({message_data})
Validation
• It is not uncommon for an application to accept
postMessage events from multiple origins.
• Sites such as google.com may wish to allow messages from
all “google” owned parent domains; google.com,
google.co.uk, gmail.com…..
• Regular Expressions are often used to validate the origin or
check that a portion of it matches the trusted domain.
Regex bypass
The following Regex is based on a real world example
encountered by AppCheck researchers:
RegExp("^https*://mail.google.com$")
The intention was to ensure the origin domain exactly
matched mail.google.com with either http:// or https:// as
the protocol
Regex bypass
RegExp("^https*://mail.google.com$").test(origin)
However dot “.” means “Any Character” within the regex.
Therefore the following origins also pass the test;
mailAgoogle.com
mailBgoogle.com
mailCgoogle.com
mailDgoogle.com
….
Regex bypass
• For £6.99 the attacker could own a domain that will pass
validation
Insecure Validation
Checking the origin using “indexOf” is a common pattern
that can be easily bypassed:
x = event.origin
if (x.indexOf("https://mail.google.com") > -1)
{..}
In this case the following origin would pass validation:
https://mail.google.com.attacker.com
CORS
CORS
• CORS provides an Access Control mechanism for allowing
bi-directional cross domain requests.
• Permissions are enforced using the following headers:
Access-Control-Allow-Origin:
Access-Control-Allow-Credentials:
Access-Control-Allow-Methods:
CORS
The following features/APIS are currently supported by
CORS:
• Invocations of the XMLHttpRequest API in a cross-site manner
• Web Fonts (for cross-domain font usage in @font-face within
CSS)
• WebGL textures.
• Images drawn to a canvas using drawImage
CORS
Access-Control-Allow-Origin: <origin> | *
The Access-Control-Allow-Origin header must list
either the origin for which connections are allowed or use a
wildcard “*” to mean all origins.
CORS
Access-Control-Allow-Credentials: true
Cross Origin Requests using XMLHttpRequest will not
include cookies unless Access-Control-Allow-Credentials
header is set to true
When the “*” wildcard is used, the browser will not submit
cookies regardless of this setting
CORS Vulnerabilities
• A vulnerability occurs when the target server echos back the
value supplied within the browsers “Origin” header:
Request:
GET /postmessage/inner_frame HTTP/1.1
Origin: http://evil.b.c
Response:
HTTP/1.0 200 Ok
Access-Control-Allow-Origin: http://evil.b.c
Access-Control-Allow-Credentials: true
CORS Vulnerabilities
A common configuration is to validate the origin header from the
client browser against a list of allowed origins.
http://appcheck-ng.com.com
Origin: http://appcheck-ng.com
HTTP Header
appcheck-ng.com
google.com
CORS Vulnerabilities
A common configuration is to validate the origin header from the
client browser against a list of allowed origins.
http://appcheck-ng.com.com
Origin: http://appcheck-ng.com
HTTP Header
Access-Control-Allow-Origin:
http://appcheck-ng.com
Validated as a trusted origin therefore echoed back in the response
appcheck-ng.com
google.com
CORS Vulnerabilities
• In some cases the validation of the requested origin fails.
Some previously encountered examples:
• All origins are permitted though error, or for “testing” purposes.
• Validation process is flawed, for example:
RegExp("^https*://mail.google.com$")
• The target resource is vulnerable to header injection
(https://www.owasp.org/index.php/HTTP_Response_Splitting)
Demo
• AppCheck NG will report CORS vulnerabilities through
passive analysis of server headers and active scanning
against the Origin header.
For example, if the target application is http://www.nsa.gov,
the following origins are attempted:
Origin: http://wwwXnsa.gov
Origin: http://www.nsa.gov.evil.com
Origin: (null)
CORS Remediation
• Ensure the CORS header specifically lists trusted domains
only. This is of particular importance when credentials are
allowed.
• Ensure that URLs responding with Access-ControlAllow-Origin: * do not include any sensitive
content or information that might aid attacker in further
attacks.
http://appcheck-ng.com/
@AppcheckNG
@garyoleary
[email protected]