The HTTP request must contain a user-specific secret - Error in fortify - ajax

I have below code in my applicaton.
makeAjaxRequest: function(url, data){
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.onload = function () {
var response = Ext.JSON.decode(xhr.responseText);
if (response) {
Ext.Msg.alert('Alert', response.message);
Ext.getBody().unmask();
}
};
Ext.getBody().mask('Loading...');
xhr.send(data);
}
Fortify is showing this error for this line
Error - "The http request at * line * must contain a user-specific secret in order to prevent an attacker from making unauthorized requests"
xhr.open('POST', url, true);
How do i resolve this fortify issue?
Is it something Fortify is highlighting because it doesn't have full context of the application.
In my application i have SSO setup which is passing a user specific secret with every request. But fortify may not be aware of it and ends up flagging this as an issue.
Kindly advice on what is best way to resolve this issue.
Thanks.

You need to add the setRequestHeader !!!
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(data);

Related

Laravel / Airlock AJAX login - 419 (unknown status)

I'm trying to do a cross origin login request and everything except logging in is working. So if I go to api.example.com and log in with the laravel app and then go to www.example.com I can get the user by calling the /api/user end point (setup as part of airlock). What I'm failing to do is log in via AJAX with username / password. Here is the JS used:
First I call setCSRFCookie()
function setCSRFCookie() {
let xhr = new XMLHttpRequest();
xhr.open('GET', domain+'/airlock/csrf-cookie');
xhr.withCredentials = true;
xhr.send(null);
}
Then I call loginUser()
function loginUser() {
let xhr = new XMLHttpRequest();
let params = 'username=m#example.com&password=password';
xhr.open('POST', domain + '/login', true);
xhr.withCredentials = true;
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
}
xhr.send(params);
}
I'm getting a 419 (unknown status) which appears to be Laravel's response for an invalid CSRF token. I looked at the actual request and both APP_NAME_session and XSRF-TOKEN are being passed as part of the request. The only thought I had was that the /login default auth route isn't setup for this and I need to do one under /api/login so it's served by the airlock middleware. I appreciate any help you can give.
Laravel 6.12.0
Airlock 0.1.0
Make sure api.example.com is included in config/airlock.php like this
'stateful' => [
'localhost',
'api.example.com'
],
And request middleware should be auth:airlock

Cannot call aws API Gateway via ajax

I am using aws APi gateway and api gateway custom authorizer. The code that I have for api gateway custom authorizer is as follows:
console.log('Loading function');
exports.handler = (event, context, callback) => {
var token = event.authorizationToken;
// Call oauth provider, crack jwt token, etc.
// In this example, the token is treated as the status for simplicity.
switch (token.toLowerCase()) {
case 'allow':
callback(null, generatePolicy('user', 'Allow', event.methodArn));
break;
case 'deny':
callback(null, generatePolicy('user', 'Deny', event.methodArn));
break;
case 'unauthorized':
callback("Unauthorized"); // Return a 401 Unauthorized response
break;
default:
callback("Error: Invalid token");
}
};
var generatePolicy = function(principalId, effect, resource) {
var authResponse = {};
authResponse.principalId = principalId;
if (effect && resource) {
var policyDocument = {};
policyDocument.Version = '2012-10-17'; // default version
policyDocument.Statement = [];
var statementOne = {};
statementOne.Action = 'execute-api:Invoke'; // default action
statementOne.Effect = effect;
statementOne.Resource = resource;
policyDocument.Statement[0] = statementOne;
authResponse.policyDocument = policyDocument;
}
// Can optionally return a context object of your choosing.
authResponse.context = {};
authResponse.context.stringKey = "stringval";
authResponse.context.numberKey = 123;
authResponse.context.booleanKey = true;
return authResponse;
as you can see it is just a simple mock up example provided in aws website.
Then I configured my get method in API gateway using this authorizer. Also in method execution I added a custom hedear called authorizationToken which will be used by authorizer.
When I use the postman everything is good:
However when I try to call it via ajax as follows I get the following error:
XMLHttpRequest cannot load https://590vv3bkda.execute-api.us-east-1.amazonaws.com/hamedstg/tjresource/story. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 401.
Here is my ajax call:
$.ajax(
'https://590vv3bkda.execute-api.us-east-1.amazonaws.com/xxxxxxx',
{
method : 'GET',
headers : {
'authorizationToken' : 'allow'
},
beforeSend : function(xhr) {
xhr.setRequestHeader('authorizationToken', 'allow');
}
}).then(function(data) {
console.log(data);
});
Also it is noteworthy that I enabled CORS on the api in aws.
Can anyone help?
Did you add any methods or resources since enabling CORS? If so, then run the CORS wizard again and redeploy to your stage.
Also, make sure that the OPTIONS method on your resource does not require/use the customer authorizer. OPTIONS needs to be open to all as the browser will call it on your behalf for pre-flight CORS checks in some cases.
There is also a known issue that when an API Gateway call fails for any reason, the CORS headers are not set and thus you'll get that "No 'Access-Control-Allow-Origin' header is present" error, when the root cause is something entirely different. Try turning on developer logging on your browser, get the exact request sent to the API (it may be an OPTIONS method) and try the same request as a test invoke from the API Gateway console. That will let you look at the output and the logs to determine if there is another issue.

Ionic 2 ASP APi token request

I'm Trying to retrieve a bearer token from my ASP API from my ionic2 app.
I have enabled CORS on the API as shown below:
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
This enabled me to form a POST request from my ionic 2 app to my API in order to register a user. This works wonderfully.
The request I used for this is as shown below:
let headers = new Headers({
'Content-Type': 'application/json'
});
let options = new RequestOptions({
headers: headers
});
let body = JSON.stringify({
Email: credentials.email,
Password: credentials.password,
ConfirmPassword: credentials.confirmPassword
});
return this.http.post('http://localhost:34417/api/Account/Register', body, options)
However when I try to retrieve a token from my API I receive the following error:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access.
The request I'm using to try and retrieve the token is as follows:
let body = "grant_type=password" + "&userName=" + credentials.email + "&password=" + credentials.password;
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
return this.http.post('http://localhost:34417/token', body, options)
This is the only request that is throwing this error, all other requests to my API work fine.
Have I missed anything, or am I doing something wrong?
var cors = new EnableCorsAttribute("*", "*", "*");
Looks like you are setting Access-Control-Allow-Origin as *.
Check MDN CORS Requests with credentials.
Credentialed requests and wildcards
When responding to a credentialed request, the server must specify an
origin in the value of the Access-Control-Allow-Origin header, instead
of specifying the "*" wildcard.
You will have to set a specific url if you use credentials.
Or if you only intend to use only for ionic 2, you could avoid the cors issue by setting a proxy.
According to the official blog:
The proxies settings contain two things: the path you use to access them on your local Ionic server, and the proxyUrl you’d ultimately like to reach from the API call.
{
"name": "ionic-2-app",
"app_id": "my_id",
"proxies": [
{
"path": "/api",
"proxyUrl": "http://localhost:34417/api"
}
]
}
Ionic serve command by default will start server on localhost:8100.
The set proxy will hit your http://localhost:34417/api.
Your path in the requests will be to the localhost:8100/api instead of your actual server.

Access denied in IE 10 and 11 when ajax target is localhost

I'm trying to do a ajax call between a server (http) that is on internet. And target that to my own localhost. FF/Chrome/ ETC... works. It's ONLY an IE issue. IM USING IE 11 AND 10.
The request is don't even done. The "denied access" is thrown instantly.
This is the code. Just for you to see.
Is not the classical HTTP/HTTPS error in IE8 AND IE9. This is something else, but the documentation is not helpful.
$jq.ajax({
contentType: 'application/json',
url: url,
dataType: 'json',
crossDomain: true,
beforeSend: function (xhr) {
xhr.withCredentials = true;
xhr.setRequestHeader("Authorization", "Basic " + $jq.base64.encode(username and password));
},
success: function (data, status, headers) {},
error: function (xhr, status, error) {}
The status is 0 in xhr object and error is "Denied access"
Internet Explorer raises this error as part of its security zones feature. Using default security settings, an "Access is Denied" error is raised when attempting to access a resource in the "Local intranet" zone from an origin in the "Internet" zone.
If you were writing your Ajax code manually, Internet Explorer would raise an error when you try to open the resource. For example:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost/', true); // This line will trigger an error
xhr.send();
You can work around this error by adding the origin site to the "Trusted sites" security zone. You can test this by adding "http://client.cors-api.appspot.com" to your "Trusted sites" zone and using this test page at test-cors.org with your localhost site as the Remote URL.
In addition to the trusted site requirement I found that the problem was not fixed until I used the same protocol for the request as my origin, e.g. my test site was hosted on a https but failed with any destination using http (without the s).
This only applies to IE, Chrome just politely logs a warning in the debug console and doesn't fail.
If you are attempting to make cross-origin ajax requests in IE9, you'll need to use XDomainRequest instead of XMLHttpRequest. There is a jQuery plug-in that wraps XDR. You should be aware that there are some notable limitations of XDR.
Another option would be to use a library like this: https://github.com/jpillora/xdomain.
jQuery implements ajax calls using the XMLHttpRequest object which is not supported in IE9. You have to force it to use XDomainRequest instead.
I get around this problem using this jQuery plugin:
https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest
Note:
Do not use "http://www.domain.xxx" or "http://localhost/" or "IP" for URL in Ajax.
Only use path(directory) and page name without address.
false state:
var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'http://www.example.com/dir/getSecurityCode.php', true);
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
true state:
var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'dir/getSecurityCode.php', true); // <<--- note
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
function createAjax()
{
var ajaxHttp = null;
try
{
if(typeof ActiveXObject == 'function')
ajaxHttp = new ActiveXObject("Microsoft.XMLHTTP");
else
if(window.XMLHttpRequest)
ajaxHttp = new XMLHttpRequest();
}
catch(e)
{
alert(e.message);
return null;
}
//-------------
return ajaxHttp;
};

xhr sending requests to specific port?

I am very new to ajax development, I am trying to use xhr to get and post data,the problem is when I use port based requests?
here is my working code and not working codes
$.ajax({
url : "login.php",
type : "post",
data : {
userProfile : JSON.stringify(data)
},
success : handleDBResponse,
error : function(jqXHR, textStatus,errorThrown) {
console.log("The following error occured: "+ textStatus,errorThrown);
},
complete : function() {
// console.log("user authentication
// successful.")
}
});
this works good, but when I am using native xhr with url:port getting no response.
function reqListener () {
console.log(this.responseText);
};
var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.open("get", "http://www.domain.com:443/akorp.css", true);
oReq.send();
It's not working, I was debugged and I found request status is cancelled.
.htaccess file included
Access-Control-Allow-Origin:*
still I am getting the error
www.domain.com:443 not allowed by www.domain.com Access-Control-Allow-Origin etc..
what are the possible causes for this error and how to properly send request to port?
443 is the HTTPS port. Perhaps you should try an HTTPS URL instead of forcing the port.
I'm not sure I want to know why you're pulling a CSS file from somebody else's serer with xhr.

Resources