PHP SoapClient: Problems with Distributed WSDL File - php

I have a problem using a distributed WSDL File (scheme / other definitions are declared outside the actual WSDL) with PHP's SoapClient.
This is the fault message I got:
SOAP-ERROR: Parsing WSDL: 'getSomeInfo' already defined.
After some googling, it seems to be a bug inside PHP as someone else discovered exactly the same problem: http://bugs.php.net/bug.php?id=45282
Has there been any bug fix(es)? Any solution to work around this bug?
I think posting a code snippet is senseless, since the invocation of the SoapClient ctor using just the WSDL is the only that fails.

I had same issue. The problem was in wsdl and imports, I saved wsdl from site and pointed soapclient to use local file, but all references were original. Soap client each time gets file from remote host, went to parts, and from them back to same file but on remote drive. That caused same file to be loaded twice.
Solution is to use only remote files or to rewrite paths to local (all). SoapUI does that when you hit "export definitions" on project wsdl. Hope that will help others.

Download a local copy of the WSDL file. Remove duplicate method names. Update your soap client to use the local WSDL file. This has worked well for me in the past.

I had the same issue while accessing a WCF service providing multiple endpoints through PHP. In my case, it turned out that the main WSDL imports sub-WSDLs for each endpoint, while the sub-WSDLs do include the main-WSDL in turn. This is apparently the reason why PHP reads the main-WSDL twice and comes up with the "already defined"-error. I could avoid this behavior by creating the client with the sub-WSDL URL of the desired endpoint instead of the main WSDL URL.

The PHP source code (svn) which takes care of the import nodes contains the comment /* TODO: namespace ??? */. Namespaces are ignored which enables the method collisions to occur.
Three solutions are proposed:
Fix the source code to cater for namespaces (which would be very welcome)
Manipulate the WSDL files to prevent such method overlaps (this is likely not an option at all)
Instead of using the original WSDL file, call the imported ones individually (or group ones which do not have method name collisions) with separate SoapClient instances.
Sorry that I can't be of more help.

Related

Check if user has a Chrome extension installed [duplicate]

I am currently trying to detect if a user has a certain Chrome extension installed. The Chrome extension is not my own and I do not have the source code to it. I have tried methods in numerous posts but they all fail. What I've tried and why it failed is detailed below.
This results in 'cannot read property connect of undefined' when executed:
var myPort=chrome.extension.connect('idldbjenlmipmpigmfamdlfifkkeaplc', some_object_to_send_on_connect);
Trying to load a resource of the extension as follows to test if it's there but going to this URL in browser results in 'your file was not found' Chrome error page (note that I found this path by going to C:\Users\\AppData\Local\Google\Chrome\User Data\Default\Extensions\idldbjenlmipmpigmfamdlfifkkeaplc\1.0.0.1_0\ on my Windows local machine):
chrome-extension://idldbjenlmipmpigmfamdlfifkkeaplc/1.0.0.1_0/icon_16.png
Using Chrome management but this results in console error 'cannot read property get of undefined' when executed
chrome.management.get("idldbjenlmipmpigmfamdlfifkkeaplc", function(a){console.log(a);});
And most other answers I've come across seem to involve the extension being written by the same person who is trying to check for it.
Assuming you need it from a website
connect/message method implies that the extension specifically listed your website in the list of origins it expects connection from. This is unlikely unless you wrote this extension yourself, as this cannot be a wildcard domain.
Referring to files within the extension from web context will return 404 simulate a network error unless the extension declared them as web-accessible. This used to work before 2012, but Google closed that as a fingerprinting method - now extensions have to explicitly list resources that can be accessed. The extension you specifically mention doesn't list any files as web-accessible, so this route is closed as well.
chrome.management is an extension API; websites cannot use it at all.
Lastly, if an extension has a content script that somehow modifies the DOM of your webpage, you may detect those changes. But it's not very reliable, as content scripts can change their logic. Again, in your specific case the extension listens to a DOM event, but does not anyhow make clear the event is received - so this route is closed.
Note that, in general, you cannot determine that content script code runs alongside yours, as it runs in an isolated context.
All in all, there is no magic solution to that problem. The extension has to cooperate to be discoverable, and you cannot bypass that.
Assuming you need it from another extension
Origins whitelisted for connect/message method default to all extensions; however, for this to work the target extension needs to listen to onConnectExternal or onMessageExternal event, which is not common.
Web-accessible resources have the same restrictions for access from other extensions, so the situation is not better.
Observing a page for changes with your own content script is possible, but again there may be no observable ones and you cannot rely on those changes being always the same.
Similar to extension-webpage interaction, content scripts from different extensions run in isolated context, so it's not possible to directly "catch"code being run.
chrome.management API from an extension is the only surefire way to detect a 3rd party extension being installed, but note that it requires "management" permission with its scary warnings.

Parse a php file from an outside server

I'm trying to figure out how (if possible) to do this:
I want to have a server/space/cloud-storage without apache storing a php file, then, another server actually running and parsing that file.
This is because I know Dropbox (Copy, Google Deive, etc) does store any type of file but cannot run php files due to security and due to the lack of Apache.
I therefore thought it may be possible to have a server requesting the Dropbox php file, parse it and return the HTML result.
I thought of this solution and I tried making an include from an external source:
include_once("https://dropbox.com/whatever/file.php");
But is not feasible... Any solution?
Use the API of Dropbox instead of the webview. Then store the value in a variable or temp file and output the result of eval($codeFromDropbox); and delete it if you don't need it anymore.
Dropbox provides you a PHP class (also see the reference) to archive this or you can simply use the global HTTP API Docs to write this small script on your own.
Once you did the authorization as described in the API docs you can simply download any file you have the permissions for.
You can actually include remote files but it is disabled by default:
http://php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen
ini_set('allow_url_fopen', true);
This is OFF (false) by default because it is a VERY HIGH security risk.
It's also a high security risk using eval(). The whole idea is risky.
Why don't you store and the files on the PHP server you want to execute?
Update:
The ini configuration is allow_url_include, not allow_url_fopen, but you should lookup both.

Securing third-party API credentials in PHP and include

I am writing a series of functions to interact with third-party APIs that will be included in other PHP scripts. Most of these third-party APIs use token-based authentication, so I would like to store these tokens within the function, but I’m wondering what the best practices are for preventing exploitation of those functions in the included file.
For example, in a script called ~/public_html/includes/functions.php I would define some functions that call a public API using cURL, and then return some sort of response from the API. Then, within my app, I would include ~/public_html/includes/functions.php and call the functions to interact with the third-party APIs.
My concern is what if someone else includes http://www.example.com/includes/functions.php in their script, and starts calling my functions to make API calls using my credentials? Should functions.php live somewhere else, perhaps outside of the ~/public_html dir? Or perhaps I can use UNIX permissions to prevent anyone but my own apps to include the functions.php script?
My concern is what if someone else includes
http://www.example.com/includes/functions.php in their script, and
starts calling my functions to make API calls using my credentials?
Should functions.php live somewhere else, perhaps outside of the
~/public_html dir? Or perhaps I can use UNIX permissions to prevent
anyone but my own apps to include the functions.php script?
You are mixing up a lot of things here. And the long story short: You should not worry. I gave a full explanation on how include works with URLs in this answer. Below is a summary for your purposes.
Specifically, while one could use include to include full URLs like include('http://www.google.com/'); the only thing you get from that include is the final rendered content of the page. 100% none of the functions, classes, variables, strings, constants or anything contained in the internals of that PHP code. Or as very clearly explained in the PHP documentation you are linking to; emphasis mine:
If "URL include wrappers" are enabled in PHP, you can specify the file
to be included using a URL (via HTTP or other supported wrapper - see
Supported Protocols and Wrappers for a list of protocols) instead of a
local pathname. If the target server interprets the target file as PHP
code, variables may be passed to the included file using a URL request
string as used with HTTP GET. This is not strictly speaking the same
thing as including the file and having it inherit the parent file's
variable scope; the script is actually being run on the remote server
and the result is then being included into the local script.
So you cannot include credentials remotely—or any PHP internals—in the way you describe. The only way that could happen is if ~/public_html/includes/functions.php were included locally. That is when PHP internals are exposed.
Or the better way to understand this: When you request a PHP file via http:// or https:// it is parsed & processed via the PHP module in Apache. So it only returns the final product—if any—post often conveyed by an echo statement.
But when you include a file via the local file system it is not parsed by the PHP module in Apache. It is simply raw code. And that is how you can use the functions, classes, variables, strings, constants and anything contained in the internals of that PHP code.

PHP SOAP server configuration/implementation

I need to implement a SOAP server that will respond to a third-party application that behaves as a SOAP client.
The server should be in PHP, so I started using nusoap and http://www.wsdltophp.com/ to generate the skeleton.
Here's the wsdl file they gave me:
http://pastebin.com/YXBbszqE
The guy from support said I should start with the Ping request, because it's the most simple and straightforward to implement.
I'm new to this and will really appreciate some help.
Here's what I have so far for the server:
http://pastebin.com/vARst5t0
and to simulate the client:
http://pastebin.com/seG7EmM6
and it gives me an error:
http://pastebin.com/Say6FmF6
Thanks a lot, guys.
EDIT:
I found that on the server, after disabled the error_reporting, I don't receive the previous error.
I forgot to mention that I use the nusoap feature of loading the wsdl file and not defining each complexType manually, but it's still not working, now I get the following error:
Operation 'Ping' is not defined in the WSDL for this service.
And I'm sure it is there.
Maybe it comes from the options you chose when generating the package. Indeed, when calling the MySoapServicePing::Ping() method, parameters are maybe not sent properly : contained by an array or not. So try modifying the generation behaviour and send the request again.
You may also look to the XML request sent to the SOAP server in order to ensure that it does not come from the request. To get the XML request, you can call the MySoapWsdlClass::getSoapClient()->__getLastRequest() method or the $mySoapServicePing->getLastRequest() method (depends on the version of the generator) after sending the request.
Let me know if it changes anything or not.
Thank you guys, I ended up using the php native functions and it was much easier to configure.

SOAP PHP server-side debugging

I was landed a project to debug a PHP SOAP server (SoapServer) written by an unknown party. It is being used by a c# SOAP client, which I don't have access to the source code to (in other words, I cannot use __getLastResponse to see what it gets). I am trying to capture XML output of the server's responses. Traffic sniffing (wireshark, etc) doesn't work because of the SSL layer being used to encrypt XML messages. Any help in figuring out how to see the XML messages sent out by the server would be greatly appreciated.
There's an excellent example for extending the SoapServer class and grabbing the Soap XML request and responses here: http://blog.mayflower.de/archives/179-Extending-class-SoapServer-PHP5-for-debugging.html
Does the SoapServer look like this one, or like this one? If it's the former, you're up a tree and every ladder within a year's distance has been violently destroyed by wolverines. Rather, it's a binary blob of compiled code from which there is no escape.
If it's the latter, you may have some hope -- the service method's third parameter can be set to true to get the response data rather than blindly sending it out.
There's also a rumor that the ancient "nuSOAP" library has a server mode, but that project seems to have imploded in upon itself, and took the documentation with it.
Long-term, you may be better served by using a web service layer that isn't pathologically backwards, though that might not be an option for you.

Categories