How XMLHttpRequest behaves in combination with same-origin policy - html

I've a basic HTML, hosted in www.foodomain.com, with a simple script that just tries to make a POST call to a site located to another domain (www.bardomain.com), in order to provoke an action to be performed on that site. The attacker.html file is:
The hosting
<html lang="en">
<head>
<meta charset="utf-8">
<title>Attacker.html</title>
<script language="JavaScript" type="text/javascript">
var http = new XMLHttpRequest();
var url = "http://www.bardomain.com/attacked.php";
var params = "action=deleteAll";
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {//Call a function when the state changes.
if (http.readyState == 4 && http.status == 200) {
alert("fet");
}
}
http.send(params);
</script>
</head>
<body>
Some presentation text ...
</body>
</html>
As far as I know that behaviour should be blocked by the web browser due to its same-origin policy, but in fact the POST call to the www.bardomain.com site is done, though the action is never accomplished because the apache server sends an HTTP 302 message:
www.bardomain.com:80 192.168.56.1 - - [14/Dec/2014:12:57:30 +0100] "POST /attacked.php HTTP/1.1" 302 509 "http://www.foodomain/attacker.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:34.0) Gecko/20100101 Firefox/34.0"
Since it's a HTTP 302 response the action is not really done, but I didn't even expect the request to be sent by the browser (since it's to another domain). I'd really appreciate if anybody could give me an explanation to this behaviour.
On the other hand, another curious behavior occurs if instead of accessing the attacker.html file from apache, I just load the file in the Eclipse web brower, the POST message is sent and returns an HTTP 200 message, so the action is performed in the www.bardomain.com:
www.bardomain.com:80 192.168.56.1 - - [14/Dec/2014:13:20:52 +0100] "POST /attacked.php HTTP/1.1" 200 1586 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.78.2 (KHTML, like Gecko) Safari/522.0"
Any explanation to those behaviours?

Sending information is not blocked, but the other end may not send you back anything. Also, your browser may not use scripts loaded from outside your host domain if the CORS headers are not found with the returning payload.
In other words, the whole Cross Site Request Security is a two way hand shake before it works. The client (your browser) typically makes a request with the verb OPTIONS to verify it will be allowed to request the script in the first place. The server (other end) then replies with the VERBS you can use to request stuff from outside its domain.
Then, when you actually request the asset, the client provides HOST information for the server to validate and if all is well, other headers will be added to the return telling the client that the information was requested and okay to use.
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

Related

How to make a web server using Erlang

I'm new with Erlang
I try to make a web server with Erlang. How to do it with Erlang?
I was using this code to make a local:
-module(test).
-export([start/0,service/3]).
start() ->
inets:start(httpd, [
{modules, [
mod_auth,
mod_esi,
mod_actions,
mod_cgi,
mod_dir,
mod_get,
mod_head,
mod_log,
mod_disk_log
]},
{port,8082},
{server_name,"helloworld"},
{server_root,"C://xampp//tmp"},
{document_root,"C://xampp//htdocs"},
{erl_script_alias, {"/erl", [test]}},
{error_log, "error.log"},
{security_log, "security.log"},
{transfer_log, "transfer.log"},
{mime_types,[
{"html","text/html"}, {"css","text/css"}, {"js","application/x-javascript"} ]}
]).
service(SessionID, _Env, _Input) -> mod_esi:deliver(SessionID, [
"Content-Type: text/html\r\n\r\n",
"<DOCTYPE html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<title>HTML1</title>
<script
src='https://code.jquery.com/jquery-3.2.1.js'
integrity='sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE='
crossorigin='anonymous'></script>
<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet'/>
<link href='css/test1.css' rel='stylesheet'/>
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'></script>
</head>
<html>
<body>Ham oc cho!
<div class='header'>
<ul class='first'>
<li class='col-md-4'><a href='#' >Tai khoan cua toi</a></li>
<li class='col-md-4'><a href='#' >Trang thai don hang</a></li>
<li class='col-md-4'><a href='#' >Danh sach ua thich</a></li>
<li class='col-md-4'><a href='#' >Gio hang</a></li>
<li class='col-md-4'><a href='#' >Dang nhap</a></li>
<li class='col-md-4'><a href='#' >Dang ky</a></li>
</ul>
</div>
</body>
</html>" ]).
But I don't see any way to add a css-js file and don't know how to write a backend to this.
If you guy have some example or document pls share me
There is some useful Erlang tools like Cowboy, Mochiweb, Chicagoboss and YAWS for working on web protocols.
You might find it instructive to work through sws, my Erlang simple web server. It shows how to handle connections, read HTTP requests from a socket, and send replies using Erlang's built-in socket support and HTTP support.
The web server works by accepting incoming connections and parsing incoming requests using Erlang's built-in support for HTTP request parsing — see line 29:
ok = inet:setopts(S, [{packet,http_bin}]),
The {packet, http_bin} socket option tells Erlang to try to parse incoming socket data as HTTP. In the serve/3 function at line 36, for flow control and backpressure purposes, we keep the socket in {active, once} mode, which also means sws receives incoming data from Erlang as messages — see lines 37-41:
ok = inet:setopts(S, [{active, once}]),
HttpMsg = receive
{http, S, Msg} -> Msg;
_ -> gen_tcp:close(S)
end,
The serve/3 function is recursive, receiving HTTP request data until we get a full request or an error. Once serve/3 has a full request, it passes it to a handler function, which you're expected to provide when you call sws:start/1,2. The handler is expected to return a 3-tuple of HTTP status, HTTP reply headers, and HTTP reply body, where the headers or body can be empty depending on the return status.
For example, here's a simple "Hello, World!" application running in an Erlang shell:
1> c(sws).
{ok,sws}
2> Sws = spawn(sws, start, [fun(_,_) -> {200, [], <<"Hello, World!">>} end]).
<0.73.0>
Here, the fun passed as a handler always returns HTTP status 200, no reply headers, and a string binary for the reply body. Accessing the server via curl from a Unix shell shows the expected reply:
$ curl http://localhost:8000
Hello, World!
If we pass -v to curl to show more details, we see:
$ curl -v http://localhost:8000
* Rebuilt URL to: http://localhost:8000/
* Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 8000 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.51.0
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200
<
* Curl_http_done: called premature == 0
* Closing connection 0
Hello, World!
First curl tries to connect over IPv6, which fails since sws doesn't support it (though it could), so it retries over IPv4, which succeeds. Curl then sends a GET request for the / resource. When curl sees the reply, it shows the 200 status code, and also note that it sees that the reply is HTTP 1.0 and thus correctly assumes the connection will close after the body is sent, so after receiving the reply it closes its side as well.
The handler function you supply takes two arguments: the client socket and a request object, which is a property list consisting of 2-tuples where the first tuple element is an atom identifying its associated data. For example, the handler can determine the invoked HTTP method by finding the method tuple in the Request argument using lists:keyfind/3:
{method, Method} = lists:keyfind(method, 1, Request),
For our example above, Method would have the value of 'GET' (an atom). Other properties of the request that can be discovered like this are:
uri for the requested resource
version for the client HTTP version
headers for a list of the HTTP headers in the request
The handler function you supply can be as simple or complex as you wish. Note that if your handler fails and causes an exception, sws catches it and returns HTTP status code 500.
To stop the web server, back in the Erlang shell we send a stop message to the spawned sws process:
3> Sws ! stop.
stop
=ERROR REPORT==== 19-Jul-2017::11:17:05 ===
Error in process <0.77.0> with exit value:
{{badmatch,{error,closed}},[{sws,accept,2,[{file,"sws.erl"},{line,28}]}]}
The error shown here, which can be ignored, is simply due to the fact that sws always assumes that gen_tcp:accept/1 succeeds — see line 28:
{ok, S} = gen_tcp:accept(LS),
It would be easy enough to make this a case expression instead and handle error returns as well.
Note that sws is intended for demonstration and learning, and so it's intentionally not particularly efficient since it supports HTTP 1.0 only and handles only one request per connection.
Consider using http://phoenixframework.org/
It uses elixir which runs on the Erlang VM.

What is causing requests to this url/path?

My company is hosting an ecom shop based on Infinity Shop System. Our logs say that there are HTTP calls to this path which lead to 404 errors since the file does not exist:
http://{domain}/{somePath}/skin/default/images/tb-collectingalarm-red-low_inject.png
However, this reference is not made by us as I cannot find this path in any line of our source code.
The logs also state that only (some?) Firefox users do this call:
User Agent Mozilla/5.0 (Windows NT 6.3; rv:35.0) Gecko/20100101
Firefox/35.0
So, since this does cause quite some 404 errors, does anyone know what could cause these requests?
We already followed the referrer URL which lead to one of our sites but within its html markup we could not find any reference.

Cannot run xmlhttprequest in Chrome App : provisional headers & No 'Access-Control-Allow-Origin'

I am building a chrome app sending a Get HTTPRequest to an external API:
I get the answer:
XMLHttpRequest cannot load
http://developer.echonest.com/api/v4/artist/profile?api_key=FILDTEOIK2HBORODV&name=weezer.
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'chrome-extension://ihdfphmemcdeadpnjkhpihmcoeiklphe'
is therefore not allowed access.
I did allow the external domain in permissions in my manifest (to prevent blocking in cross domain requests)
When I type the URL in the Address Bar it works perfectly
It seems Chrome is blocking my request, I even tried to load directly the script in an HTML page and it does not work (same message but with origin "null") (oh and it did not allow me to cheat by changing the Origin in the Header).
I also get the famous "Caution : Provisional Headers are shown" in the console, which makes me think Chrome is blocking my request, I looked up on other Stack Overflow Questions but apart running chrome://net-internals and looking for stuff I haven't the first clue about I cannot find any good answers (I did run chrome://net-internals but really can't make any sense out of it).
Here is the request :
function update_stations() {
var xhr = new XMLHttpRequest();
xhr.open("Get","http://developer.echonest.com/api/v4/artist/profile?api_key=FILDTEOIK2HBORODV&name=weezer", true);
xhr.responseType = "json";
xhr.onreadystatechange = function() {
console.log("Essai");
console.log(xhr.readyState);
console.log(xhr);
document.getElementById("resp").innerText = xhr;
}
xhr.send()
}
Any thoughts (would be highly appreciated)?
Cross-Origin XMLHttpRequest chrome developer documentation explains that the host must be listed in the permissions of the manifest file.
I've taken the XHR code from above and included it in the hello world sample. It works after adding the following to the manifest.json.
"permissions": [
"http://*.echonest.com/"
]

SignalR client function not called when transport=serverSentEvents

On my machines I find that SignalR client functions are not called in Chrome.
My SignalR test app works fine with with IE9, Firefox and even Safari on my iphone. Looking at Fiddler, these browsers all seem to negotiate transport=longPolling. But Chrome negotiates a connection with transport=serverSentEvents, and I'm assuming this is why client functions are not called in Chrome.
More detail:
I'm using full IIS (not IIS express) on Windows 7. I'm using SignalR version 1.0.0-rc2. I've disabled my AVG firewall and the Windows firewall is not running. Chrome is version 24.0.1312.56, and was up-to-date at the time of writing. The app is invoked on localhost.
On Chrome, the signalR connection seems to take place OK - the $.connection.hub.start().done callback function is invoked. But after that, the client function is never called, even while the other browsers work just fine.
In the client-side code, I've turned on logging with
$.connection.hub.logging = true;
I can see log messages in Chrome's javascript console that correspond to a successful connection.
For reference, those log messages are
[20:22:16 GMT+0800 (W. Australia Standard Time)] SignalR: Negotiating with '/SignalRChat-RC/signalr/negotiate'. jquery.signalR-1.0.0-rc2.js:54
[20:22:16 GMT+0800 (W. Australia Standard Time)] SignalR: Attempting to connect to SSE endpoint 'http://localhost/SignalRChat-RC/signalr/connect?transport=serverSentEvents&…7-22c5dbf27e0d&connectionData=%5B%7B%22name%22%3A%22chathub%22%7D%5D&tid=3' jquery.signalR-1.0.0-rc2.js:54
[20:22:16 GMT+0800 (W. Australia Standard Time)] SignalR: EventSource connected jquery.signalR-1.0.0-rc2.js:54
[20:22:16 GMT+0800 (W. Australia Standard Time)] SignalR: Now monitoring keep alive with a warning timeout of 40000 and a connection lost timeout of 60000 jquery.signalR-1.0.0-rc2.js:54
But there are no messages logged in Chrome's javascript console when a client-side method is invoked.
Interestingly, the send method works OK on Chrome. The other clients display a message sent from Chrome even through Chrome itself can't see it.
The application is pretty much the chat application from the signalR tutorial at http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr
If I explicitly specify longPolling in the start method, i.e.
$.connection.hub.start({ transport: 'longPolling' })
then Chrome works OK. But my expectation was that I should be able to allow the browsers to negotiate their connection, and things would Just Work.
For reference, the relevant part of my client-side code looks like this:
$(function () {
// Turn on logging to the javascript console
$.connection.hub.logging = true;
// set up an error-handling function
$.connection.hub.error(function (err) {
alert("Error signalR:" + JSON.stringify(err));
});
// Declare a proxy to reference the hub.
var chat = $.connection.chatHub;
// Create a function that the hub can call to broadcast messages.
// This function is never called when running in Chrome with the default signalR connection
chat.client.broadcastMessage = function (name, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div />').text(message).html();
// Add the message to the page.
$('#discussion').append('<li><strong>' + encodedName
+ '</strong>: ' + encodedMsg + '</li>');
};
// Get the user name and store it to prepend to messages.
$('#displayname').val(prompt('Enter your name:', ''));
// Set initial focus to message input box.
$('#message').focus();
// Start the connection.
// Use $.connection.hub.start({ transport: 'longPolling' }) for reliability
// Use $.connection.hub.start() to demonstrate that Chrome doesn't receive messages
$.connection.hub.start().done(function () {
// Enable the "Send" button
$('#sendmessage').removeAttr('disabled');
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send($('#displayname').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
});
Can anybody see what I'm doing wrong?
I tried the sample in Win7 Google Chrome 24 and it works fine.
You can troubleshoot installing Fiddler and setting breakpoints in the javascript
POST /signalr/send?transport=serverSentEvents&connectionId=6ff0bffa-c31e-4d85-9aff-24f4528555ee HTTP/1.1
Host: localhost:43637
Connection: keep-alive
Content-Length: 113
Accept: application/json, text/javascript, */*; q=0.01
Origin:
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17
Content-Type: application/x-www-form-urlencoded
Referer: /index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
data=%7B%22H%22%3A%22chathub%22%2C%22M%22%3A%22Send%22%2C%22A%22%3A%5B%22gus%22%2C%22hello%22%5D%2C%22I%22%3A0%7D
May be it is related with buffering the responses.
https://github.com/SignalR/SignalR/issues/1944
Try setting EnableJSONP = False on the server hub. This fixed a similar issue I was having.

HTML5: Latest WebSockets

Has anyone read Hickson's May 2010 draft-hixie-thewebsocketprotocol-76 WebSocket protocol?
Here is the the source of an .htm file:
<html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript">
var socket = new WebSocket('ws://localhost:8181/websession');
socket.onopen = function() {
alert('handshake successfully established. May send data now...');
};
socket.onclose = function() {
alert('connection closed');
};
</script>
</head>
<body>
</body>
</html>
If I have a TCP port listening on 8181, this is the request I get when I load the .htm file above in Chrome:
GET /websession HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Host: localhost:8181
Origin: null
[\n]
(Where [\n] is CRLF character.)
What should I return to this handshake opener? draft-hixie-thewebsocketprotocol-76 shows:
HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Origin: http://example.com
Sec-WebSocket-Location: ws://example.com/demo
Sec-WebSocket-Protocol: sample
8jKS'y:G*Co,Wxa-
This response causes socket.onclose to fire though.
Draft 76 renamed the WebSocket- response headers to Sec-WebSocket-, and added some unnecessarily ugly Key header and request body crypto stuff to which the 8jKS'y:G*Co,Wxa- is a response. But that's only the correct response for the example included in the draft; it's no good returning that specific string for any other request. See this post for an explanation of how to implement the new protocol.
In any case, unless you are using the latest development builds, Chrome/Chromium will still be using the old draft 75 protocol (as the request you posted demonstrates), and won't talk to the a server that implements the new protocol. See the Chromium blog for more info. If you need to support old/current Chrome versions you effectively have to implement two WebSocket protocols.
This is always the risk in developing stuff against a protocol that is not yet standardised. You can expect annoying interinoperability until WebSocket is finalised; you may prefer to hold off until then.
(Trying to actually read the spec and work out what exactly has changed amongst the reams of unreadable parsing algorithms, is an exercise in frustration. I have no idea why it is written like this instead of the usual BNF-style specifications RFCs like. It's as if Hixie wrote a parser in C and then wrote an automated tool to turn the code into English. C would have been more readable TBH.)
You might find the wsproxy included in noVNC to be useful as a reference. It transparently supports both WebSockets v75 and v76 clients.
wsproxy is a generic WebSockets to TCP socket proxy. There is both a C and python version of wsproxy included with noVNC.
http://github.com/kanaka/noVNC/tree/master/utils/
Also, just to keep things interesting, the latest (no version yet) draft proposal changes things up again (in particular it changes how things are framed): http://www.whatwg.org/specs/web-socket-protocol/