I am trying to login to a website using java.net in Google App Engine for Java.
The login id and password are stored in variables 'loginid' and 'password' respectively.
The code that I have created is given below:
public Integer login()
{
String param1="", param2="", query="";
String charset = "UTF-8";
String loginurl = "https://website.com/login";
try {
param1 = URLEncoder.encode(loginid, "UTF-8");
param2 = URLEncoder.encode(password, "UTF-8");
query = String.format("username=%s&password=%s",
URLEncoder.encode(param1, charset),
URLEncoder.encode(param2, charset));
} catch (UnsupportedEncodingException ex) {
// ...
}
try {
URL url = new URL(loginurl + "?" + query);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line="";
String resp="";
while ((line = reader.readLine()) != null) {
resp=resp + line;
}
actionmessage=" Response-" + resp;
return(1);
}
catch (Exception e) {
// ...
}
}
I want to know more about a couple of things with ref to above code.
I am sure that I have entered correct ID and password, but still I am getting login failure. What is wrong with the above code?
How do I check if a submission as made by above code is successful or if there is an error? If there is an error, how do I get the error stream?
It was an error on my part- I encoded the 2 parameters passed to input url, twice!! So the site where I was authenticating, received a garbled value for user id and password!
Related
I am working on an English dictionary using an online free API: https://api.dictionaryapi.dev/api/v2/entries/en_US/
The code was working fine just one month ago, but now the returned data is always "error". It is not giving back response :: 200. Could anyone tell me what's wrong with the code?
public String getOnlineData(String word){
String data = "";
String decodeData = "";
try{
URL url = new URL("https://api.dictionaryapi.dev/api/v2/entries/en_US/"+word);//store the url link in the variable url
HttpURLConnection con = (HttpURLConnection)url.openConnection();//start a new connection
if(con.getResponseCode()==200){
InputStream im = con.getInputStream();//store the text result in the variable im
BufferedReader br = new BufferedReader(new InputStreamReader(im));
//read the result using bufferedreader
String line=br.readLine();//read each line
while(line!=null){//stop until there is no line to read
data = data + line;
line=br.readLine();
}
br.close();//close the buffered reader
decoder jd = new decoder();//decode the result
decodeData = jd.Decoder(data);//store the decoded result in decodeData
}
else{
decodeData="error";//if the system doesn't get response, the result will be error
}
}
catch(Exception e){
try{
decodeData="error";//if the connection failed, result is error
System.out.println(e);
}
catch(Exception e1){
System.out.println(e1);
}
}
return decodeData;
}
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
I'm writing a Java application that communicates with the NASA open apis. I've a class named NASAClient which exposes the required interface to achieve this task, but I'm facing with the following problem when dealing with the Earth Imagery API.
public EarthImageryResponseObject earthImagery(double lon, double lat, String year, String mon, String day, boolean cloud_score) {
String cs;
if(cloud_score) cs = "True";
else cs = "False";
String url = "https://api.nasa.gov/planetary/earth/imagery?lon="
+ lon
+ "&lat="
+ lat
+ "&date="
+ year+"-"+mon+"-"+day
+ "&cloud_score="
+ cs
+ "&api_key=" + api_key;
try {
String json = (read(getConnection(url)));
return gson.fromJson(json, EarthImageryResponseObject.class);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private String read(HttpURLConnection conn) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
return readFromBufferedReader(br);
}
private String readFromBufferedReader(BufferedReader br) throws IOException {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
}
return sb.toString();
}
private HttpURLConnection getConnection(String url) throws IOException {
HttpURLConnection connection;
connection = createConnection(url);
this.availability = connection.getHeaderField("X-RateLimit-Remaining");
connection.setConnectTimeout(2000);
this.last_resp = connection.getResponseCode();
return connection;
}
private HttpURLConnection createConnection(String url) throws IOException {
URL UniformResourceLocation = new URL(url);
return (HttpURLConnection) UniformResourceLocation.openConnection();
}
When I call earthImagery with some standard parameters, I get the following url:
https://api.nasa.gov/planetary/earth/imagery?lon=100.75&lat=1.5&date=2017-01-01&cloud_score=False&api_key=[MY_KEY]
If I navigate to this url using curl or the browser, I get the expected Json serialized object, but when invoked within my application, I get a redirection link (with 301 response code) to an heroku app:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><title>Redirecting...</title><h1>Redirecting...</h1><p>You should be redirected automatically to target URL: http://earth-imagery-api.herokuapp.com/earth/imagery/?lon=100.75&lat=1.5&date=2017-01-01&cloud_score=False. If not click the link.
If I try to open a connection to such link, as explained here ,or open it in a browser it returns an error message (parameters are wrong). Really don't know what I am doing wrong. This strategy is the same for the other API I'm using in the application, and they work. Here it follows the stacktrace
Exception in thread "Thread-1" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
at com.google.gson.Gson.fromJson(Gson.java:927)
at com.google.gson.Gson.fromJson(Gson.java:892)
at com.google.gson.Gson.fromJson(Gson.java:841)
at com.google.gson.Gson.fromJson(Gson.java:813)
at com.alexfoglia.nasaapi.NASAClient.earthImagery(NASAClient.java:151)
at com.alexfoglia.nasaapi.gui.EarthPanel.lambda$2(EarthPanel.java:127)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:215)
... 7 more
And that's because i'm expecting a Json object, but I get a String (html redirect page).
If you want your code to automatically follow redirects then set this flag
connection.setFollowRedirects (true);
https://developer.android.com/reference/java/net/HttpURLConnection.html#setFollowRedirects(boolean)
I solved using both HttpURLConnection and SSLSocket. The first connection obtain the redirect link, that is reached not by another httpurlconnection, instead, a SSLSocket is used to get to this link.
public EarthImageryResponseObject earthImagery(double lon, double lat, String year, String mon, String day, boolean cloud_score) {
String cs;
if(cloud_score) cs = "True";
else cs = "False";
String url = "https://api.nasa.gov/planetary/earth/imagery?lon="
+ lon
+ "&lat="
+ lat
+ "&date="
+ year+"-"+mon+"-"+day
+ "&cloud_score="
+ cs
+ "&api_key=" + api_key;
try {
HttpURLConnection conn = getConnection(url);
String new_url = conn.getHeaderField("Location");
SSLSocketFactory factory =
(SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket socket =
(SSLSocket)factory.createSocket("api.nasa.gov", 443);
socket.startHandshake();
socket.getOutputStream().write(("GET "+new_url+"\n").getBytes());
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
StringBuilder sb = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null)
sb.append(inputLine);
in.close();
socket.close();
String json = sb.toString();
System.out.println(json);
return gson.fromJson(json, EarthImageryResponseObject.class);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
I have a small piece of code that makes a connection with a webpage. When I login Iretrieve the user_id from the database and put that in a textbox.
Then I want to retrieve the Firstname and Lastname from the database but when I do that I get a <br/> from the webpage. I cannot find out why I get the <br/> instead of the firstname.
This is my php code to handle the request that I get from Java
$user_id = $_SESSION['user'];
$voornaam = $con->select('voornaam', 'users', 'id', $user_id);
$achternaam = $con->select('achternaam', 'users', 'id', $user_id);
echo $voornaam;
public function select($detail, $table, $row, $value) {
$query = mysqli_query($this->connect, "SELECT `$detail` FROM `$table` WHERE `$row` = '$value'");
$associate = mysqli_fetch_assoc($query);
return $associate[$detail];
}
And this is the code that I use to send the data to php
public static String Select() {
String mysql_type = "2"; // 2 = Select
try {
String urlParameters = "mysql_type=" + mysql_type;
URL url = new URL("http://localhost:8080/HTTP_Connection/index.php");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while((line = reader.readLine())!= null)
{
return line;
}
writer.close();
reader.close();
return reader.readLine();
} catch (IOException iox) {
iox.printStackTrace();
return null;
}
}
Can someone explain to me why I get the <br/> instead of the first name?
Thanks in advance
It could be that in the line where you select the $voornaam:
"SELECT$detailFROM$tableWHERE$row= '$value'"
You use 3 different quotes:
U use ", ',
Try to replace thewith ' and then I think it should work.
So replace
"SELECT$detailFROM$tableWHERE$row= '$value'"
with "SELECT '$detail' FROM '$table' WHERE '$row' = '$value'"
I have a program in Java where I retrieve contents from a database.
Now I have a form in the program, and what I want to do is, on the press of a button, some string (text) content retrieved from the database, should be sent over to a website that I'm hosting locally. The content so sent, should be displayed on the website when refreshed.
Can someone guide me as to how I can achieve this (the sending of data to be displayed over the website)?
Will appreciate a lot, if you could kindly show some sample snippets or give me a reference to some tutorial that can help.
---- Okay so i found a link to a snippet that's supposed to do this, but im unable to understand at this stage as to how exactly this snippet works...can someone please guide me into knowing this better ?
here's the code
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) {
}
I'm not sure on how you store and manage any of the records but from Java you can send a HTTP Post to the Url (In your case http://localhost/, probably).
Have a look at http://www.exampledepot.com/egs/java.net/post.html for a snippet on how to do this.
Your Website could then store the received information in a database and display it when you refresh.
Update heres the function
Just a side not this is by no means the best way to do this and I have no idea on how this scales but for simple solutions this has worked for me in the past.
/**
* Posts a Set of forms variables to the Remote HTTP Host
* #param url The URL to post to and read
* #param params The Parameters to post to the remote host
* #return The Content of the remote page and return null if no data was returned
*/
public String post(String url, Map<String, String> params) {
//Check if Valid URL
if(!url.toLowerCase().contains("http://")) return null;
StringBuilder bldr = new StringBuilder();
try {
//Build the post data
StringBuilder post_data = new StringBuilder();
//Build the posting variables from the map given
for (Iterator iter = params.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
String key = (String) entry.getKey();
String value = (String)entry.getValue();
if(key.length() > 0 && value.length() > 0) {
if(post_data.length() > 0) post_data.append("&");
post_data.append(URLEncoder.encode(key, "UTF-8"));
post_data.append("=");
post_data.append(URLEncoder.encode(value, "UTF-8"));
}
}
// Send data
URL remote_url = new URL(url);
URLConnection conn = remote_url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(post_data.toString());
wr.flush();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = rd.readLine()) != null) {
bldr.append(inputLine);
}
wr.close();
rd.close();
} catch (Exception e) {
//Handle Error
}
return bldr.length() > 0 ? bldr.toString() : null;
}
You would then use the function as follows:
Map<String, String> params = new HashMap<String, String>();
params.put("var_a", "test");
params.put("var_b", "test");
params.put("var_c", "test");
String reponse = post("http://localhost/", params);
if(reponse == null) { /* error */ }
else {
System.out.println(reponse);
}
The big question is how will you authenticate the "update" from your Java program to your website?
You could easily write a handler on your website, say "/update" which saves the POST body (or value of a request parameter) to a file or other persistent store but how will you be sure that only you can set that value, instead of anybody who discovers it?