Make a PHP file accesable only via my C# application? - c#

I got a little questions for you all! Currently I have a login form on my C# application and you need to enter the right user and pass to open another form that is the real program. To do this I got this line of codes:
string response = SendRequest("http://mysite/login.php?name=" + userName);
string[] back = response.Split('_');
back[0] = back[0].Replace(" ", "");
back[0] = back[0].ToUpper();
and I got this method:
private string SendRequest(string url)
{
try
{
using (WebClient client = new WebClient())
{
return client.DownloadString(new Uri(url));
}
}
catch
{
MessageBox.Show("Error while receiving data from the server.","Something broke.. :(", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
return null;
}
}
I also have a method that checks if the entered password = the stored passwod in the database
$dbConnection = new mysqli("SERVER", "LOGIN", "PASS", "DBNAME");
$email = $_GET['name'];
$stmt = $dbConnection->prepare('SELECT password, salt FROM TABLE WHERE email = ?');
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->bind_result($pass, $salt);
$stmt->fetch();
echo "$pass" . "_" . "$salt";
This works fine and I can login when I enter the right password and I can't when I enter the wrong password.
My problem though is if I enter : http://mysite/login.php?name=[username]
where [username] is any username it returns the hashed and salted password. Since it's hashed and salted this is not a big issue but later when I will do inserts this will become a bigger problem since then someone could enter information into the tables with this method. So my question is: Is there anyway to make the PHP file only allow to return the values if the connections come from my C# application?

If you are really interested in managing this in a manner such as that, you should do one of the following:
Implement an OAUTH Configuration
You should implement a form of OAUTH in your PHP app, and generate the right proper tokens for your C# app. You would then use a full OAUTH dialogue to send/retrieve the data from the PHP server. This would eliminate the possibility for random queries to the page to return proper results. You should also implement HTTPS with this. PHP OAUTH implementation basics: http://www.sitepoint.com/creating-a-php-oauth-server/
Advantages: Security. This method provides a greater deal of security than the others, without sacrificing the robustness of the project in general. You would also be able to remove the entire GET/POST request by using tokens for each client, instead of a GET against username. Extensibility. This method can be easily extended to provide features for further apps/programmes.
Disadvantages: Complexity. This method is much more complex and has much more overhead than the others.
Modify the Request to be a POST with Secret
Another option is to change the C# programme to send a POST request to the PHP page, and send some secret value with it as well. This is not recommended, as anyone who knows the secret value could send it from a malicious page. This is equivalent to implementing basic XSS attack prevention. You should also use HTTPS for this as well.
Advantages: Simplicity. This method is the quickest/easiest to implement without removing any current features.
Disadvantages: Insecurity. This method does not provide any security benefits, apart from security through obscurity.
Alter Database Visibility
Since you are using MySQL on the PHP page to return the value, you should modify the C# programme to connect directly to the MySQL database and collect the value. This has the advantage of eliminating the possibility of someone with malicious intent querying the PHP page without your permission. Various MySQL connectors: https://www.mysql.com/products/connector/
Advantages: Moderate Security. This method does remove the possibility of PHP exploits, and also assists in keeping the database secret.
Disadvantages: Moderate Insecurity. This method requires embedding the connection string (with username and password) into the application when distributed. Certain measures could be taken to assist in eliminating some of the issues with this, but in general this method is an average method. Code Rewrites. This method requires an entire rewrite of the programming infrastructure.
Custom User Agent
Edit: Forgot to mention, another simple/easy workaround that is extremely insecure.
You could utilize a custom User Agent (similarly to the secret in the POST method.) This would allow your PHP page to determine that the request likely came from your application. You should, again, use HTTPS for this method as well. This method would not require much code change, and could be combined with HTTP_REFERER to assist in securing the origin as well.
Advantages: Simplicity. This is, by far, the easiest method to implement.
Disadvantages: Insecurity. Much like the POST with Secret method, this is extremely insecure. Anyone who knows how your User Agent is formed could quite simply and readily exploit it. Using HTTPS would likely help mitigate this risk, but it would never go away.
Examples:
C#: client.Headers.Add ("user-agent", "my-super-insecure-user-agent");
https://msdn.microsoft.com/en-us/library/system.net.webclient.aspx
PHP: if ($_SERVER['HTTP_USER_AGENT'] === "my-super-insecure-user-agent") {/*Process request*/}
http://php.net/manual/en/reserved.variables.server.php
Tl;dr
Ultimately, the choice is yours. Given the situation, I would recommend using the following advisories:
If development time is not an issue, utilize the OAUTH model. This is the most expandable and secure method.
If you can eliminate the PHP in general, use the Database Visibility model. This has the advantage of removing the inherit security risks associated with having a publicly-visible PHP page. You could also use this model, with more efficiency and speed, if the database is always local to the users network. This also means that outsiders could not access your information, if properly fire-walled.
If you need a quick-and-dirty solution, use the POST model. This would be the fastest and simplest to implement, but the least secure.

Related

How to identify Post Data is hacked using anti-forgery token

I know how anti-forgery token in ASP.NET MVC works.But still not clear about few scenarios. One I mentioned below.
submit a post request with below information
cookie token(antiforgerytoken)
form data(first name & last name)
form input hidden token(antiforgerytoken)
Before reaching server a hacker modified form data(first name & last name) leaving token info unchanged.
In this scenario, how we can make sure the data submitted securely reached server without any modification
Actually this question is asked by an interviewer. I discussed with my colleagues and I searched in Google too. Since I couldn't find a clarity on this I thought to ask here.
I am not sure if this is a valid question.If yes,any help would be appreciated
Multiple things are mixed here. The confusion is around the purpose of different protections, so let me try and get that straight.
CSRF, and antiforgerytoken
The basic threat is the following. A victim user is logged on to the victim website victim.com. Meanwhile (say in another browser tab) he visits a malicious website malicious.com that wants to exploit CSRF in victim.com. For that, malicious.com has the user post the required parameters to victim.com to call a certain function which obviously victim user did not want to perform. This is the base case of CSRF, exploiting an existing user session, malicious.com performed something on victim.com via a victim user.
This is prevented, if for example antiforgerytoken is used, because malicious.com will not be able to send the right token to victim.com, so the request will be denied.
Note that this has nothing to do with legitimate request content.
Integrity of requests
A different problem is making sure the request is received as sent, ie. data is the same. This is usually achieved by using HTTPS, which provides message integrity and encryption (among others). So if HTTPS is used, such change of data in transit is not possible.
Of course if the attacker controls either the client or the server (more precisely, the TLS endpoint, which is not always the server), ie. anything outside the TLS channel, then the attacker can modify data. But that would mean having control over the client. For example you can do this if you run a local proxy (Fiddler, Burp, ZAP Proxy, etc.) on your client - you can then change any data in the request, that's how penetration testers work. However, an attacker not having this level of control would not be able to do this.
Without HTTPS, request (and btw also response) integrity and encryption are problems that are hard to solve. The solution is HTTPS. :)

Send login credentials from C# client to Yii SOAP server

So, I have SOAP handling classes from https://soapclient.codeplex.com/SourceControl/latest. Using provided methods, I managed to connect to server and retrieve data, like:
SoapClient client = new SoapClient("http://somelink.someserver.net/~johndoe/gogogo/servis");
XElement myEle = client.Invoke("getProjekti");
What I need to do next is to provide HTTP authentication i.e. to send login credentials to web server. There is a way of adding Username and Password to a provided SoapHeader:
client.Header = new SoapHeader();
client.Header.Name = "AuthHeader";
client.Header.Add("UserName", "student");
client.Header.Add("PassWord", "student");
And there's the roadblock for me. What to do next? Common sense and programming experience make me think that there should be, hypothetically, request method that will now somehow send that header to web server, like:
bool sendLoginRequestToServer(client)
or something, returning true if login is successful or false otherwise. Despite vigorous search I was only left puzzled, since many people use many methods, most of which I failed to understand. What makes it even more difficult for me is that most of tutorials cover C# WebService, while I have ordinary WinForms GUI application. Solution within aforementioned SoapClient would be preferable, but I would settle for anything that works.

Open url in browser and fill asp.net popup with values from wpf application

I have a Wpf application and I want to open url (asp page) and fill popup with values (login, password). How can I do it?
Now I open url with Process.Start:
var processStartInfo = new ProcessStartInfo(url);
Process.Start(processStartInfo);
But I can't find out a way to fill popup..
I find way to use webControl... but I need to open url in browser..
My first recommendation is to think whether a mechanism like this is really necessary because it deals with a lot of sensitive Information. If you can avoid it, I'd recommend not to use at least the password.
Can you make changes to the ASP-page? Then you can add some request parameters that the ASP application fills into the fields, you could do that.
However, in this specific scenario I strongly recommend NOT to fill the username and password directly in the URL because it can be read easily along the path. If the application runs in a completely safe, controlled area, one can argue about the username, but I would not recommend it.
What you could do is to create some kind of token mechanism, so that you do not transmit sensitive data:
WPF application creates token, e.g. in database. It is important that the token is random and cannot be guessed, maybe a GUID. Also it should be valid only for a short period of time. Also the WPF application stores the necessary login Information in the database.
WPF application opens the browser with an URL like https://srv?token=<random token>.
ASP application receives token through request Parameter, checks whether it is still valid and signs user in using the Information that is stored along with the token. It deletes the entry in the database immediately so that the token cannot be reused.
This approach requires you to be able to make changes to both the WPF application and also the ASP application.
And as said above, if you can avoid it, it is preferrable to have the user enter his or her credentials manually.

C# app should send some data to php website but should respect auth policies

I have a situation where my C# Application need to communicate with my Php website (yes I have sources for both of them and I can edit without any problem).
I have to send some data from my C# app to PHP website to update some data in the database.
The biggest problem, is that this webpage where I should send data is protected with an authentication mechanism.
I don't have any problem in editing this mechanism, however I need a secure way to send (eventually) username/password and the data required. What's a secure way to do this? I don't think sending username and password as plain text is a good idea, so I was looking for suggestion.
SSL + username in request (optional; but if you will eventually have multiple clients that you have to differentiate, it's probably necessary) + SIGN the request with the password that corresponds to that username and is known on both ends.
Note that "signing" does not mean sending the password over the network. It means hashing a part or the complete request, then including that value in clear-text request. The recipient (PHP) would then do the same, then compare hashes. Signing ensures that only the client that knows the password can make the request; invalid requests should be rejected.
Encrypting with SSL certificate (if you have it on php side) helps only to hide the data from curious eyes. Signing is what verifies the client.
Make an anon php handler (make an exception in your auth rules), and this should work.
EDIT: EXAMPLE
Let's say that you want your C# app to pass the following data to your PHP app:
<data>hello</data>
Let's say that you decided for this client to be recognized by username "uid" and password "pwd".
Signing data relates to hashing it. Hashing means encrypting it in such a way that it cannot possibly be decrypted (well, kind of; I simplified that; look it up). There are several hashing algorithms, and you'll have to find a library to do it, for both C# and PHP. The most popular (I guess) are "sha1" and "md5". I don't even know the core difference, neither do I care. All I know is that different values get to be "translated" to fairly unique hash values. For example - although, off-topic, it's common to store hash values of passwords in the database, and compare hashes, rather then be comparing clear-text password, during user validation.
In .NET, you can sha1/md5 hash string values by method System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile. I know very little about PHP, but I'm sure you'll find a library that does exactly the same.
So, given the above example data, and above credentials, you could do the following:
1 - Find the place for the username (so, that you know who's sending the request; again, if you anticipate having multiple clients; otherwise, in your case, you can skip this). For example:
<data username="uid">hello</data>
Instead of this, you can do various things: define your own format (xml, json, delimited, binary), or if the data is short and you're using HTTP GET, then encode it and have data and username be two different query pairs, or HTTP-POST them as post arguments.
2 - The above data is still clear-text. Now, signing. This can be done in multiple ways, but I'll make it simple: add the clear-text password to this data (doesn't matter where, as long that location is known to both parties); e.g.
<data username="uid">hello</data>pwd
Notice how I don't even care that I just broke the xml-format. You could have placed it as an attribute/element - anywhere. That's still clear-text.
3 - Hash it. Again, it doesn't matter which hash algorithm you use, as long it's known to both parties. For this example, I'll use one of many online hash generators that are out there:
http://www.joeswebtools.com/security/sha1-hash-generator/
When I paste the complete text (including the password) from #2 over on that site, I'll get this (go ahead and you also try):
3311d4ed24ce60f7bf9cf261e3203616b239d944
So, given the exact same text input (case sensitive, encoding sensitive) hashing will always produce the exact same result. SHA1/MD5 are fixed-length algorithms (36 and 40 chars, I believe; I'm lazy to verify that right now).
4 - Now, add this hashed value to the original request data from #1 (any spot, as long as it's known to both parties); for example:
<data username="uid">hello</data>3311d4ed24ce60f7bf9cf261e3203616b239d944
or
<data username="uid" signature="3311d4ed24ce60f7bf9cf261e3203616b239d944">hello</data>
The important thing is that PHP needs to know where to find the hash value and how to parse it out.
5 - Send the text from #4 from C# to PHP. What we did so far was only signing to be certain that the sender is who you think it is. It is not encrypting: there are ways to intercept this request and read it (however, nobody can decipher the password). It is up to you if you also want to encrypt it (do you care if somebody can read this?). There are bunch of ways to encrypt data as well, but using SSL certificate on PHP side (and then sending the request over HTTPS) is probably your simplest, cheapest, the least error-prone/risky method, and - I dare say - the best. If you choose not to encrypt, C# sends the data as it is in #4 above.
6 - PHP receives the data. If you used SSL, I'm pretty sure you won't have to do anything to decrypt it (it will be done by PHP for you) - so, in either case, your PHP script will receive the data in clear-text.
<data username="uid" signature="3311d4ed24ce60f7bf9cf261e3203616b239d944">hello</data>
7 - PHP knows about this format. If parsing this request fails for any reason, ignore the request. I said this assuming that the code running on both ends has no bugs related to creating the request and reading it.
8 - PHP removes the the signature from the request data (while keeping it in memory), resulting in this:
<data username="uid">hello</data>
9 - PHP reads the username from the request ("uid"). It then looks up the password associated with it ("pwd"). It then does the exact same things that the C# client did in steps #2 and #3, producing the following for itself:
3311d4ed24ce60f7bf9cf261e3203616b239d944
10 - The signature form #9 has GOT TO be the same as the signature provided in the request (from #8) - case-sensitive! If it's not, somebody is trying to pretend they are the uid client.
11 - Now that PHP is certain that the client is its friendly C# app (let's call this "the trust"), it can process the request.
There may be more elegant ways, possibly simpler. Also, where in step #2 I told you add the password, you could instead add the HASH of the password (assuming your PHP doesn't even have the clear-text password, but it has that same HASH instead).
No, this method cannot be faked. It is impossible for me to - without knowing the password - to send you some maliciously-formed request pretending to be your C# client. However, replaying IS possible. Replaying means: intercepting the request, reading it, and resending it as it. This is mostly done to steal information without neither of the 2 parties knowing. There are ways to prevent replaying also, but it's out of scope, and you're not doing anything for the military, are you?
Now, I want an A for all this info and my time :)

RESTful service and user maintenance - url structure and commands question

I'm designing restful service and one of the entities to maintain - user accounts. I'm doing it in .NET and using membership provider.
Here is what I have:
/users/ GET - returns list of users
/users/ POST - can create or update
multiple users (post array of User
objects)
This POST won't matter if you updating or creating user
Problem I have: How do I create service to change password? Changing password is separate from updating users procedure. I'm thinking something like:
/users/{userName}/password POST - to
change user password.
But then I have to pass different object here? (I use JSON)
Do you have any suggestion on how to layout URL? And should I really create another object? MembershipProvider requires old and new password to change
Well the question has to be whether we see the password as a resource in its own right, or not.
In my user dbs, I store all my passwords (salted and stretched) in their own table, so I can easily present the password as a separate resource. But just because you don't have that fine grained control doesn't mean you can't do the same - but I wouldn't consider implementing a GET for the password, ultimately you need an authentication service for that, which should follow some kind of protocol.
A rest service is free to represent its data however it wishes, with no real regard for the underlying structure so, given that, I think you're free to do it as a separate resource if it makes sense in your case.
You could include in your user data a uri to be used for changing the password. The client would have to know the type of data to send (so yes you will need a dedicated resource type to handle the change request), and that the uri should be triggered with a POST request.
If I understand your question, you'd like suggestions on how related to the Uri layout itself. The suggestions below is related specifically to designing a Uri that someone can use to change a password.
Never include any sensitive information in the clear in URIs, even if it comes over HTTPS, as that information may be written to log files on the server, or worse, recorded by analytics or monitoring software. Make sure sensitive information is sent as part of the body or part of the header.
Here are a couple of considerations why changing a password with a RESTfull service may require its own Uri:
Prevent accidental changes to a password when updating a user details.
Whenever this method changes, you may need additional security reviews as any defects therein that allows a anonymous user to change the password of an existing user will allow that anonymous user to hijack the account.
You may also want to include other additional security features like notifying a user that their password has changed and invalidate any OAuth tokens issues to applications. The membership provider is great, but doesn't provide this additional measures.
Since it is a different Uri you can monitor its usage and correlate it to IP Addresses allowing you to detect whether someone is trying to compromise a user account.
You can just PUT a data contract to https://example.com/users/{id}/password:
[DataContract]
public class ChangePassword
{
[DataMember]
public string OldPassword { get; set; }
[DataMember]
public string NewPassword { get; set; }
}
The latter assumes you'll authorize whether the client can actually perform this action. You may want to look at PUT vs POST in REST whether to use PUT or POST. In addition, the book RESTful Web Services and REST API Design Rulebook has been invaluable to me when designing RESTfull services, including Uri layout.

Categories

Resources