My swagger yaml for an endpoint request object looks like
auth.LoginGoogleRequest:
properties:
id_token:
type: string
required:
- id_token
type: object
which means hit the endpoint with body with
{"id_token": "someid-1234"}
So I used
rm -rf src/generated-sources/openapi; openapi-generator-cli generate -i ../memesgen-backend/pkg/docs/swagger.yaml -o src/generated-sources/openapi -g typescript-fetch --additional-properties=supportsES6=true,npmVersion=6.9.0,typescriptThreePlus=true
It generated the functions for me however its returning the wrong body value by accessing an unnecessary property
export function AuthLoginGoogleRequestToJSON(value?: AuthLoginGoogleRequest | null): any {
if (value === undefined) {
return undefined;
}
if (value === null) {
return null;
}
return {
'id_token': value
};
}
did i configure the yaml wrong?
Related
We have an application which is already in production where an IDOR vulnerability was detected in an endpoint "CustomerKey". This contains customer ID which when used brute force allowed for session take over in our app.
Now we can't encrypt this as it might make the app slow as the CustomerKey is being used many times in the JS as well as backend. Our app allows many users to login at the same time we are using signalR in the app as well.
Some sample backend code where this CustomerKey is being used :
[HttpPost]
[AllowAnonymous]
public JsonResult UpLoadLog(string CustomerKey, string message)
{
try
{
var log = message.Split(new string[] { "\r\n" },
StringSplitOptions.RemoveEmptyEntries);
foreach (string s in log)
{
Logger.Write(LogType.Info, this.GetType(), "UpLoadLog", CustomerKey + ": "
+ s.TrimStart('\r', '\n'), null);
}
}
catch (Exception ex)
{
Logger.Write(LogType.Fatal, this.GetType(), "UpLoadLog", ex.Message, ex);
}
HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.OK;
return null;
}
[AuthorizeUser]
public ActionResult Customer(string CustomerKey, string FeedData, string FeedInfo)
{
if (string.IsNullOrEmpty(CustomerKey))
{
var owinContext = Request.GetOwinContext();
CustomerKey = owinContext.Get<string>("CustomerKey");
FeedData = owinContext.Get<string>("FeedData");
FeedInfo = owinContext.Get<string>("FeedInfo");
}
ViewBag.CustomerKey = CustomerKey;
ViewBag.FeedData = FeedData;
ViewBag.FeedInfo = FeedInfo;
ViewBag.UseSignalR = true;
ViewBag.isOffline = true;
return View("Offline", "CustomerLayout");
}
Sample js code where CustomerKey is being used:
var UpLoadLog = function (log, isAsync) {
if (isAsync== null || isAsync== undefined)
isAsync= true;
jQuery.ajax({
type: "POST",
async: isAsync,
contentType: "application/json;charset=utf-8",
url: rooturl + "Authentication/UpLoadLog",
data: JSON.stringify({ CustomerKey: jQuery("#customerKey").val(), message: "\r\n\r\n" + log + "\r\n\r\n" }),
dataType: "json",
success: function (response, status, jqXHR) {
},
error: function (jqXHR, status, error) {
}
});
LogMessages = "\r\n\r\n";
};
The app also contains a hidden field in the layout where the value of CustomerKey is being used
<input type="hidden" id="customerkey" value="#ViewBag.CustomerKey"/>
What I need help is how can I resolve this vulnerability without making huge changes in the application?
If I understood the problem correctly, then it lies in the fact that anyone can send a request with any CustomerKey, and get a response by CustomerKey, even if they are not authorized to receive such information.
If the information about the CustomerKey is associated with authorization filters (AuthorizeUser), then, in my opinion, the least time-consuming way to solve the problem would be to compare the CustomerKey with the corresponding property of the authorized user. And if the keys don't match, throw an exception.
To talk about specific lines of code, I need, in fact, to work with the project and have access to all the source code.
You could enter a third parameter which is the md5() of the CustomerKey parameter. This way when the method is contacted, it checks if the md5 parameter is really the md5 of the CustomerKey parameter, if so it writes the log. It is a sort of checksum made on the first parameter which guarantees that only those who know this rule can save logs. This can be an example of the new method signature
[HttpPost]
[AllowAnonymous]
public JsonResult UpLoadLog(string CustomerKey, string message, string md5)
This instead a way to calculate md5:
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
string calculatedMd5 = Convert.ToHexString(hashBytes);
}
I'm trying to return a list of my model sorted by date. But I run into a vague error.
Here is my graphql.schema
type Vote #model(timestamps: { createdAt: "created_at", updatedAt: "updated_at" }) {
id: ID!
name: String!
date: AWSTimestamp #index(name: "date-index", sortKeyFields: ["name"], queryField: "getVotesByDate")
}
Here is the request:
Future<List<Vote?>> recentVotes() async {
const getRecentVotes = "getRecentVotes";
String document = """
query getRecentVotes {
listVotes(limit: 5) {
items {
date
id
name
}
nextToken
}
}
""";
try {
final request = GraphQLRequest(
document: document,
modelType: Vote.classType,
decodePath: getRecentVotes,
);
final response = await Amplify.API.query(request: request).response;
List<Vote?>? votes = response.data?.items;
if (votes == null) {
return [];
}
_voteLength = votes.length;
return votes;
} catch (err) {
debugPrint(err.toString());
}
return [];
}
The error I get back is pretty terrible:
flutter: ApiException(message: The HTTP response status code is [400]., recoverySuggestion: The metadata associated with the response is contained in the HTTPURLResponse.
flutter: For more information on HTTP status codes, take a look at
flutter: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes, underlyingException: null)
As best I can tell, it's just a standard bad request error but with no message of what makes it bad. The graphql syntax is valid and tested.
*Edit
I've managed to restart the app which provided more details about the error. With the same code, I now get
flutter: type 'Null' is not a subtype of type 'String'
My first thought after this is that there's some returned field that is null that cannot be. I've checked the name and the id of all the records in the database and they are not null so I'm not sure how that's possible.
I'm trying to get file uploads to work in my Laravel Nova on a Vapor server.
When I try to upload, it keeps showing me a 401 response on /vapor/signed-storage-url.
What am I missing?
This is my Nova Resource:
public function fields(Request $request)
{
return [
VaporFile::make('Attachment')->rules('bail', 'required', function ($attribute, $value, $fail) use ($request) {
if (Storage::size($request->input('vaporFile')[$attribute]['key']) > 1000000) {
return $fail('The document size may not be greater than 1 MB');
}
}),
This is added to my app.js:
window.Vapor = require("laravel-vapor");
This is my registered policy:
class UserPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can upload files.
*
* #param \App\User $user
* #return mixed
*/
public function uploadFiles(User $user)
{
return true;
}
Looks to me I've done everything correctly.. but it still fails.
I'm trying to send a GET request to Binance's API, but I don't exactly know how to.
Here is the documentation page: https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#account-information-user_data
I have a private apiKey and secretKey.
I can do a general request to Binance, but I cannot get my private data, using my private keys.
First try:
For the GET request in Postman I use this string:
https://api.binance.com/api/v3/account?timestamp=1499827319559&signature=here_I_put_my_secret_key
And I pass as a header as Danny suggested the apiKey.
But I get:
{
"code": -1021,
"msg": "Timestamp for this request is outside of the recvWindow."
}
Thanks.
I solved this correcting the time using javascript in Postman.
Another easy fix is to use the ccxt library : https://github.com/ccxt/ccxt
This might be what you're after, as per the documentation.
https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#endpoint-security-type
API-keys are passed into the Rest API via the X-MBX-APIKEY header.
In your Request, add that as the header key and your API Key as the value.
You can try this. This is working for me. Just Replace your API_KEY and SECRET
You need to retrieve serverTime time from https://api.binance.com/api/v3/time and need to use that serverTime to sign the request.
GET : https://api.binance.com/api/v3/account?timestamp={{timestamp}}&signature={{signature}}
Header:
Content-Type:application/json
X-MBX-APIKEY:YOUR_API_KEY
Pre-request Script :
pm.sendRequest('https://api.binance.com/api/v3/time', function (err, res) {
console.log('Timestamp Response: '+res.json().serverTime);
pm.expect(err).to.not.be.ok;
var timestamp = res.json().serverTime;
postman.setEnvironmentVariable('timestamp',timestamp)
postman.setGlobalVariable('timestamp',timestamp)
let paramsObject = {};
const binance_api_secret = 'YOUR_API_SECRET';
const parameters = pm.request.url.query;
parameters.map((param) => {
if (param.key != 'signature' &&
param.key != 'timestamp' &&
!is_empty(param.value) &&
!is_disabled(param.disabled)) {
paramsObject[param.key] = param.value;
}
})
Object.assign(paramsObject, {'timestamp': timestamp});
if (binance_api_secret) {
const queryString = Object.keys(paramsObject).map((key) => {
return `${encodeURIComponent(key)}=${paramsObject[key]}`;
}).join('&');
console.log(queryString);
const signature = CryptoJS.HmacSHA256(queryString, binance_api_secret).toString();
pm.environment.set("signature", signature);
}
function is_disabled(str) {
return str == true;
}
function is_empty(str) {
if (typeof str == 'undefined' ||
!str ||
str.length === 0 ||
str === "" ||
!/[^\s]/.test(str) ||
/^\s*$/.test(str) ||
str.replace(/\s/g,"") === "")
{
return true;
}
else
{
return false;
}
}
}
);
Get the official Postman collections for the Binance API from here:
https://github.com/binance/binance-api-postman
Import the desired collection and environment in Postman, for instance
binance_spot_api_v1.postman_collection.json
and binance_com_spot_api.postman_environment.json
Add your API key to the binance-api-key environment variable and your secret key to the binance-api-secret variable.
CAUTION: Limit what the key can do in Binance key management. Do not use this key for production, only for testing. Create new key for production.
For the signed requests calculate the signature in a Pre-request Script then set the signature environment variable.
Example Pre-request Script:
function resolveQueryString() {
const query = JSON.parse(JSON.stringify(pm.request.url.query))
const keyPairs = []
for (param of query) {
if (param.key === 'signature') continue
if (param.disabled) continue
if (param.value === null) continue
const value = param.value.includes('{{') ? pm.environment.get(param.key) : param.value
keyPairs.push(`${param.key}=${value}`)
}
return keyPairs.join('&')
}
const signature = CryptoJS.HmacSHA256(
resolveQueryString(),
pm.environment.get('binance-api-secret')
).toString(CryptoJS.enc.Hex)
pm.environment.set('signature', signature)
ok this is something that start to show a few weeks ago, I have a parse server running on an ubuntu machine with version 2.3.3, I have a bunch of cloud functions running, nothing fancy just querying some specific Class, all the data in that class is public and all work most of the time just fine. However from time to time, calling a cloud function start to return invalid sessions error 209, even with a user logged or not, super weird, but what is even strange is that when that happens no one else can run the function, and every user start to got the same error.
The only way I can make it work again is restarting the server, also only happens with cloud functions and from the ios app, I saying this cause we have some other part calling functions from php but it seems those are not starting the problem
2017-02-21T01:26:57.676Z - Failed running cloud function partnersv2 for user undefined with:
Input: {"k":"","searchType":"","category":"comida"}
Error: {"code":141,"message":{"code":209,"message":"invalid session token"}}
2017-02-21T01:26:57.669Z - invalid session token
2017-02-21T01:26:55.738Z - ParseError { code: 209, message: 'invalid session token' }
2017-02-21T01:26:55.737Z - Error generating response. ParseError {
code: 141,
message: ParseError { code: 209, message: 'invalid session token' } }
I have no idea why is this happening, also I don't think is related to the legacy session cause this server and the user are new, we start developing this a few months ago is not a ported app from the old service
One thing we are doing a lot is removing from the dashboard sessions at will, cause we are testing and developing, not sure if this could be a reason, but what about when the user is undefined, it shouldn't even try to use session I think, or maybe a user that was actually logged could be the culprit, setting the server to VERBOSE is not telling anything else as well, just the params and the call which it doesn't look weird to me, am looking for someone that maybe can put me in the right direction of maybe how the session work or something, thank you for any help
EDIT 1:
This is the cloud function that is trowing the error
Parse.Cloud.define('partnersv2', function (req, res) {
var searchType = req.params.searchType,
k = req.params.k,
category = req.params.category,
query;
query = new Parse.Query('Partner');
query.addDescending('is_open');
query.equalTo('enabled', true);
query.equalTo('category', category);
query.select(['name', 'phone', 'delivery_eta', 'keys', 'price_range', 'is_new', 'cover', 'recommended', 'open_time', 'min_order', 'delivery_rank', 'logo', 'comingsoon', 'category', 'is_open']);
if (searchType !== '' && searchType !== undefined && k !== '' && k !== undefined) {
if (searchType === 'Tag') {
query.equalTo('tags', k);
} else {
query.equalTo('name', k);
}
}
query.limit(1000);
query.find({
success: function (results) {
if (results.length > 0) {
res.success(results);
} else {
res.error('404 not found');
}
},
error: function (error) {
res.error(error);
}
});
});
and this is a screenshot of the ACL col
Use Master Key
Parse.Cloud.define('partnersv2', function (req, res) {
//var token = req.user.getSessionToken() // getSession Token return r: (yourkey);
var searchType = req.params.searchType,
k = req.params.k,
category = req.params.category,
query;
query = new Parse.Query('Partner');
query.addDescending('is_open');
query.equalTo('enabled', true);
query.equalTo('category', category);
query.select(['name', 'phone', 'delivery_eta', 'keys', 'price_range', 'is_new', 'cover', 'recommended', 'open_time', 'min_order', 'delivery_rank', 'logo', 'comingsoon', 'category', 'is_open']);
if (searchType !== '' && searchType !== undefined && k !== '' && k !== undefined) {
if (searchType === 'Tag') {
query.equalTo('tags', k);
} else {
query.equalTo('name', k);
}
}
query.limit(1000);
query.find({
useMasterKey: true, // sessionToken: token
success: function (results) {
if (results.length > 0) {
res.success(results);
} else {
res.error('404 not found');
}
},
error: function (error) {
res.error(error);
}
});
});