Accept Trade Offer from Steam using Web-API & Java - java

I have a Java Steam Trade Bot that reads through pending Trade Offers from Steam and declines them based on requirements. I am using the official Web API (using the API Key from http://steamcommunity.com/dev/apikey) to communicate requests to Steam. The variable trade is from my own API Interface (which I have debugged and works for declining offers).
SteamPlug.steamRequest(method, query); is just a basic HTTP requester:
public static String steamRequest(String method, String query) {
try {
URL obj = new URL(query);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod(method);
int responseCode = con.getResponseCode();
if (responseCode != 200 && responseCode != 201) {
return "ERR" + responseCode;
}
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
} catch (MalformedURLException | ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
// Ignored
}
return null;
}
This is how it declines trade offers:
SteamPlug.steamRequest(
"POST",
"http://api.steampowered.com/IEconService/DeclineTradeOffer/v0001/?key="
+ SteamPlug.API_KEY + "&tradeofferid=" + trade.getTradeOfferId()
);
What I am trying to do is accepting trades as well. I have tried this:
SteamPlug.steamRequest(
"POST",
"https://steamcommunity.com/tradeoffer/" + trade.getTradeOfferId() + "/accept?key="
+ SteamPlug.API_KEY
);
But I receive a 411 Length Required response.
I believe I can accept offers by using a Steam session authentification, but is it possible to accept a Trade Offer using only the user's Web-API key?

Have you read steam API docs? There's no trade accept function, so I assume you can't accept trades via API.
Your option is to check SteamBot's (though it is written in C#) trade functions and think about straight http requests to steam site (with proper steam authentication I believe). I myself writing a bot currently, and single thing that stops me now - accepting trades.

Related

Reflected XSS on BufferedReader readLine() method

I have scanned a java web project with the Checkmarx tool, and the analysis marks an XSS vulnerability in a method where a web service is executed that responds a JSON, the vulnerability is in the line while((output = Encode.forJava(br.readLine())) != null) {, specifically in br.readLine().
Checkmarx says:
The attacker would be able to alter the returned web page by simply
providing modified data in the user input readLine, which is read by
the NetClientPost method. This input then flows through the code
straight to the output web page, without sanitization.
This can enable a Reflected Cross-Site Scripting (XSS) attack.
I tried with OWASP for Java, implementing the method Encode.forJava(), but the vulnerability continues to appear in the analysis. This is the implementation of the method:
public String NetClientPost (String urlSer, String param){
String result ="";
try {
InetAddress ip = InetAddress.getLocalHost();
String host = ip.getHostAddress();
doTrustToCertificates();
URL url = new URL(urlSer);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setConnectTimeout(2000);
String input = param;
String output = "";
try(OutputStream os = conn.getOutputStream()) {
os.write(input.getBytes());
os.flush();
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP code : " + conn.getResponseCode());
}
try (BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())))) {
while ((output = Encode.forJava(br.readLine())) != null) {//LINE OF CHECKMARX XSS
result += output;
}
}
}
conn.disconnect();
return result;
} catch (MalformedURLException e) {
return result;
} catch (IOException e) {
return result;
} catch (Exception e) {
return result;
}
}
Any have an idea of how to solve this?
Try parsing the incoming data as JSON and then serializing it back to a string before sending it on.
That way you can be sure that your method only returns JSON to the client. If for some reason, your incoming data isn't JSON, then your method would encounter an error parsing the JSON, which you can then handle appropriately.
Encode.forJava isn't a helpful method to use here: it is used to encode a string to be inserted into a Java string literal.
output = Encode.forHtmlAttribute(br.readLine() works for me

Microsoft Graph: Requesting an Extension returns http 400 bad request

I added an open extension to an event in a calendar and am trying to read it back.
Here is the url:
https://graph.microsoft.com/v1.0/users/{userid}/calendars/{calendarId}=/events?$expand=Extensions($filter=Id eq 'c.i.m.p.server.entities.outlook.Event')
I cannot get this to work in a Java program. The following combinations do work:
It works my Java program if I remove the $expand... parameter. I can also ask for certain fields, that works too.
The request works in Postman (I just have to set the token)
The request works in Graph Explorer when I log in as the owner of the calendar
Here is the extension (inside one of the events) when I use Postman to read the event. It is the last item in the event:
"extensions#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('{userid}')/calendars('{calendarId}')/events('{eventId})/extensions",
"extensions": [
{
"#odata.type": "#microsoft.graph.openTypeExtension",
"id": "Microsoft.OutlookServices.OpenTypeExtension.c.i.m.p.server.entities.outlook.Event",
"extensionName": "c.i.m.p.server.entities.outlook.Event",
"adherentId": "12346",
"timeSlotID": "346463"
}
]
Here is the Java code (Java 8, using java.io and java.net libraries):
private static void doSomething(String _accessToken) throws IOException {
String urlString = "https://graph.microsoft.com/v1.0/users/{userId}/calendars/{calendarId}/events?$expand=Extensions($filter=Id eq 'c.i.m.p.server.entities.outlook.Event')";
URL url = new URL(urlString);
Proxy webProxy
= new Proxy(Proxy.Type.HTTP, new InetSocketAddress({proxy-address}, {port}));
HttpURLConnection connection = (HttpURLConnection) url.openConnection(webProxy);
// Set the appropriate header fields in the request header.
connection.setRequestProperty("Authorization", "Bearer " + _accessToken);
connection.setRequestProperty("Accept", "application/json");
connection.setDoOutput(true);
connection.setReadTimeout(5000);
connection.setRequestMethod(HttpMethod.GET);
try {
connection.connect();
int responseCode = connection.getResponseCode();
System.out.println("execute(), response code = " + responseCode);
String responseMessage = connection.getResponseMessage();
System.out.println("execute(), response Message = " + responseMessage);
String responseString = null;
try {
InputStream ins = connection.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(ins));
StringBuffer sb=new StringBuffer();
String line;
while ((line=br.readLine()) != null) {
sb.append(line);
}
responseString = sb.toString();
} catch (Exception e) {
System.out.println("Could not get input stream from response, error is " + e.toString());
}
System.out.println("execute(), httpResult = " + responseString);
} catch (IOException e) {
System.out.println(".execute(), IOException : " + e.toString());
} finally {
connection.disconnect();
}
}
How do I fix this? Thanks!
400 means bad request. It could be because of url encoding. Url encode the query string.
Something like
String query = "Extensions($filter=Id eq 'c.i.m.p.server.entities.outlook.Event'";
String url = "https://graph.microsoft.com/v1.0/users/{userId}/calendars/{calendarId}/events?
$expand=" + URLEncoder.encode(query, StandardCharsets.UTF_8.name());
Alternatively you could use graph service java api based on your need which will help abstract all the interactions for you or you could use any of the rest clients available.
First of all, you should provide more info on the error - Stacktrace and error message. But 400 code indicates that was a user mistake, meaning that you are sending an invalid request. Since you say that postman request works then compare all the headers that are sent by postman and see if your code misses some hearer. As for the code, instead of coding your own Http client functionality I would suggest using 3d party Http client. Here are a few suggestions:
Apache Http client - very popular and well known 3d party Http Client
OK Http client - Open-source Http client. Here is tutorial
MgntUtils Http client - very simple 3d party HttpClient: Provided in MgntUtils Open source library (written by me). Very simple in use. Take a look at Javadoc. Library itself provided as Maven artifacts and on Git (including source code and Javadoc).

How to make multiple API calls in a efficient way in java

I have a list of 100k users. I have to loop through the list and make an API call to the server to get the result. Every time I create a new URL connections and making the APi call then closing the connection once I read the input stream, but it is taking too much time.
Is there any optimized way to do it, like using the same instance of URL connection multiple times instead of closing it? or going for another third-party library will improve the speed of execution?
I am calling the below method in my loop to get the output.
private String getOutput(String loginName) {
String responseStatus = null;
HttpURLConnection connection = null;
try {
URL url= new URL(<<https://api.junk.123.com/output>>);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("apikey", "authentication key");
connection.setUseCaches(false);
connection.setDoOutput(true);
//Send request
try(DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())){
JsonObject jsonParam = new JsonObject();
jsonParam.putString("loginName", "loginName");
outputStream.writeBytes(jsonParam.toString());
outputStream.flush();
}
//Get response
InputStream inputStream;
if(connection.getResponseCode() == HttpURLConnection.HTTP_OK){
inputStream = connection.getInputStream();
} else {
inputStream = connection.getErrorStream();
}
if(null == inputStream){
return String.valueOf(connection.getResponseCode());
}
StringBuilder response = new StringBuilder();
try (BufferedReader inputBuffer = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while (null != (line = inputBuffer.readLine())) {
response.append(line);
response.append("\r");
}
}
JsonObject jsonObject = new JsonObject(response.toString());
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
responseStatus = "success";
} else {
responseStatus = String.valueOf(connection.getResponseCode()) + jsonObject.getString("errorMessage") ;
}
} catch (MalformedURLException e) {
logger.error("Malformed URL exception occurred while calling the API", entry.getKey(), e);
} catch (IOException e) {
logger.error("Creation of connection failed while calling the API", entry.getKey(), e);
} catch (Exception e) {
logger.error("Error occurred while calling the API", entry.getKey(), e);
} finally {
if (null != connection){
connection.disconnect();
}
}
return responseStatus;
}
This Q&A explains that HTTP persistent connections are implemented behind the scenes by HttpURLConnection:
Persistent HttpURLConnection in Java
However, that may not be sufficient. If you use a single client-side thread to do the fetching you are limited by the round trip time for the requests; i.e. you can't start a second request until the result of the first one has been returned to you. You can remedy this ... up to a point ... by using multiple client-side threads.
However (#2) sending multiple requests in parallel also has its limits. Beyond a certain point you will saturate the client, the server or the network. In addition, some servers have throttling mechanisms to cap the number of requests that a client can make.
The way to get maximum throughput would be to redesign the API so that a single request can get information for multiple users.

How i can get connected with qc 12 with rest api

Can u please help me to understand with simple piece of java code to get connect wth qc 12 using rest api.
I gone thorough the rest api documentation but am not clear with how to start with.but it will be helpful if people can show me a simple java code for authentication(login,logout or getting defect details) using rest api. Also want to know do i need to include any jars in my build path.
Thanks a lot friends.
I don't quite get what you're asking, but if you want to connect to a REST API, there are several ways... I usually use HttpURLConnection, here's an example of a get:
public String getProfile(String URL) throws IOException {
URL getURL = new URL(url);
//Establish a https connection with that URL.
HttpURLConnection con = (HttpURLConnection) getURL.openConnection();
//Select the request method, in this case GET.
con.setRequestMethod("GET");
//Add the request headers.
con.setRequestProperty("header", headerValue);
System.out.println("\nSending 'GET' request to URL : " + url);
int responseCode;
try {
responseCode = con.getResponseCode();
System.out.println("Response Code : " + responseCode);
} catch (Exception e) {
System.out.println("Error: Connection problem.");
}
InputStreamReader isr = new InputStreamReader(con.getInputStream());
BufferedReader br = new BufferedReader(isr);
StringBuffer response = new StringBuffer();
String inputLine;
while ((inputLine = br.readLine()) != null) {
//Save the response.
response.append(inputLine + '\n');
}
br.close();
return response.toString();
}

send http request to linux server

I have to send an HTTP request to our C programme which is running on a Linux machine. How can I send an HTTP request in Java to our server which is in C and running on a Linux machine?
public void sendPostRequest() {
//Build parameter string
String data = "width=50&height=100";
try {
// Send the request
URL url = new URL("http://www.somesite.com");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
//write parameters
writer.write(data);
writer.flush();
// Get the response
StringBuffer answer = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
answer.append(line);
}
writer.close();
reader.close();
//Output the response
System.out.println(answer.toString());
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
The above example is for sending a POST request using a URL.
If you're asking how to send an HTTP request in Java to a web server written in C, you can use the URLConnection class.
try {
// Construct data
String data = URLEncoder.encode("key1", "UTF-8") + "=" + URLEncoder.encode("value1", "UTF-8");
data += "&" + URLEncoder.encode("key2", "UTF-8") + "=" + URLEncoder.encode("value2", "UTF-8");
// Send data
URL url = new URL("http://hostname:80/cgi");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
// Process line...
}
wr.close();
rd.close(); } catch (Exception e) { }
The above example is for sending a POST request using a URL.
Also take a look at Sun Tutorial on reading/Writing from/to a URLConnection. The other option is to use Apache HTTPComponents which has examples for the HttpCore and HttpClient module.
If you are looking into implementing the web Server, you will have to handle the Http request yourselves which involves a thread pool, parsing the requests, generating HTML, security, multiple sessions, etc or follow the easy route by using off-the-shelf web server like Apache and seeing which all high-level languages like Perl, Ruby can be used for developing the web application.
For implementing your own Http server, please take a look at Micro-Httpd or tinyHttpd
You may also want to look at Adding Web Interface -C++ application which has a sample code.
From the way your question is worded.. I think you need to know some basic stuff before you can start. Try try googling for a simple guide to how web servers work.
Once you have the basic idea, there are a couple of options for a C programmer:
1) You want your C program to be running continuously, waiting for a request from your Java.
In this case, you will have to code your C program to open a Socket and Listen for connections. See http://www.linuxhowtos.org/C_C++/socket.htm for example.
OR
2) You have a web Server on your server which will run your C program each time a particular request is made? In this case, you will have to code your C as a CGI program. See http://www.cs.tut.fi/~jkorpela/forms/cgic.html for example.
Hint: (2) is much easier!

Categories