Can client side code access or set http request attributes? - java

I'm reasonably confident I know the answer to this, but am struggling to find any concrete information out there. I'm aware that the client submits requests to an http server optionally supplying reqeust parameters. The server has the additional capability to store information in request attributes via Objects. My question is, does the client have any access to the attributes in an http request object? We have a lot of poorly written code which looks something like this:
if (request.getAttribute("name") != null)
name = request.getAttribute("name);
else if (request.getParameter("name") != null)
name = request.getParameter("name");
I'm guess this is because the original developer didn't fully understand how client side http requests submitted data to the server. In any case, I'm currently working on implementing additional valiadation and encoding of request data to prevent XSS vulnerabilities and wondered if it was possible for the client to corrupt/hack/take advantage of request attributes (assuming they aren't ever populated with data sourced from the client)?

No. The attributes are something the servlet spec adds, and can be used to communicate between different entities operating on the request. They don't travel over the wire, so they don't exist client side.
The client can set the body, the parameters (i.e. the url) and the headers, and that's pretty much it.
See:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5
How the attribute field of a HttpServletRequest maps to a raw HTTP request?

Related

Spring REST - Proper PUT functionality when resource does not already exist

I am building a REST API using Spring and implementing the PUT functionality. I am trying to handle the scenario in which the client tries to PUT to a uri where the resource does not already exist. In this scenario, per the PUT spec, a new resource should be created at that ID. However because of the ID generation strategy I am using (#GeneratedValue(strategy = GenerationType.IDENTITY)), I cannot create resources with IDs out of sequence. The database must use the next available value. However, according to the w3 spec on PUT...
If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.
If the server desires that the request be applied to a different URI, it MUST send a 301 (Moved Permanently) response; the user agent MAY then make its own decision regarding whether or not to redirect the request.
In this case, I can do neither of these. I cannot create a new resource at the existing URI due to the ID generation restrictions, and I cannot send a 301 Moved Permanently response because according to How do I know the id before saving an object in jpa it is impossible to know the next ID in a sequence before actually persisting the object. So I would have no way of telling the client what URI to redirect to in order to properly create the new resource.
I would imagine this problem has been solved many times over because it is the standard PUT functionality, yet I am having trouble finding any other people who have tried to do this. It seems most people just ignore the "create new resource" part of PUT, and simply use it as update only.
What I want to do is just go ahead and create the new resource, and then send the 301 Moved Permanently to redirect the client to the true location of the created resource - but as we see above, this violates the definition of PUT.
Is there a spring-y way to solve this problem? Or is the problem unsolved, and the true standard practice is to simply not allow creation of new resources via PUT?
If the server cant processes the request due to an error in the request, just return a 400.
400 Bad Request -
The server cannot or will not process the request due to an apparent client error (e.g., malformed request syntax, size too large, invalid request message framing, or deceptive request routing).

why we need to use get method inside a java file #RequestMapping(method = RequestMethod.GET)

In generally while sending form data from the ui pages we are using method="GET" or method="POST" in the form tag then what is the use of these methods in the server side programs. I am using these methods in spring while calling the methods in the controller #RequestMapping(method = RequestMethod.GET)
Can anyone explain what is the real use of get or post methods in server side code
Loosely speaking, if the purpose of your method is to retrieve data from the server use GET. e.g. getting information to display on the client.
If you are sending data to the server use POST. e.g. sending information to the server to be saved on a database somewhere.
There is a limit to the size of data you can send to the server with a GET request.
The server side GET or POST is used to specify what the server expects to receive in order to accept the request. The client side GET or POST is used to specify what will be sent to the server. These two must match. You cannot send a GET request when server expects a POST and vice-versa.
When you are building a server application, it is important to know the appropriate request type to use, which by itself is a whole big different topic which you should research if it is you the one that builds the server side part.

Java: Can I alter HTTP Headers And Read The Headers Server Side?

I have a legacy Java webapp that does MANY redirects and forwards. I'm trying to find a way in a ServletFilter to differentiate GET requests from those server side redirects and GET requests that come from the client side.
I was hoping to do that by adding an attribute as a flag, to the header before the redirect/forward is sent and then read it in the ServletFilter to route it accordingly.
I tried request.setAttribute("myflag", "yes") before the redirect and request.getAttribute("myflag") in the ServletFilter. All I got were null values.
Can I modify headers server side and read those modifications server side?
Thanks in advance for any tips.
You can use a HttpServletRequestWrapper, there is a comprehensive tutorial on how to do that here:
http://vangjee.wordpress.com/2009/02/25/how-to-modify-request-headers-in-a-j2ee-web-application/
don't use request.setAttribute()/request.getAttribute() , it's scopes on forwards.
you can use Cookies.
If your application sets a request attribute and then forwards the request, the filter (if executed) on the forwarded URI will see the request attribute values.
In contrast, if the application sets a request attribute and then issues a redirect on the response, the browser issues a new HTTP request to the next URI - so previous request object attributes are not persisted and you'll get null values.
You could use this technique to determine which requests were redirects vs forwards.
For example:
Servlet A executed at URI /webapp/a calls request.setAttribute("forward", Boolean.TRUE) and then response.sendRedirect("/webapp/b")
If you have a servlet filter mapped to /webapp/b, in the scenario above, request.getAttribute("forward") will be null.
If, however, /webapp/a asks RequestDispatcher to forward to /webapp/b, then the call to request.getAttribute("forward") within the servlet filter's doFilter() will yield Boolean.TRUE because the request object is the same. It can then deduce that the request was forwarded (or included) and not a redirect OR a direct GET request to /webapp/b.

Options for passing data across HTTP redirects

I am working on a Web application and need to pass data across HTTP redirects. For example:
http://foo.com/form.html
POSTs to
http://foo.com/form/submit.html
If there is an issue with the data, the Response is redirected back to
http://foo.com/form.html?error=Some+error+message
and the query param "error"'s value is displayed on the page.
Is there any other reliable way to pass data across redirects (ie HTTP headers, etc.).
Passing the data as query params works but isn't ideal because:
its cleartext (and in the query string, so SSL cant be relied on to encyrpt) so I wouldn't want to pass sensitive data
URIs are limited in length by the browser (albiet the length is generally fairly long).
IMPORTANT: This platform is state-less and distributed across many app servers, so I can't track the data in a server-side session object.
From the client-server interaction point of view, this is a server internal dispatch issue.
Browsers are not meant to re-post the entity of the initial request automatically according to the HTTP specification: "The action required MAY be carried out by the user agent without interaction with the user if and only if the method used in the second request is GET or HEAD."
If it's not already the case, make form.html dynamic so that it's an HTML static file. Send the POST request to itself and pre-fill the value in case of error. Alternatively, you could make submit.html use the same template as form.html if there is a problem.
its cleartext (and in the query string, so SSL cant be relied on to
encyrpt) so I wouldn't want to pass sensitive data
I'm not sure what the issue is here. You're submitting everything over plain HTTP anyway. Cookie, query parameters and request entity will all be visible. Using HTTPS would actually protect all this, although query parameters can still be an issue with browser history and server logs (that's not part of the connection, which is what TLS protects).
I think using cookies would be a reasonable solution depending on the amount of data. As you can't track it on the server side (by using a sessions for example, which would be much simpler)
You can store error message in database on server and reference to it by id:
http://foo.com/form.html?error_id=42
If error texts are fixed you even don't need to use a database.
Also, you can use Web Storage. Instead of redirection with "Location" header you can display output page with this JavaScript:
var error_message = "Something is wrong";
if( typeof(Storage) !== "undefined" ) {
localStorage.error_message = error_message;
else {
// fallback for IE < 8
alert(error_message);
}
location.href = "new url";
And after redirection you can read localStorage.error_message using JavaScript and display the message.

AS2: Does xml.sendAndLoad use POST or GET?

All,
I'm trying to find out, unambiguously, what method (GET or POST) Flash/AS2 uses with XML.sendAndLoad.
Here's what the help/docs (http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002340.html) say about the function
Encodes the specified XML object into
an XML document, sends it to the
specified URL using the POST method,
downloads the server's response, and
loads it into the resultXMLobject
specified in the parameters.
However, I'm using this method to send XML data to a Java Servlet developed and maintained by another team of developers. And they're seeing log entries that look like this:
GET /portal/delegate/[someService]?svc=setPayCheckInfo&XMLStr=[an encoded version of the XML I send]
After a Google search to figure out why the POST shows up as a GET in their log, I found this Adobe technote (http://kb2.adobe.com/cps/159/tn_15908.html). Here's what it says:
When loadVariables or getURL actions are
used to send data to Java servlets it
can appear that the data is being sent
using a GET request, when the POST
method was specified in the Flash
movie.
This happens because Flash sends the
data in a GET/POST hybrid format. If
the data were being sent using a GET
request, the variables would appear in
a query string appended to the end of
the URL. Flash uses a GET server
request, but the Name/Value pairs
containing the variables are sent in a
second transmission using POST.
Although this causes the servlet to
trigger the doGet() method, the
variables are still available in the
server request.
I don't really understand that. What is a "GET/POST hybrid format"?
Why does the method Flash uses (POST or GET) depend on whether the data is sent to a Java servlet or elsewhere (e.g., a PHP page?)
Can anyone make sense of this? Many thanks in advance!
Cheers,
Matt
Have you try doing something like that :
var sendVar=new LoadVars();
var xml=new XML("<r>test</r>");
sendVar.xml=xml;
sendVar.svc="setPayCheckInfo";
var receiveXML=new XML();
function onLoad(success) {
if (success) {
trace("receive:"+receiveXML);
} else {
trace('error');
}
}
receiveXML.onLoad=onLoad;
sendVar.sendAndLoad("http://mywebserver", receiveXML, "POST");
The hybrid format is just a term Macromedia invented to paint over its misuse of HTTP.
HTTP is very vague on what you can do with GET and POST. But the convention is that no message body is used in GET. Adobe violates this convention by sending parameters in the message body.
Flash sends the same request regardless of the server. You have problem in Servlet because most implementation (like Tomcat) ignores message body for GET. PHP doesn't care the verb and it processes the message body for GET too.

Categories