Sanitizing url and parameters - validation

Currently, my software has the following workflow
User performs an search through a REST API and selects an item
Server performs the same search again to validate the user's selection
In order to implement step 2, the user has to send the URL params that he used for his search as a string (ex. age=10&gender=M).
The server will then http_get(url + "?" + params_str_submitted_by_user)
Can a malicious user make the server connect to an unintended server by manipulating params_str_submitted_by_user?
What is the worst case scenario if even newlines are left in and the user can arbitrarily manipulate the HTTP headers?

As you are appending params_str_submitted_by_user to the base URL after the ? delimiter, you are safe from this type of attack used where the context of the domain is changed to a username or password:
Say URL was http://example.com and params_str_submitted_by_user was #evil.com and you did not have the / or ? characters in your URL string concatenation.
This would make your URL http://example.com#evil.com which actually means username example.com at domain evil.com.
However, the username cannot contain the ? (nor slash) character, so you should be safe as you are forcing the username to be concatenated. In your case URL becomes:
http://example.com?#evil.com
or
http://example.com/?#evil.com
if you include the slash in your base URL (better practise). These are safe as all it does is pass your website evil.com as a query string value because #evil.com will no longer be interpretted as a domain by the parser.
What is the worst case scenario if even newlines are left in and the user can arbitrarily manipulate the HTTP headers?
This depends on how good your http_get function is at sanitizing values. If http_get does not strip newlines internally it could be possible for an attacker to control the headers sent from your application.
e.g. If http_get internally created the following request
GET <url> HTTP/1.1
Host: <url.domain>
so under legitimate use it would work like the following:
http_get("https://example.com/foo/bar")
generates
GET /foo/bar HTTP/1.1
Host: example.com
an attacker could set params_str_submitted_by_user to
<space>HTTP/1.1\r\nHost: example.org\r\nCookie: foo=bar\r\n\r\n
this would cause your code to call
http_get("https://example.com/" + "?" + "<space>HTTP/1.1\r\nHost: example.org\r\nCookie: foo=bar\r\n\r\n")
which would cause the request to be
GET / HTTP/1.1
Host: example.org
Cookie: foo=bar
HTTP/1.1
Host: example.com
Depending on how http_get parses the domain this might not cause the request to go to example.org instead of example.com - it is just manipulating the header (unless example.org was another site on the same IP address as your site). However, the attacker has managed to manipulate headers and add their own cookie value. The advantage to the attacker depends on what can be gained under your particular setup from them doing this - there is not necessarily any general advantage, it would be more of a logic flaw exploit if they could trick your code into behaving in an unexpected way by causing it to make requests under the control of the attacker.
What should you do?
To guard against the unexpected and unknown, either use a version of http_get that handles header injection properly. Many modern languages now deal with this situation internally.
Or - if http_get is your own implementation, make sure it sanitizes or rejects URLs that contain invalid characters like carriage returns or line feeds and other parameters that are invalid in a URL. See this question for list of valid characters.

Related

How to have a root query/mutation argument(s) in GraphQL API?

I need to have a "global argument" that can be specified (at most) once and applies to the entire request (having however many queries/mutations inside). If I were able to have the client specify it in query(arg: "value") {...} and/or mutation(arg: "value") {...} I would... but I understand this is reserved for "variables". I dislike other options I am aware of:
HTTP header - ties this to HTTP only, not in schema, not documented nicely.
POST /graphql
X-MyArg: some-value
...
{"query":"{someQuery{id name}}"}
HTTP (URL) query string parameter - ugh... I like the single common URL, also same problems as with (1)
POST /graphql?myArg=some-value
...
{"query":"{someQuery{id name}}"}
Introduce an intermediate wrapper field to expose this argument ... but this makes everything longer and I don't know of a way saying "this must be specified/requested at most once", while supporting multiple occurrences makes no sense for at least some of these (e.g. authentication / authorization / security related and others).
POST /graphql
...
{"query":"{wrapper(arg: \"some-value\"){someQuery{id name}}}"}
Cheat/hack and require an $arg variable (meant to be defined by the API client(s)) to be specified while somehow preventing the framework I am using from throwing up when that variable isn't actually referenced from anywhere inside.
POST /graphql
...
{"query":"query($arg:String){someQuery{id name}}","variables":{"arg":"some-value"}}
Can anyone help? Am I missing something or am I really forced to pick one of those poison pills?

Pass encrypted email in url in nop commerece

I want to pass encrypted email in url,but its not working on server,
while it is working on localhost.
I check the encrypted email- It contains some specific character like + , =
all those url which contains + sign are not working on server. but it working on localhost.
for example-
url format - {controllername}/{methodname}/{encrypted email}/{bool}
working url-
www.test.com/home/index/IZoc1QJlukTro7XN4kTaRDoy7mPNS-14YjKeZsXeyt3XsL4tXbLUPQ==/false
not working url-
www.test.com/home/index/KV6UWqy5fN7FY+lZuMAQ5nvA0+X4f8sQyB0la+-bSawUPEY1TIHK-C2bUdZUBRA6/false
not working url gives error like
404 - File or directory not found.
The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.
Thoughts ?
You should pass it as an url encoded query string parameter and not as part of the route:
http://www.test.com/home/index?email=IZoc1QJlukTro7XN4kTaRDoy7mPNS-14YjKeZsXeyt3XsL4tXbLUPQ%3D%3D%2Ffalse
If you want to pass some string as part of the route you should ensure that it doesn't contain dangerous characters which is your case. Scott Hanselman wrote a nice and detailed blog post on the difficulties that you might encounter if you attempt to pass such strings as part of the route here: http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx
I will quote his conclusion if you don't want to go through the entire post:
After ALL this effort to get crazy stuff in the Request Path, it's
worth mentioning that simply keeping the values as a part of the Query
String (remember WAY back at the beginning of this post?) is easier,
cleaner, more flexible, and more secure.

Data URI and a potentially dangerous Request.Path value

I have tried using a Data URI with this CSS property:
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA9JREFUeNpiYGBg8AUIMAAAUgBOUWVeTwAAAABJRU5ErkJggg==");
And locally it works fine.
However, when I am debugging the file appears missing in chrome. If I try to navigate to it, I get: A potentially dangerous Request.Path value was detected from the client (:).
So obviously my application considers the URI for this image suspicious.
How do I get it to show?
I tried relaxing the validation using:
<httpRuntime requestPathInvalidCharacters="" requestValidationMode="2.0" />
<pages validateRequest="false"></pages>
Ideally I wouldn't want to relax the rules too much, only enough to get these data URI images loading.
I would bet that the application considers the request suspicious because of the Base-64 encoded URI. Encoding malicious URLs in Base-64 is a common strategy by attackers to get URLs through front end filters that strip and/or escape URLs, and to obscure the request from any humans reading the code. XSS attacks are commonly done by getting one of these URIs stored in a database and served back to other users.
Because of the high risks of XSS these days, I would hesitate to disable the check. If you can, just use a non-encoded URI. If you can't, you should ask yourself why. If you are trying to enhance security by obfuscating the URI, do know that this is very trivial for an attacker to decode. It is not any form of encryption, just a different way to represent data.

Fiddler: Creating an AutoResponse rule to map all calls to one host to another host

Example:
I want to create one AutoResponse rule that will map all calls to one host to another host, but preserve the urls. Examples
http://hostname1/foo.html -> http://hostname2/foo.html
and
http://hostname1/js/script.js -> http://hostname2/js/script.js
in one rule.
For now, I've accomplished this by creating aN AutoResponse rule for every URL my project calls, but I'm sure there must be a way to right one rule using the right wildcards. I looked at http://www.fiddler2.com/Fiddler2/help/AutoResponder.asp, but I couldn't see how to do it. The wild cards all seem to be around the matching and not the action.
Full context: I'm developing on a beta platform and Visual Studio is borked in such away that it is sending all the requests to http://localhost:24575 when my project is actually running on http://localhost:56832
This is how I configured Fiddler2 :
I want to redirect all requests from http://server-name/vendor-portal-html/ to http://localhost/vendor-portal-html/
My configuration is as follows:
REGEX:.*/vendor-portal-html/(.*) to http://127.0.0.1/vendor-portal-html/$1
Thanks to EricLaw for above comment.
To map from one host to another, don't use AutoResponder. Instead, click Tools > Hosts.
Alternatively, you can click Rules > Customize Rules, scroll to OnBeforeRequest and write a bit of code:
if (oSession.HostnameIs("localhost") && (oSession.port == 24575)) oSession.port = 56832;
Because this was way harder to find than it should have been to use Fiddler to redirect all requests for one to host to another host:
Use the AutoResponder tab to set a rule such that any request matching your old host will redirect to your new host with the path and query string appended.
Match with regex options ix to make it case-insensitive and ignore whitespace. Leave off the n option as it requires explicitly named capture groups.
Capture the path and query string of the request and append it to the redirect response using the variable $1, where the path+query is the first capture group. You can use capture groups $1-$n if your regex has more.
Fiddler will then issue an HTTP 307 redirect response.
Request: regex:^(?ix)http://old.host.com/(.*)$ #Match HTTP host
Response: *redir:http://new.host.com/$1
Request
GET http://old.host.com/path/to/file.html HTTP/1.1
Host: old.host.com
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Response
HTTP/1.1 307 AutoRedir
Content-Length: 0
Location: http://new.host.com/path/to/file.html
Cache-Control: max-age=0, must-revalidate
Mapping requests with Fiddler Autoresponder using Regular Expressions is possible.
This can be done with rexexp rules. However this doesn't seem to be documented anywhere.
If you add a rule and use regular expressions within parenthesis, these matches can be used in the desired mapping when using the placeholders ... $n
each number corresponds to the matched regexp in the rule.
Example of Rule: regex:http://server1/(\w*) -> http://server2/
This will result in the following mapping: http://server1/foo.html -> http://server2/foo.html

Ajax and filenames - Best practices

I am using jQuery to call PHP files via the $.get method
function fetchDepartment(company_id)
{
$.get("ajax/fetchDepartment.php?sec=departments&company_id="+company_id, function(data){
$("#department_id").html(data);
});
}
What I am thinking is can I secure the filename even further?
Currently I have a global access check within the .php file that check if the user is logged in, if he can access this data etc.
But I am wondering if there are further steps I can take so a user couldn't see this filename, or what other steps you recommend to take.
Encoded requests
You could make the request details effectively invisible to the casual miscreant by encoding almost all of the URL and then decoding the request details server-side.
The request details would include the action you wish to perform plus the parameters relevant to that action.
All requests would be sent to a single URL, where a server-side process would decode the request details and perform the relevant action as required.
Example Original URL:
/ajax/delete.php?parameter1=foo&parameter2=bar
Request details:
action=delete&parameter1=foo&parameter2=bar
Encoded request details (encoded using base64):
YWN0aW9uPWRlbGV0ZSZwYXJhbWV0ZXIxPWZvbyZwYXJhbWV0ZXIyPWJhcg==
Encoded URL:
/ajax/?request=YWN0aW9uPWRlbGV0ZSZwYXJhbWV0ZXIxPWZvbyZwYXJhbWV0ZXIyPWJhcg==
I don't believe there is native functionality to encode to base64 in JavaScript, but it's far from impossible to find a suitable method or to write your own.
With obfuscated/minified client-side JavaScript it would be quite tricky for someone to determine how to make a request 'by hand'.
Hide implementation details
There are a number of practices you can follow to make your application less susceptible to attack through URL misuse.
Let's start with a URL of: ajax/fetchDepartment.php?sec=departments&company_id=99
There's no need to reveal what server-side technology you're using (PHP) nor, through the query string (sec, company_id), what the query string values actually mean.
Masking the server-side technology
Assuming you have index.php defined as a default, the following URLs are equivalent:
ajax/fetchDepartment.php?sec=departments&company_id=99
ajax/fetchDepartment/index.php?sec=departments&company_id=99
ajax/fetchDepartment/?sec=departments&company_id=99
The third URL does not reveal the server-side technology you're using. This limits the range of possible attacks. It also makes it easier for you to switch over to a different server-side technology without changing your URLs.
Hiding the meaning of request parameters
ajax/fetchDepartment/?sec=departments&company_id=99
ajax/99/departments/
The latter URL still conveys enough information to perform the request without revealing what the information means.
Whilst someone could still change the values, they won't know what they're changing. This will make it more difficult for an attacker to evaluate and understand the result of any URL changes they make.
Pretty much the only way you can obscure the URL for a certain piece of information from the user is by not loading it in through http. Maybe you can load a set of data on the calling page, or another page with a more generic url.

Resources