is there any security issue if I send a path in a QueryString? - security

is there any security issue if I send a path in a QueryString? like if send this request http://localhost/eCTDTreeViewer/Home/Index/?pathOnServer=G:\test\company2

Thinking about QueryString security, you should keep in mind (read as "worry") the following moments:
URLs are stored in web server logs
URLs are stored in the browser history
URLs are passed in Referrer headers
You can find more detailed information about this reading How secure are query strings over HTTPS article and Is an HTTPS query string secure? question on SO.

The risk of exposing a path, given the filesystem is not externally accessible, is negligible.
Especially if the sole purpose of the component you're talking about is to display directories as they exist on the server. What you see in the query string is what you will see in the payload of the response, so it's just fine having the path there in plain text.
Trouble can arise when this "TreeViewer" exposes sensitive files and allows the user to browse to arbitrary locations, enabling them to retrieve passwords stored in files and what not.
Of course it never hurts to add HTTPS, but that only prevents a man in the middle from finding out which directories and files exist on that server and does not offer anny additional security.
HTTPS does not make your improperly secured application secure, you still have to implement authentication and authorization, input sanitation and so on.

Yes, you open yourself up to Directory Traversal (DT) and Local File Inclusion (LFI) attacks.
The main difference between the two is that DT is read-only in which a user can access any file on your web server provided that they have sufficient privileges. LFI on the other hand would allow you to invoke a file (e.g. a PHP file) on the web server rather than reading it.
If, for example, you have a SQL Injection vulnerability on your web application, an attacker may deploy a web shell into your system:
SELECT "<?php system($_GET['cmd']); ?>" INTO OUTFILE C:/tmp/shell.php
An attacker could then invoke the file:
http://localhost/eCTDTreeViewer/Home/Index/?pathOnServer=C:/tmp/shell.php?cmd=echo "foo"
This is very brief but it should provide a good idea as to how dangerous it can be.

If you stay in plain HTTP, yes. The request will be sent in plain text over the network. Don't be confused, it will be the same issue with a POST request with your information inside the body of it.
The good way to make it safe is to use HTTPS. Because of the handshake done before the exchange, the full request will be encrypted (with the path as well) to be sent to the endpoint.

Related

How to prevent snooping by user of Mac app?

I am creating a Chromium/Electron based Mac app. The app is essentially a browser for my customers to use a web service that I have no control over. My requirement is that users of my app (who may have root access on their Mac) should not be able to view the URLs the app is visiting, and should be unable to gain access to the cookies the app is storing. Normally it is not hard to MITM yourself, or attach a debugger to an app and dump memory to see the URLs and cookies.
How can I prevent these types of leaks to the user? If it's impossible, it may be acceptable to make it very hard so that a very high level of sophistication is needed.
Your users have full control of their devices, it is not possible to securely prevent them from proxying or exploring what your client-side app does. Obfuscation would seem like an option, but in the end, the http request that leaves your app will traverse the whole OS through different layers, and your user can easily observe that, if not else then in network packets (but usually much easier).
The only way it is possible to prevent the user from knowing what's happening is if you have your own backend. The frontend app (Electron) would make a request to your backend, which in turn could make any request with any parameters without the user being aware.
Note though that your backend could still be used as a proxy or oracle just like if the user was connecting to the real service. This might or might not be a problem in your case, depending on what you actually want to achieve and why.
The app is essentially a browser for my customers to use a web service that I have no control over. My requirement is that users of my app (who may have root access on their Mac) should not be able to view the URLs the app is visiting, and should be unable to gain access to the cookies the app is storing
Basically, you cannot (you could with the appropriate infrastructure. But you lack that infrastructure).
Network communications can be secured, to a point, using HTTPS (if you can't even use that, then you're completely out of luck - users wouldn't even need root access to the Mac to sniff traffic). You need to verify the server certificate to be sure you're connecting to the correct server.
One thing you might do - effectual just against wannabes, I'm afraid - is first run a test API call on some random server and verify that the connection either fully succeeds, with the proper server identification and matching IP, if the server exists, or that it properly fails if the server never existed. Anything else would be a telltale that someone has taken over the network layer, and at that point you could connect to a different server, making different calls, and lament that the server isn't answering properly.
Strings in memory can be (air quote) protected (end air quote) by having them available only for the shortest time, and otherwise stored in a different form - you can have for example an URL and a random byte sequence with the same length, then store the sequence and the XOR of the URL and the sequence. You can then reconstruct the URL every time you need it, remembering to clear it off any app caches it might find its way into. Also, just for the lols, you can keep a baker's dozen of different URLs sprinkled in the clear throughout the code. A memory dump at that point will turn out nothing useful.
Files, of course, can be encrypted with any one of several schemes - the files residing on the same machine that has to know how to decode them makes all such schemes ultimately vulnerable, but there again, you can try and obfuscate things. I once stored some information in a ZIP file - but it was just the header of an encrypted ZIP file, with the appropriate directory entry block glued at the end. The data were actually just gzipped in the clear, there was no password whatsoever. The guys that tried to decode the file thought it was a plain encrypted Zip file with the extension changed, wasted a significant amount of time with several Zip cracking tools, and ended up owing me a beer.
More than that, there is not much that can realistically be done.
A big advantage would be in outsourcing the API calls and "cookie" maintenance to an external service that you control, e.g. on Amazon AWS or Azure or similar. Then you could employ all kinds of protection schemes (for example: all outbound API calls could be stored in an opaque object, timestamped, nonced, and encrypted with your server's public key, and the responses sent encrypted with your client's unique key). Since this is relatively simple and cost-effective, it would also be my recommendation.

How to hide content in a txt file from direct url

I'm working on a windows app which is reading a "authorized" domains list from a txt file with a web request from "domain.com/sub/txtfile"
I don't want people to see the content of the file when entering it directly in the browser. Is it possible to achieve this with some .htaccess hacks or something else?
As your app is a client-side native Windows application, it's not possible to store any secret in the app itself that could be used for authentication. As the user has everything the Windows app may have, it impossible to authenticate the client as discussed many times here.
It also doesn't make much sense. Imagine it was somehow possible and file contents were only visible to your app. What would be the purpose? What if an attacker changed the hosts file on Windows to download the file from a rogue server? What if he used an intermediate proxy to inspect, change or replace contents? The latter is also possible with https, because the user has full control of the client, and can trust whatever certificate he wants.
You could authenticate the user though. An attacker can still see and modify downloaded file contents, but at least not anybody could download the file, only your authenticated users. But this means having a user database where the file is downloaded from, and implementing proper authentication. And it still doesn't solve the other problems.
In short, you can't protect a client-side application from a user that controls the whole client.

Are security concerns sending a password using a GET request over https valid?

We have webpage which uses the sapui5-framework to build a spa. The communication between the browser and the server uses https. The interaction to log into the page is the following:
The user opens the website by entering https://myserver.com in the browser
A login dialogue with two form fields for unsername and password is shown.
After entering username and password and pressing the login-button
an ajax-request is send using GET to the URL: https://myusername:myPassword#myserver.com/foo/bar/metadata
According to my understanding using GET to send sensitive data is never a good idea. But this answer to HTTPS is the url string secure says the following
HTTPS Establishes an underlying SSL conenction before any HTTP data is
transferred. This ensures that all URL data (with the exception of
hostname, which is used to establish the connection) is carried solely
within this encrypted connection and is protected from
man-in-the-middle attacks in the same way that any HTTPS data is.
An in another answer in the same thread:
These fields [for example form field, query strings] are stripped off
of the URL when creating the routing information in the https packaging
process by the browser and are included in the encrypted data block.
The page data (form, text, and query string) are passed in the
encrypted block after the encryption methods are determined and the
handshake completes.
But it seems that there still might be security concerns using get:
the URL is stored in the logs on the server and in the same thread
leakage through browser history
Is this the case for URLs like?
https://myusername:myPassword#myserver.com/foo/bar/metadata
// or
https://myserver.com/?user=myUsername&pass=MyPasswort
Additional questions on this topic:
Is passsing get variables over ssl secure
Is sending a password in json over https considered secure
How to send securely passwords via GET/POST?
On security.stackexchange are additional informations:
can urls be sniffed when using ssl
ssl with get and post
But in my opinion a few aspects are still not answered
Question
In my opinion the mentioned points are valid objections to not use get. Is the case; is using get for sending passwords a bad idea?
Are these the attack options, are there more?
browser history
server logs (assuming that the url is stored in the logs unencrypted or encrypted)
referer information (if this is really the case)
Which attack options do exist when sending sensitive data (password) over https using get?
Thanks
Sending any kind of sensitive data over GET is dangerous, even if it is HTTPS. These data might end up in log files at the server and will be included in the Referer header in links to or includes from other sides. They will also be saved in the history of the browser so an attacker might try to guess and verify the original contents of the link with an attack against the history.
Apart from that you better ask that kind of questions at security.stackexchange.com.
These two approaches are fundamentally different:
https://myusername:myPassword#myserver.com/foo/bar/metadata
https://myserver.com/?user=myUsername&pass=MyPasswort
myusername:myPassword# is the "User Information" (this form is actually deprecated in the latest URI RFC), whereas ?user=myUsername&pass=MyPasswort is part of the query.
If you look at this example from RFC 3986:
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
| _____________________|__
/ \ / \
urn:example:animal:ferret:nose
myusername:myPassword# is part of the authority. In practice, use HTTP (Basic) authentication headers will generally be used to convey this information. On the server side, headers are generally not logged (and if they are, whether the client entered them into their location bar or via an input dialog would make no difference). In general (although it's implementation dependent), browsers don't store it in the location bar, or at least they remove the password. It appears that Firefox keeps the userinfo in the browser history, while Chrome doesn't (and IE doesn't really support them without workaround)
In contrast, ?user=myUsername&pass=MyPasswort is the query, a much more integral part of the URI, and it is send as the HTTP Request-URI. This will be in the browser's history and the server's logs. This will also be passed in the referrer.
To put it simply, myusername:myPassword# is clearly designed to convey information that is potentially sensitive, and browsers are generally designed to handle this appropriately, whereas browsers can't guess which part of which queries are sensitive and which are not: expect information leakage there.
The referrer information will also generally not leak to third parties, since the Referer header coming from an HTTPS page is normally only sent with other request on HTTPS to the same host. (Of course, if you have used https://myserver.com/?user=myUsername&pass=MyPasswort, this will be in the logs of that same host, but you're not making it much worth since it stays on the same server logs.)
This is specified in the HTTP specification (Section 15.1.3):
Clients SHOULD NOT include a Referer header field in a (non-secure) HTTP request if the referring page was transferred with a secure protocol.
Although it is just a "SHOULD NOT", Internet Explorer, Chrome and Firefox seem to implement it this way. Whether this applies to HTTPS requests from one host to another depends on the browser and its version.
It is now possible to override this behaviour, as described in this question and this draft specification, using a <meta> header, but you wouldn't do that on a sensitive page that uses ?user=myUsername&pass=MyPasswort anyway.
Note that the rest of HTTP specification (Section 15.1.3) is also relevant:
Authors of services which use the HTTP protocol SHOULD NOT use GET based forms for the submission of sensitive data, because this will cause this data to be encoded in the Request-URI. Many existing servers, proxies, and user agents will log the request URI in some place where it might be visible to third parties. Servers can use POST-based form submission instead
Using ?user=myUsername&pass=MyPasswort is exactly like using a GET based form and, while the Referer issue can be contained, the problems regarding logs and history remain.
Let assume that user clicked a button and following request generated by client browser.
https://www.site.com/?username=alice&password=b0b123!
HTTPS
First thing first. HTTPS is not related with this topic. Because using POST or GET does not matter from attacker perspective. Attackers can easily grab sensitive data from query string or directly POST request body when traffic is HTTP. Therefor it does not make any difference.
Server Logs
We know that Apache, Nginx or other services logging every single HTTP request into log file. Which means query string ( ?username=alice&password=b0b123! ) gonna be written into log files. This can be dangerous because of your system administrator can access this data too and grab all user credentials. Also another case could be happen when your application server compromise. I believe you are storing password as hashed. If you use powerful hashing algorithm like SHA256, your client's password will be more secure against hackers. But hackers can access log files directly get passwords as a plain-text with very basic shell scripts.
Referer Information
We assumed that client opened above link. When client browser get html content and try to parse it, it will see image tag. This images can be hosted at out of your domain ( postimage or similar services, or directly a domain that under the hacker's control ) . Browser make a HTTP request in order to get image. But current url is https://www.site.com/?username=alice&password=b0b123! which is going to be referer information!
That means alice and her password will be passed to another domain and can be accessible directly from web logs. This is really important security issue.
This topic reminds me to Session Fixation Vulnerabilities. Please read following OWASP article for almost same security flaw with sessions. ( https://www.owasp.org/index.php/Session_fixation ) It's worth to read it.
The community has provided a broad view on the considerations, the above stands with respect to the question. However, GET requests may, in general, need authentication. As observed above, sending user name/password as part of the URL is never correct, however, that is typically not the way authentication information is usually handled. When a request for a resource is sent to the server, the server generally responds with a 401 and Authentication header in the response, against which the client sends an Authorization header with the authentication information (in the Basic scheme). Now, this second request from client can be a POST or a GET request, nothing prevents that. So, generally, it is not the request type but the mode of communicating the information is in question.
Refer http://en.wikipedia.org/wiki/Basic_access_authentication
Consider this:
https://www.example.com/login
Javascript within login page:
$.getJSON("/login?user=joeblow&pass=securepassword123");
What would the referer be now?
If you're concerned about security, an extra layer could be:
var a = Base64.encode(user.':'.pass);
$.getJSON("/login?a="+a);
Although not encrypted, at least the data is obscured from plain sight.

How secure is it to use fragment identifiers to hold private data in URLs?

We know the URL itself is not a secure way to pass or store information. Too many programs will perform unexpected processing on the URL or even ship it over the network, and generally speaking, the URL is not treated with a high regard for its privacy.
In the past we've seen Bitcoin wallets, for example, which have relied on keeping a URL secret, but they found out the hard way there are too many ways in which a URL (sent via Skype, or emailed, or even just typing it into the Google Chrome omnibar) will get stored by a remote server, and possibly displayed publicly.
And so I thought URL would be forsaken forever as a means for carrying any private data... despite being extremely convenient, except now I've seen a few sites which are using URL fragments -- the portion of the URL after the '#' -- as a kind of 'secure' storage. I think the expectation is that Google won't parse the fragment and allow it to show up in search results, so that data shouldn't be published.
But that seems like a pretty weak basis for the security of your product. There would be a huge benefit to having a way to securely move data in URL fragments, but can we really rely on that?
So, I would really like to understand... Can anyone explain, what is the security model for fragment identifiers?
Tyler Close and others who did the security architecture for Waterken did the relevent research form this. They use unguessable strings in URI fragments as web-keys:
This leakage of a permission bearing URL via the Referer header is only a problem in practice if the target host of a hyperlink is different from the source host, and so potentially malicious. RFC 2616 foresaw the danger of such leakage of information and so provided security guidance in section 15.1.3:
"Because the source of a link might be private information or might reveal an otherwise private information source, … Clients SHOULD NOT include a Referer header field in a (non-secure) HTTP request if the referring page was transferred with a secure protocol."
Unfortunately, clients have implemented this guidance to the letter, meaning the Referer header is sent if both the referring page and the destination page use HTTPS, but are served by different hosts.
This enthusiastic use of the Referer header would present a significant barrier to implementation of the web-key concept were it not for one unrelated, but rather fortunate, requirement placed on use of the Referer header. Section 14.36 of RFC 2616, which governs use of the Referer header, states that: "The URI MUST NOT include a fragment." Testing of deployed web browsers has shown this requirement is commonly implemented.
Putting the unguessable permission key in the fragment segment produces an https URL that looks like: <https://www.example.com/app/#mhbqcmmva5ja3>.
Fetching a representation
Placing the key in the URL fragment component prevents leakage via the Referer header but also complicates the dereference operation, since the fragment is also not sent in the Request-URI of an HTTP request. This complication is overcome using the two cornerstones of Web 2.0: JavaScript and XMLHttpRequest.
So, yes, you can use fragment identifiers to hold secrets, though those secrets could be stolen and exfiltrated if your application is susceptible to XSS, and there is no equivalent of http-only cookies for fragment identifiers.
I believe Waterken mitigates this by removing the secret from the fragment before it runs any application code in the same way many sensitive daemons zero-out their argv.
The part after the # is not any more secure than any other part of the URL. The only difference is that it MAY be omitted from the web server access log. But the web server is not the threat.
As long as you store the secret, either in a URL or somewhere else where it can become public it is insecure. That is why we invented passwords, because they are supposed to only exist in peoples head.
The problem is not to find a way to store a secret in a URL.
That is impossible, because as you say: The probably will become public. If all you need is the URL, and it gos public, nobody cares what the original data is. Bacuse they have what they need, the URL. So to rely on the URL alone for authentication is.. moronic.
The The problem is to store your secrets in a secure way, and to create secure systems.

htaccess as a security option and using a login form

I am learning PHP, and I am obsessed with learning security. I know a few about some kind of attacks likes injections, session theft, etc., but I would like to code my own CMS with a perfect security (if possible).
Reading I drop on .htaccess security in directories. This is a good option because all my CMS files are in one directory. I just read this in a website:
HTAccess is the most secure method of password protection, as it relies on the Web server, so the valid usernames and passwords are never shared with the Web browser or stored in the HTML like they can be with other scripts.
Is this true? I mean, it is "unhackeable"? Of course with extra security (like hidding the .htaccess file).
If this is true, I mean, there is no way to hack a site with .htaccess security, how can I use a form (instead of the popup window) so I can log in my CMS? Is there a way to use a "Forgot Your Password" option?
Any help will be apreciated, as examples and links for reference.
HTAccess is the most secure method of password protection, as it
relies on the Web server, so the valid usernames and passwords are
never shared with the Web browser or stored in the HTML like they can
be with other scripts.
I'm a little scared of the person who wrote this sentence originally.
Usernames and passwords would never be shared with the web browser or stored "in the HTML" except in the cases of the most rank disregard for hygienic programming practices. That someone would even present that as an "option" as a straw man argument is troublesome. I recommend finding a better guide.
The htaccess mechanism for server security is also a bit of a misnomer. The .htaccess file in directories is really intended to be a mechanism for clients on shared hosting sites to have some degree of control over Apache configuration variables -- which is a complete non-starter for "totally secure CMS system" (as if such a thing were a possibility. :) You should expect to have complete and total control over your Apache configuration, including all authentication and authorization and access control mechanisms. The .htaccess files are re-loaded, re-parsed, and re-configure the server on every single request but the site-wide Apache configuration is loaded once, parsed once, and configures the server once.
The server-based mechanisms rely upon either HTTP basic authentication (which is roughly akin to shouting your user name and password in a crowded room) or HTTP digest authentication (which is significantly better and if your users pick good passwords, probably even vaguely safe). Tunneling either one through TLS would be wise. (Heck, if you really want "security", you might even go to the effort of using client certificates.)
Note that these mechanisms ask the browser to pop up a dialog box for authentication. If you want to integrate the username and password into your web page in a "beautiful" way, then you will need to do all the username and password authentication checks via a form submission, storing session information, and checking your internal security mechanisms to provide authorization whenever it is necessary. You will be responsible for everything. (And, again, TLS is the way to go.) The web server cannot help you at all. (And you further won't be sending usernames, passwords to the browser in HTML... sheesh. That still scares me.)
is this what your looking for? this will allow you to use a php form to login through htaccess
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Text to send if user hits Cancel button';
exit;
} else {
echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";
}
?>
reference

Resources