Showing posts with label CORS. Show all posts
Showing posts with label CORS. Show all posts

Lambda functions and CORS implications

CORS (Cross-Origin Resource Sharing) is a web browser security mechanism that restricts web pages from making cross-origin requests, adhering to the Same Origin Policy (SOP). When a web page from one origin requests a resource from another origin, the browser blocks the request unless the server hosting the requested resource explicitly allows it.

In the context of AWS Lambda functions, CORS security is crucial when developing serverless applications that interact with APIs hosted on different domains. Here are some important considerations to keep in mind while working with CORS and Lambda functions:

Set CORS headers properly: When your Lambda function returns a response, it should include the appropriate CORS headers to indicate which origins are allowed to access the resource. This is typically done using the Access-Control-Allow-Origin header, which specifies the domain(s) that are allowed to make requests.

Validate all inputs: To prevent malicious requests from bypassing CORS restrictions, it is important to validate all inputs to your Lambda function. This includes checking for invalid characters, input length limits, and other security checks.

Leverage API Gateway: API Gateway offers built-in support for CORS, allowing you to specify which origins are allowed to access your API. You can configure CORS settings at the API level or at the method level. 

Restrict access: You should limit access to your Lambda function to only the necessary resources and methods. This can be done using IAM (Identity and Access Management) policies to restrict access to specific resources or API methods. 

Having HTTPS: To prevent man-in-the-middle attacks, it is recommended to use HTTPS when making requests to your Lambda function. This will also help ensure that your CORS headers are not tampered with by an attacker.

By following these best practices, you can ensure that your Lambda function is secure and not vulnerable to CORS attacks.

WebSocket Security - Protecting streams Over HTTP

WebSocket is gaining popularity with HTML5 architecture and has wide support from various browsers now. WebSocket allows full duplex communication over TCP as defined in the RFC 6455. Applications need such fast connection with data push coming from servers over polling data time to time. Hence, during our testing we started getting applications running WebSocket. It is imperative to understand the threat model for WebSocket usage and some of the concerns. In this post we try to address this.

WebSocket support and overview

The WebSocket protocol has been defined in RFC 6455 (http://datatracker.ietf.org/doc/rfc6455/?include_text=1) along with the WebSocket API (https://w3c.github.io/websockets/).  Hence, it is possible to use API via JavaScript and embed code right into HTML pages. As soon as a connect call is made by the browser, the HTTP Server switches to WebSocket protocol when it come across an "Upgrade" request call from the client on the same TCP connection. Applications support WebSocket calls via specific URLs like ws:// and wss:// on the pages.

WebSocket has become an integral part of Browser's communication stack as shown below.
We covered a post in the past on new Architecture over here ( HTML5/Browser Evolution and Threats)



Following is a simple upgrade call coming from a browser to a HTTP server.

GET / HTTP/1.1
Host: x.x.x.x
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: http:// x.x.x.x
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: Ru+jZkzO8cdIIHtoe8b80g==
Connection: keep-alive, Upgrade
Upgrade: WebSocket

Now, if the server is supporting the protocol then it will allow switching by the following response.

HTTP/1.1 101 Switching Protocols
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Accept: uRxNF7tq3wE+y/7EJjPbk1bPB5w=


Hence, at this point a tunnel is established and bi-directional communication can begin between client and server.If we look at API, then it is simple. Initializing WebSocket object

var WS = new WebSocket(“ws://api.target.example”);

Once that is done one can go ahead and use methods like onopen(), onmessage(), send() and close().

If you want to dig more into WebSocket –
http://www.html5rocks.com/en/tutorials/websockets/basics/

WebSocket usage

We have traditional web applications running over HTTP request and response. One of the problems with traditional usage of HTTP is of refresh and reload. Ajax helped, in a way, to solve this problem by making a quick async call and updating DOM. But in this mechanism, there is polling involved and it is not truly a faster bidirectional channel between the two. To improve overall efficiency one can use WebSocket in cases like the following :

1.     Multiuser gaming or chatting applications
2.     Pushing multimedia like voice, music, videos or large blobs
3.     Real-time updates like financial tickers, sports, tracking, feeds etc.

Also, developers are becoming innovative and utilizing JSON, XML etc. over WebSocket. Hence, there is no limit to how and where WebSocket calls can be used.

WebSocket threats and security concerns

WebSocket has some inherent weakness like allowing cross domain calls and few other issues. Hence, it is important to properly assess the threat model at development stage. Here are few issues one should check during testing -

Cross Domain Calls and Origin Checking

By design, WebSocket protocol doesn’t abide by SOP (Same Origin Policy). Hence, a browser can initiate a cross domain WebSocket call to any domain on the Internet. It is not required for an application to make calls to its own domain only. This can create issues and security threats. It allows an attacker to establish a connection or force any victim’s browser to initiate a connection as well. When WebSocket makes an “upgrade” call over HTTP, it sends “Origin: domain” header in the HTTP request. The browser itself adds this particular header based on its current state of DOM/location. This header cannot be tampered with by script. Hence, to avoid DoS and CSRF type attacks one can validate this header on server side before switching the protocol. Also, it is possible to perform DoS by opening multiple socket connections. One can avoid that by passing a token to the browser before protocol switching. Hence, only if protocol/upgrade switching request comes to the server with that token the server should allow the connection. This will avoid possibility of DoS.

CSRF with WebSocket and Stream hijacking

As discussed in the previous section about “Origin”, WebSocket is not following SOP. This allows an attacker to put a dummy page on Internet and drive someone to that particular page. As shown in the below figure, an attacker can leverage the following scenario:

  1. A user logs in to the system and establishes a session with proper authentication. User’s browser gets a cookie from the server for that particular application bound to the application domain. This cookie is going to replay in all other requests going from browser to the target domain.
  2. Application may establish legitimate WebSocket session as and when needed as shown in step 2 of the figure.
  3. Now, an attacker comes into picture and there is a page created with WebSocket calls pointing to the target application domain. If a user with an established session visits that page, like in traditional CSRF scenario, then he ends up establishing a WebSocket session since the cookie is going to replay. This allows the attacker to have a virtual tunnel created as shown in the figure. It is also important to observe over here that this session is two-way CSRF. In traditional CSRF we just get write/post access but in this case, since WebSocket is not following CORS either, the attacker is also allowed to read incoming stream from server. Hence, he ends up getting both read and write mechanism on stream. This ends up being stream hijacking.
Figure 1 – CSRF over WebSocket Streams

You can read more on this below. This attack is termed as CSWSH (Cross Site WebSocket Hijacking)
https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html

Again, for defense one can verify “Origin” and add extra CSRF tokens to validate legitimate users for stream processing.

WebSocket and SSL

It is also important to know on which tunnel WebSocket is running. One needs to make sure that it is running over SSL channel. If calls are going over a non-SSL channel then it may end up leading to information leakage and other related attack vectors.

WebSocket and input validations

A WebSocket call fetches new data from a server and dynamically loads things in the existing DOM with various APIs. It is imperative to validate incoming content before loading into DOM and protect against DOM based XSS and other types of variants. Also, it is obvious to protect server side injections and streams going over DOM calls. Burp and ZAP both have capability for evaluating WebSocket calls.

WebSocket review Cheat Sheet

Following checks and validation can be made for WebSocket review :
  • Version check for browser and required support.
  • Application level authentication and authorization for sensitive data transfer.
  • Endpoint security with having wss://
  • DOM based protection by JSON.parse() over eval()
  • Validating “Origin:” at server end
  • CSRF type protection in place for streams

Conclusion

The WebSocket protocol is a really good and efficient way for communication in certain scenarios, but at the same time it brings a new set of threats. Hence, developers have to keep security issues in mind during implementation both at server as well as client end. Now a days, there are many applications on the Internet which are using WebSocket heavily. Also frameworks and technologies like Microsoft’s signal.r are based on WebSocket. There are many libraries available for implementation of WebSocket on the server side, but by default they do not check for security issues. Hence, one needs to keep security issues in mind while implementing them and while performing reviews.


Article by Amish Shah & Shreeraj Shah

CSRF and Cross Domain Response Extraction in Era of CORS

CORS has certain critical response headers. It is required if the application needs to share resources on a  cross domain to other applications over Internet or Intranet. This type of scenario can lead to Cross Domain Response Extraction. For example application is sending following response header as part of HTTP.
 Access-Control-Allow-Origin: *
This makes it global and cross domain can access the resources from the server. In this condition it is possible to exploit response content by reading through the other domain.
Let’s take an example of an intranet application as in the layout shown in the figure below. The attacker can not access the internal resources through the firewall but can access it using the browser. If the internal user ends up being at the attacker’s site, he/she can send a payload that can start accessing a target internal application and crawl the resources.
Figure 1 - CSRF with CORS - Two Way Channel
For example, one of the server is marked accessible for cross domain call which we can see in following response.
HTTP/1.1 200 OK
Date: Wed, 12 Sep 2012 08:30:17 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 13539
This particular server can be crawled methodically and one can harvest all information from the server. For example, here is a very simple one page crawl where we are fetching all the links.
function crawl()
{
    var http;
    http = new XMLHttpRequest();

    http.open("GET", "http://192.168.149.128/", false);
    http.send();
    response = http.responseText;
    links = response.match( /<a href="(.*?)">[^<]+<\/a>/g );
    document.getElementById('result').innerText = links; 

}
This function will go and make a connection to the internal IP address and then fetch the response. Here, since the response is marked with the following directive, it gets loaded onto the browser.
Access-Control-Allow-Origin: *
Hence, through JavaScript one can extract the content now and send it back to the attacker server. In this case, for simplicity, we display it on the browser using the following call.
document.getElementById('result').innerText = links;
It will appear as below in the browser.
We can see all links and now, step by step, can start crawling each page. We can pretty much harvest and access all the information from the internal servers. It is also possible to perform a quick internal port scan using XHR or WebSocket.
Hence, it is important to scan through the resources and make sure that none of the critical resource is exposed to CORS issue.
For example, the following simple ruby script (CORScan.rb) can quickly look at the CORS header.
require 'socket'

ip = "192.168.149.128"
port = "80"
request = "GET / HTTP/1.0\r\n\r\n"

s = TCPsocket.open(ip,port)
s.write(request)
response = s.read
headers,body=response.split("\r\n\r\n",2)
puts "-----------HTTP Header----------------"
puts headers
puts "--------------------------------------"
headers.each do |header|    
    if(header =~ /^Access-Control-Allow-Origin:/i)
        puts header
        head,value=header.split(" ",2)
        value=value.chomp("\r\n")        
        if (value=="*")
            puts "[+] CORS Vulnerable Resource"
        end
    end
end
We have kept it simple for one HTTP request, but one can take multiple IPs and crawl the results to go over multiple pages and resources. But objective is to analyze access origin policy by looking at “Access-Control-Allow-Origin”.
If we run to our target application we get following response.
D:\Tools\ruby>CORScan.rb
-----------HTTP Header----------------
HTTP/1.1 200 OK
Connection: close
Date: Wed, 12 Sep 2012 11:02:48 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 13539
--------------------------------------
Access-Control-Allow-Origin: *
[+] CORS Vulnerable Resource
Hence, we can find the resource accessible over cross domain in this case.

 CSRF countermeasures

The following countermeasure should help in protecting applications.
1.) Critical forms and HTTP request should be validated for human event either by CAPTCHA or by having a unique identifier number going back to the browser. Hence, when an actual request comes back to server it is human enabled and not automated from cross domain.
2.) The CORS policy should be implemented and cross origin requests should be denied, or allowed from selected  trusted domains only.
3.) “Content-type” must be validated before processing the HTTP requests - if the stream is JSON, XML etc. Unless  it is a really critical business call, it must be validated thoroughly.
“Origin” and “Referer” tag can be processed to identify the HTTP requets’s actual origin. This check can give a good primary defense against CSRF vector.
4.) Application should be XSS free and all protection for XSS should be provided to the application. If XSS is found then it can be leveraged to initiate same origin CSRF attack vector or HTTP request to the application.