Get request part after hash sign - ruby-on-rails

My web-site has AJAX-powered search, that uses deep-linking. When user follows a link …
http://example.com/articles#/?tags=Mac%20OS,review
… tags "Mac OS" and "review" should already been selected in a search form and articles, related to "Mac OS" and "review" should be presented on the page.
I have following scenario, that a need to fix
User follows the link http://example.com/articles#/?tags=Mac%20OS
During initial page rendering, all articles are fetched
On the client side, hash-part is parsed and only "Mac OS"-related articles are requested via AJAX.
Client receives "Mac OS"-articles and replaces all articles, fetched at step 2. Also it marks "Mac OS" tag as selected on a search-form.
The problem here - is duplicated articles rendering, that looks really bad for the user. He looks at all articles, and after couple of seconds, they will be replaced with "Mac OS"-articles.
I need to have following scenario:
User follows the link http://example.com/articles#/?tags=Mac%20OS
Server parses hash-part and returns "Mac OS"-related articles
Client understands, that "Mac OS"-articles are already there and does nothing. It just marks "Mac OS" tag as selected.
To do this, i need to get hash-part of the request string:
/?tags=Mac%20OS
I cannot use request parameters after ?, because i use AJAX and deep-linking. With ?-part, browser will be forced to reload the page. I need to do anything without reloading the page.
You help will be greatly appreciated.
Thanks.

The part of a URL after the hash is not sent to the server, so you can't process it there. You can extract that part of the URL in the client-side code that creates your Ajax request and send it as a parameter.

#NickFitz is correct, but if you must send whatever comes after the # hash/pound symbol, you can use the URL encoded characters that represent # which is %23.
So %23 and whatever that comes after %23 will be sent to the server. If you are using modern web server, they will automatically recognize that %23 is #. In Ruby on Rails, Rack does this for you.

Related

Why url params doesn't work in some sites?

I'm trying to add param in the url, like in this example:
https://www.google.com/ > https://www.google.com/search?q=qq
Opening the last link you can see "qq" in the "q" input.
For this site it doesn't work (this is the problem):
https://www.calabriasue.it/assistenza/richiesta-assistenza-e-supporto/
https://www.calabriasue.it/assistenza/richiesta-assistenza-e-supporto/?nome=mario
Can I add url param also in the last one? I need it.
Thanks!
I tried using different input names, different params ecc but it doesn't work.
Google's server side code is designed to generate an HTML document with an input field that is prefilled with the current search term which is reads from the URL. That is why adding q=search+term to the URL populates the input field.
You can't make arbitrary third-party websites prefill inputs. They have to explicitly provide a mechanism to make it possible.
Parameters only work as long as the code for the target website is expecting to handle a parameter named "nome" with a value "mario". In the case of the google website, it is expecting a parameter named "q" and has a form input for it.
Clicking a URL sends a a GET request type, and the target site may only be accepting parameters from a POST request type. You could consider using the application known as "PostMan" to help with that.
Alternately, the target page you are viewing may be forwarded / routed from a different page which accepts parameters.

How to fix encoded URL to bind parameters correctly

I'm using a Bank E-Payment webservice and set the redirectURL into http://Example.com/EPaymentResultCallback?Param1=0&Param2=1
when the bank finish it's job, browser redirects to preceding url.
But the problem is: Bank webservice has changed my url into http://Example.com/EPaymentResultCallback?Param1=0&Param2=1 (noticing the extra &).
In fact my innocent url encoded and therefore Param2 will be lost.
I cannot change the websercive obviously. but interested to know if there is a way to resolve the second url parameter (Param2) on my website?
For more general explanation: 'mywebsite' calls a webservice and redirected to a whole new website. after 'new website' done, browser redirects to the given URL (in fact 'mywebsite/somesubUrl/param1&param2') but parameter separator (&) changed into (&) so the second parameter (param2) won't delivered correctly to the action method and an exception raise, pointing that the second input parameter in the action method could not be null.
Actually i`m looking for a built-in solution to read encrypted url. that would be the best. but any other idea is welcomed.

How can I secure this form post from manipulation

I have a very unique situation. I am building an application where a user uploads a QR code to my site, and when decoded, it has a matching ID already stored in the DB (as in I already have a record of the qr code before the user uploads it)
When they upload it, I decode it, which is a base64 string like so 6BbW0pxO0YENxn38HMUbcQ==
Like I said, That code corresponds to some information, and after they upload the QR image, I redirect them to one more page, which shows them the qr code, the corresponding information stored in the DB, and they are also prompted with a submit button. When pressed, I take note that they have confirmed, and I do some other things.
To elaborate
As a user I go to www.url.com/code/upload and upload an image. I am then redirected to /code/new with the page displaying the data stored in the DB from the correspond decoding of the image.
How can I make the submit button on /code/new reliable? Here are the solutions I can think of, and their vulnerabilities
Propagate /code/new with the correspond data stored in the DB, lets say #username and #movie into a form, with a submit button and POST the data to the server
This is dangerous because I don't think anything stops someone from editing the DOM and changing #username and #movie to something else
Pass the unique base64 identifier in the parameters such like, /code/new?id=STRING
Then when you submit, the string gets passed to the handling controller action, but i feel that this is not safe because then users can attempt to guess the strings and make concurrent post requests.
Essentially, I have a user upload a qr code, and after submission, I need to verify to verify that they were the one that uploaded the image. I lose all state, and information after they upload the image.
A proposed solution:
After the user uploads the image, create a unique string and store it in the session and also a record in the database (A user is logged in, so its the current_user.session_token), then when the user clicks submit on /uploads/new, I grab the session token, and verify that the current_user.session_token == session_token.
At this point, I can only verify that the current user was the one that uploaded the image.. I then need to somehow grab the base64 string that was from the uploaded QR code.
Another proposed solution: I temporarily put the base64 string as an attribute of the user when they upload the file. So I will have current_user.session_token and current_user.base64_string. Then when the user clicks on the 2nd submit button, I do something like
#check if the user's token is equal to the sessions, and the string is not nil
if current_user.session_token == session_token && !current_user.base64_string.nil?
data = current_user.base64_string
#hooray! I have the QR code
end
Then delete the session token, and then delete the current_user's base64_string and session_token
if a malicious user attempts to forge their session token, it won't match their's store in the database, then when I handle the post request, I will not proceed. But If a legitimate user makes the second post request, the session Id matches, and I am able to grab the base64 string.
TL;DR, I need 2 concurrent post requests that carry the information without losing it, and can verify that both the first and second post requests were done by the same user.
If anyone had the patience to read through that, I appreciate it! if there are any suggestions I would greatly appreciate it, or if you think my solution is sufficient or not, please let me know. Thanks!
Sign the parameters generated from the first request, and verify the signature when you process the second request.
The technology to use for this is HMAC. Here's how to use one version available in Ruby:
require 'openssl'
secret = 'ABCDEFGHIJKLMNOP'
data = 'user:code'
signature = OpenSSL::HMAC.hexdigest( 'sha256', secret, data )
p signature
Output:
"bd7194c0604902d6594694d25e7f27bdc2d10926638e0ce8bdda3f6debb37f6a"
This is how you can use it to link two HTTP routes together so that the second one can trust that parameters sent to it via the first one have not been tampered with:
When the first route is called, generate or fetch a secret. It is important that this secret value is not ever sent or exposed to the end user. It can simply be application configuration (which then applies to all linked requests), but if you can store it associated with perhaps the QR code, then the strongest protection is to generate a long random string just before creating the signature, and to store it ready to use to confirm the second step. Something like SecureRandom.hex is great for a short-term secret if you have somewhere server-side to store it.
Combine all the parameters on the form that you want to be tamper-free into one long message. Easiest thing to do is .join them in an array, and you should use a delimiter that is not allowed in any value, and that you are also not accepting due to validation. This string is the value to use for data in the example.
Generate the form that calls the second route. In addition to the params you want to accept at next stage, add the signature value generated as above. Do not send the value of secret to the client by putting in the form or cookie etc.
When you receive the request from the second route to finalise the multi-stage request, generate the signature from the user-sent params (after validating them), and compare with the one sent to you from the form. If it is the same, then the request is valid. If it is different then the data may have been tampered (provided you have no bugs - do check things such as consistent character encoding if any param can contain non-ASCII characters)
Provided you have kept the secret truly secret from the end user, they have next to no chance of generating a correct signature. Only your code in routes one and two knows how to do it (because it has access to correct secret, not because of any special fact on how it is written). Therefore you can trust that the values have not been modified.

do browsers remove # in URL automatically?

our front end guy needs to form a url containing the hash, (i.e, http://blah/#some-link.) when we hit this on the browser and inspect the http traffic using fiddler, we saw that everything after blah/ gets removed, so the request is really just http://blah/. we also confirmed this on our server eclipse debug log.
the request gets redirected to the correct login page by Spring security(because user hasn't logged in), but the url on the browser now shows:
http://blah/some-link (the hash got removed) but the url on the browser should really be http://blah/log-in.
any idea why this is? any fix or workaround? thanks in advance.
URI part after # is called a fragment:
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
Scheme and hier-part identify the location of a document, and fragment helps the browser to identify a location inside this document.
Fragment is stripped from URI by client software before it is sent as a part of request.
From RFC3986:
the fragment identifier is not used in the scheme-specific
processing of a URI; instead, the fragment identifier is separated
from the rest of the URI prior to a dereference, and thus the
identifying information within the fragment itself is dereferenced
solely by the user agent, regardless of the URI scheme. Although
this separate handling is often perceived to be a loss of
information, particularly for accurate redirection of references as
resources move over time, it also serves to prevent information
providers from denying reference authors the right to refer to
information within a resource selectively.
Content after the # is only used on the client side, per HTTP specification. If you require that information on the server, you can either use a different separator, or you can submit it via ajax after the page has loaded by reading it on the client with javascript.
The part of the URI including and after the hash (#) is never sent to the server as part of the HTTP request.
The reason is that the hash identifier was originally designed to point at references within the given web page and not to new resources on the server.
If you want to get the hash identifier, you'll have to use some client-side JavaScript to grab the value and submit it with the form.
Hashmark is removed from URL when the back button is clicked in IE9, IE10 or IE11
In IE10 , first time on clicking the HREF link leads to the correct below url:
http://www.example.com/yy/zz/ff/paul.html#20007_14
If back button is clicked again the, then it comes to the below url:
http://www.example.com/yy/zz/ff/paul.html
Solution :
Please change the url with https
It works for me
you can do this with javascript
<script>
if(window.location.hash) {
console.log(window.location.hash);
window.location.hash = window.location.hash;
}
</script>

#! as opposed to just # in a permalink

I'm designing a permalink system and I just noticed that Twitter and Hipmunk both prefix their permalinks with #!. I was wondering why this is, and if the exclamation point in particular is there for a reason. Wouldn't #/ work just as well, since they're no doubt using a framework that lets them redirect queries to certain templates with a regex URL parser?
http://www.hipmunk.com/#!BOS.SEA,Dec15.Jan02
http://twitter.com/#!/dozba
My only guess is it's because browsers use # to link to an anchor element. Is this why the exclamation point is appended?
This is done to make an "AJAX" page crawlable [by google] for indexing -- It does not affect the other well-defined semantics of the fragment identifier at all!
See Making AJAX Applications Crawlable: Getting Started
Briefly, the solution works as follows: the crawler finds a pretty AJAX URL (that is, a URL containing a #! hash fragment). It then requests the content for this URL from your server in a slightly modified form. Your web server returns the content in the form of an HTML snapshot, which is then processed by the crawler. The search results will show the original URL.
I am sure other search-engines are also following this lead/protocol.
Happy coding.
Also, It is actually perfectly valid, at least per HTML5, to have an element with an ID of "!foo" so the
reasoning in the post is invalid. See the article "The id attribute just got more classy":
HTML5 gets rid of the additional restrictions on the id attribute. The only requirements left — apart from being unique in the document — are that the value must contain at least one character (can’t be empty), and that it can’t contain any space characters.
My guess is that both pages use this in their JavaScript to differ between # (a link to an anchor) and their custom #! which loads some additional content using Ajax.
In that case pretty much everything else would work after the # sign.

Resources