Before we get started, warm up with a quick story:

Year-end bonus down, Zhang Fat pondering to buy some stocks as an investment, he visited www.stock.com with a browser, input the user name and password, login success.

Stock.com returned a cookie to identify the user.

The browser took the Cookie seriously and recorded it. In the future, every time Zhang made an Http request to Stock.com, the browser would conscientiously add the Cookie to the Header of the Http request and send it to Stock.com. So stock.com will know that Zhang Dabang has logged in, can do things according to Zhang Dabang’s request, such as viewing stocks, buying and selling stocks.

Zhang Big fat see stock rise pretty good, in the heart secretly pleased. He opened www.beauty.com again to see some of his own little secrets.

The browser downloads the HTML and JavaScript from Beauty.com and executes it.

This JavaScript creates an XMLHttpRequest object and then makes an HTTP request to stock.com!

Browsers follow the rules by adding previously stored cookies to Http requests as well!

Innocent Stock.com had no idea whether the Http request was made by Beauty.com’s JavaScript or by a big fat one.

Stock.com checked the cookie, knew it was a logged-in user, executed it coldly, and Zhang’s personal information was leaked.

(Of course, carrying out such an attack would not be so simple; here are the basics.)

Poor Fat Zhang lost money just because he visited a website. This is terrible!

Let’s recap why this happens for two main reasons:

First, stock.com cookies stored in your browser are sent whenever you visit Stock.com (either by clicking a button/link, or programmatically).

Second, the JS downloaded from Beauty.com accesses stock.com using XMLHttp.

The first point is we can’t stop it. If we do, cookies are useless.

For the second point, browsers must restrict access to stock.com from JavaScript from Beauty.com! This restriction is known as the same origin policy.

The same origin policy is very strict. Two urls must meet the following three conditions to be considered the same origin.

(1) The protocol (HTTP/HTTPS) is the same

(2) Same domain name

(3) Same ports

(Note: For details, see Browser Security Strikes Back.)

This request can be said to be a thousand enemy kills, eight hundred self loss.

Because it is normal for large systems to have many domain names, JavaScript can only make requests to its own “source” and cannot access other systems, which is very frustrating.

So people think of many ways, such as JSONP, CORS and so on to break through this limitation.

When websocket, a new technology, appears, it simply gives up this restriction and websocket can be accessed across domains.

But this brings security risks: cross-site websocket hijacking, we then zhang Big fat story to tell.

Zhang logged in to www.stock.com again, and the browser received the cookie and saved it. This time, Zhang found that Stock.com offered a new feature: real-time stock price notification.

Zhang Dapang turned on this new function, which is implemented with websocket. As we all know, websocket communication is initiated by HTTP protocol.

The browser makes an HTTP request to stock.com to upgrade the HTTP protocol to the Web socket protocol. The following Header is the HTTP request:

GET/stock/ws HTTP / 1.1

Host: www.stock.com

User-Agent: xxxxxx

.

Origin: https://www.stock.com

Sec-WebSocket-Key: xxxxx

Cookie: JSESSIONID=2B323FCF3968ETDSA9459

Connection: keep-alive, Upgrade

Upgrade: websocket

Note that Cookie data is also sent to stock.com.

Stock.com checks the Cookie to confirm that it is a logged in customer, establishes a Websocket connection, and pushes the latest stock information that Zhang dagang subscribed to.

Zhang Big fat see the latest stock information, very happy, he opened www.beauty.com, to see some of their own little secret.

The JavaScript in beauty.com runs again, also making an HTTP request to stock.com, also setting up a Websocket connection.

GET/stock/ws HTTP / 1.1

Host: www.stock.com

User-Agent: xxxxxx

.

Origin: https://www.beauty.com

Sec-WebSocket-Key: xxxxx

Cookie: JSESSIONID=2B323FCF3968ETDSA9459

Connection: keep-alive, Upgrade

Upgrade: websocket

Stock.com receives the request, checks the Cookie, verifies that it’s a logged in customer, successfully establishes a Websocket connection, and pushes the data to beauty.com.

If the Websocket supports other operations, the harm is even greater. (That’s why it’s called “hijacking,” not just “forgery.”)

As you can see, websocket failure to comply with the same origin policy is the biggest cause of cross-site script hijacking.

How does the Websocket protocol solve this problem?

As the keen students have noticed, in the previous HTTP request there is something called Origin:

Legitimate request:

Origin: https://www.stock.com

Attack request:

Origin: https://www.beauty.com

This Origin is required by the WebSocket protocol.

So on the server side of www.stock.com, when establishing a Websocket connection, be sure to check the Origin to make sure that the Origin is in its own whitelist.

1. Isn’t it just an Origin? How easy can a hacker fake it?

Note: all this is happening in Zhang Big fat’s browser, is Zhang Big fat in the operation, hackers want to forge, only through JavaScript to modify it.

However, the protocol states that Origin is in the HTTP Header, which is automatically added by the browser and cannot be changed programmatically (such as JavaScript).

2. The hacker can change the Origin of the HTTP request.

If you control your browser, or even your computer, you can change HTTP requests, but you control your computer, so why bother? Just monitor your username and password.

If you act as a middleman and change Origin by capturing the packet, that’s fine, and zhang needs to use Https and WSS to prevent it.

3. Is there any other way to prevent it?

Yes, there is a more secure way, which is consistent with the idea of guarding against CSRF: use tokens.

(1) The server side assigns a random and unique token to each Websocket client

(2) When the browser establishes a Websocket connection, it sends the token.

(3) The server verifies the token. If it is valid, the connection is established and the token is discarded.

About old Liu and code farmer turn over

I’m a thread

I’m a Java Class

Object-oriented Bible

The Hacker Brothers

The Hacker Brothers (cont.)

Hacker attack and defense diary

TCP/IP daming postman

CPU forrest gump

I am a network card

I’m a router

A story over HTTPs

The pinnacle of programming languages

Java: The Birth of an Empire

JavaScript: A loser’s counterattack