How can i get from what website the soap server was called? Already tried the $_SERVER variable but no information about the source is saved there.
My soap server is accessed from various websites (ex site1.com, site2.com etc). How can i get inside the soap server class if it was from site1.com or site2.com
Thank you.
You can't.
You could get the IP address of the machine that the request came from, but multiple domains could resolve to it.
If you care about "who" is making the request, then you need to hand out identifying credentials and require they be included in the request.
You might try overriding SoapServer::handle() and looking at the raw Soap request. Though as #Quentin says, YMMV.
Related
I'm writing an app using php and have been looking into security issues. I'd like to know how the following code grabs browser information and how it is passed from the browser to the server:
$_SERVER['HTTP_USER_AGENT']
$_SERVER['REMOTE_ADDR']
gethostbyaddr($_SERVER['REMOTE_ADDR'])
Is this information encrypted when it's passed from the client PC to the server? Would it be easy for a hacker to steal this data?
Browser -> Apache -> PHP
Spoofing/Faking $_SERVER variables other than HTTP, is difficult as there are some handshakes between your Apache and Browser so if someone tries to spoof these variables he will not receive any response. For example if someone tries to spoof REMOTE_ADDR, it is probable that the request will not be completed.
On the other hand all the variables that start from HTTP_ are easy to spoof and they are sent to PHP just as received by Apache from the Browser. So for example user can write a Curl script with a custom User Agent (HTTP_USER_AGENT) and you will receive the response as it is.
$SERVER this super global var is passed from web server instead PHP, but some of them is reference by the HTTP request header, let say with prefix "HTTP" is generated by client (request header), and REMOTE_ADDR is the address on TCP level, not a arbitrary but also no guarantee.
HTTP_USER_AGENT is in plain text at header, easy to modify
REMOTE_ADDR technically is on TCP level IP address, require some equipment or specific software to fake Server.
Essentially the PHP script gets these variables from the web server. On the manual page, there is a list of the variable names, and their descriptions.
So to answer your question shortly, they are gotten from the Web Server you are using.
If someone was to try to fake an example, like $_SERVER['REMOTE_ADDR'], there is information on how it can be done here, though I've never looked into it.
Hope this helps in some way :)
I'm trying to run a SOAP method on another domain which must be received from a whitelisted IP Address, but the WSDL seems to somehow think the request is coming from the client and not the server. The call collects information from a form, uses AJAX to post to a PHP function, which formats the fields into the API-friendly format, which is then sent via PHP SoapClient.
I thought the best way to do this was to investigate the headers being sent with the SoapClient, but the headers don't list any IP address (Host, Connection, User-Agent, Content-Type, SOAPAction, and Content-Length).
First, I read the documentation of the SOAP endpoint. It doesn't apparently specify any specific parameter to be passed, which wouldn't make sense anyway because I'd just be able to fake an IP address. Then, I read the documentation for PHP SoapClient. Interestingly I couldn't find quite where the IP addresses were set, but I did find a comment which mentions using 'stream_context', but had no luck with that either.
I am also logging every request, including $_SERVER['SERVER_ADDR'] and $_SERVER['REMOTE_ADDR'], which are both reporting IP addresses as expected; technical support on their end tell me that they are receiving requests from the 'REMOTE_ADDR' value.
I tried sending a bare-bones request and expected to get a different error besides the IP address, but I keep getting IP address problems.
Is there any way I can be more sure that I am sending the SOAP request with the proper (server) IP?
Okay, I figured it out - at least for my own situation. The comment in the PHP manual that you read was correct (assuming we're talking about the same one), however, I needed to include the port on my IP address as well. So the code that I ended up using was:
$options = array('socket' => array('bindto' => 'xxx.xxx.xx.xxx:0'));
$context = stream_context_create($options);
$client = new SoapClient($url,
array('trace' => 1, 'exception' => 0, 'stream_context' => $context));
See, before, I had no included ":0" I had merely included the IP address. So don't forget that!
This is a tough one, because the question does not really draw a clear picture on what systems are actually involved and where and what kind of IP whitelisting is in use.
When using SOAP, the primary source of information about the service is included in the WSDL resource. It is supposed to be obtained via a HTTP request, and it might trigger additional HTTP request if the XML of the primary resource has xi:include elements. All these requests originate from the system that acts as the SOAP client. You cannot choose which IP address to use here (unless you have a very exotic setup of having TWO interfaces that BOTH have a valid route to the target system, and choosing the right IP is the task of the application - I wouldn't think this is the case here, and I stop thinking about it - you'd need to configure a stream context for this, set the "bindto" option, and pass it into the SoapClient).
Inside the WSDL, the URL of the real SOAP server is contained. Note that the server itself might be on a completely different domain than the WSDL description, although such a setup would also be unusual. You can override that location by passing an option array to the SoapClient with an entry "location" => "http://different.domain.example/path/to/service". This would not change the loading of WSDL ressources, but all requests for the SOAP service would go to that different base URL.
The call collects information from a form, uses AJAX to post to a PHP function, which formats the fields into the API-friendly format, which is then sent via PHP SoapClient.
There are plenty of clients and servers mentioned here. AJAX is mentioned, which makes me believe a browser is involved. This is system 1, acting as a client. A request gets sent to some PHP. This target is system 2, acting as a server here. It transforms it and, acting as a client, sends the SOAP request to system 3, which is acting as another server.
So where is the whitelist? If it is on system 3, it must list the IP that is used by system 2. Note that every networked computer has more than one IP address: At least the one from that network device, plus 127.0.0.1. With IPv6, there are even multiple addresses per each device. Using $_SERVER['SERVER_ADDR'] does not really make sense here - and additionally, systems that are on the transport way, like transparent proxies, might also influence the IP. You shouldn't use the SERVER_ADDR as the entry for the whitelist. You should really check the network setup on a shell to know which network device is used, and what IP it has. Or ask the server you are about to contact to check which IP they are seeing.
I am also logging every request, including $_SERVER['SERVER_ADDR'] and $_SERVER['REMOTE_ADDR'], which are both reporting IP addresses as expected; technical support on their end tell me that they are receiving requests from the 'REMOTE_ADDR' value.
This is the strange thing. SERVER_ADDR and REMOTE_ADDR on system 2 are set as expected. I read this as REMOTE_ADDR being the IP of system 1, and SERVER_ADDR being that of system 2. But system 3 sees the IP from system 1? What is happening here? I'd really like to have more feedback on this from the original poster, but the question is already half a year old.
And it does not have a proper description of the experienced "IP address problems". How are they seen? Is it a timeout with "connection failed", or is it any proper HTTP rejection with some 4xx status code that triggers a SoapFault? This problem can only really be solved if the description would be better.
I do suspect however, that there might be complicated code involved, and the real SOAP request is in fact sent by the browser/system 1, because the generated XML on system 2 is mirrored back to system 1 and then sent to system 3. It would at least explain why the IP of system 1 is seen on system 3.
Ok, so I found out that it is impossible to get the server IP rather than the client IP. Very unfortunate...
I guess you will have to keep track of credentials by use of login/pass
Had the same problem. You have two solutions. Both require an extra step for calling the web service.
1) Use file_get_contents to acces your page that actually interrogates the WS via php soap. Example:
public function test() {
$result = file_get_contents('http://your.domain.com/pages/php-soap?params=your-params');
header("Content-type: text/xml; charset=utf-8");
echo $homepage;
}
2) Use CURL for the same purpose.
That way, you'll pass the server ip to the webservice. You can also secure your pages, by checking in php-soap (this example) the ip of the caller (the server ip in your case, which is unique).
Quick and dirty.
is there a way to send a AJAX post to a PHP page that is in a server that I don't have access? The server always send Access Control Allow Origin error, because I'm sending a post from my server (that I have access) to another server (that I don't' have access). It seems that this server that I don't own only accepts post from it.
Any code, tip? I found easyxdm to do that but I don't' know how to use it.
Yes, send the post using your php server(not javascript). That's your only option if you don't have access to the other server and they aren't returning proper CORS headers.
When using PHP I can use file_get_contents or cURL to get a URL.
jQuery runs on the client
In jQuery there is a function called jQuery.getJSON(). Javascript is run on the client. What server is used for the download of the JSON code of the external URL? What information does the called URL know about? Does it know of the domain? The IP of the client user? It's a client language.
Prefered for many request
To make many requests, is it safer to do this with Javascript than PHP because it runs on the every client instead of one server point?
What server is used for the download of the JSON code of the external URL?
The one that the domain name in the URL passed to that function resolves to.
What information does the called URL know about?
It is an HTTP request, like any other. The usual information will be available.
Does it know of the domain? The IP of the client user?
Of course.
It's a client language.
… making an HTTP request.
To make many requests, is it safer to do this with Javascript than PHP because it runs on the every client instead of one server point?
You control the server. You don't control the client. JavaScript can be disabled. It is safer to make the request from your server.
(For a value of "safe" equal to "Less likely to fail assuming the service you are using doesn't impose rate limiting")
Because of the Same Origin Policy all requests made in JavaScript must go to the domain from which the document was loaded. It's a standard HTTP request, so the server will have the same information it would if a user was just navigating around (including cookies, etc.) From the phrasing of your question it appears you need to make requests to some external site, in which case making those requests from your server which is not subject to such a security policy would likely be best.
In jQuery there is a function called jQuery.getJSON(). Javascript is
run on the client. What server is used for the download of the JSON
code of the external URL? What information does the called URL know
about? Does it know of the domain? The IP of the client user? It's a
client language.
The code that runs your web browser is only on your PC, too, yet it is perfectly capable of retrieving content via the HTTP protocol from a web server, and has done so for several decades.
AJAX requests are no different. jQuery creates an XMLHttpRequest object that performs an HTTP request in a manner uncoupled from the general page context. As far as the server's concerned, it's just an HTTP request like any other.
The text contents of the result you get back happen to be written in JSON format, but the HTTP layer neither knows nor cares about that.
When you enter soap servers url in browser, normally it produces blank page. But if memory serves me I saw somewhere something like
Hello, this is our soap service. For
documentation please follow this link.
To get an account, please follow this
link. Blahblah.
How can I do that? (Using PHP SoapServer, if that matters).
I did try to just print everything at the bottom of soap-server-handling php code but in that case soap server doesnt work when called from proper soap client.
The example you saw doing that was probably checking for one or more things in the headers and acting upon what it saw. For example, it could inspect
USER_AGENT
ACCEPT
ACCEPT_ENCODING
etc, etc, etc.
For you to do this in PHP, you will need your check to be run before your SoapServer gets the request. You can access the header values by inspecting $SERVER. Most of them will start with HTTP. To get started just
print_r($_SERVER);
What you want to do is look into WSDL (Web Service Description Language). Languages like .NET produce them for you.