How to save a cookie after the header has been sent in Perl CGI? - perl

I know you send a cookie to a user's browser via the HTTP header, but how do you do this after the header has been sent. For example you set a value in a form you want to grant session wide scope to.
Thanks!

You can't. Cookies are only set in the header. HTTP provides no way to set them elsewhere.
If you want to set a cookie based on form data, then you do it in the response to the form submission request.
If you want to use data both for generating a cookie and generating a form, then get that data into a variable before you send the header and use it in both locations.
(You could generate JavaScript to set the cookie in the HTML body … but that would be unnecessarily complex and unreliable).

If you want to set a cookie after you've already sent a response header, you have to make the client load something else that can set the cookie. This might be through an Ajax response, an image link, or something else. You might fire this off automatically or ask the user to update something.

Related

Webextension: Set response headers for web_accessible_resources

To provide some custom caching via a webextension, I use web_accessible_resources and redirect accesses towards them in a background script – see my previous question for details.
While that works content wise, I cannot find a way to change the response headers of the cached content, for example the Last-Modified header. So when I cache content that the original website does some consistence checks on, this will fail.
I tried to intercept the redirected response with an onHeadersReceived handler, but this never triggers as “Only requests made using HTTP or HTTPS will trigger events” and my redirect uses the moz-extension:// protocol.
How does one set response headers when serving web_accessible_resources?
Is it possible at all?

can I pass headers to redirected location after redirection?

here's response header of my redirection endpoint with status code 302.
"Location": "http://<target-domain>",
"Set-Cookie": "username=user1;"
I can see it redirects correctly to 302. but the cookie does not get set on the <target-domain>
Looks like the header "Set-Cookie": "username=user1;" does not get passed to the <target-domain> on redirection.
I see 2 network activities in my development tool,
redirection endpoint responds with status code 302. I see Location and Set-Cookie in the response header.
target domain responds with status code 200. I don't see Location and Set-Cookie anymore.
Is there a way to set the cookies on the <target-domain>?
You can't set cookies on a domain other than the one you're on, so basically no. The only exception to this is you can set cookies on example.com if your current domain is something like subdomain.example.com, where you can attach the cookies to a shorter form of your domain, but it must be the same base domain.
If you need the other site to set a cookie with a value it does not know, you'll have to pass that value through somehow. Using a redirect with a query string leaves it open to tampering by the user unless you cryptographically sign it (annoying) or ship over a token that can be used to retrieve the raw value. You may need a short-term store for this, like Redis, Memcached, or even a database row you can purge later.
If it were possible to set cookies on any domain at all there'd be utter chaos. These things are heavily restricted for a reason.

WKWebView can't carry cookie for 302 redirect

I set cookie in request header before I call loadRequest() function to load a page. I also use document.cookie() to set cookie by WKUserScript according to [WKWebView Cookies. However, I find that if a 302 redirection occurs, request may fail for loss of cookie. For example, the request of http://A redirect to http://B, I could set cookie for request of http://A by operating request head and using WKUserScript, but these two ways can not set cookie for request of http://B, so the 302 request of http://B may fail. This situation occurs in ios8 more frequently than ios9. Does anybody have a workaround?
Note sure, but probably the first response may contain "Set-Cookie" header. Hence, you have to use the provided cookie in the second request. May be it's missing.
workaround for set cookies in iOS please check my answer. You must set cookies both in request and wkuserscript same time. otherwise it fail one time and sucess in 2nd run,
Can I set the cookies to be used by a WKWebView?

Preventing CSRF?

I already seen some question from here (stackoverflow) and THIS post, but I still have some questions...
Using hidden value in the post form and check it when post reach the server.
The hidden value can easy be copied and send exactly like the real one, "hard to guess" (like md5) will not help. (right?)
Setting a cookie when you reach the form and send the cookie value as a hidden value.
You can easily change a cookie value or send a custom cookie exactly like the real one using the same real hidden value. (right?)
Using 'timeout', the POST values cannot reach too late.
So, if you're slow you will fail when you try to set everything up with the hidden value. If you're fast it gonna work. (right?)
I want to be protected about CSRF...but how exactly I do it?
The easiest way I found to prevent CSRF issues is:
On the server side, assign an HttpOnly cookie to the client with a random (unguessable) token
Place a hidden field on the form with that cookie value
Upon form submit, ensure the hidden field value equals the cookie value (on the server side of things)
If you make the following changes then I think you're safe
no data updates should be allowed through GET (or better POST as well) (since both can be used through HTML forms)
disable CORS on your server (or at least on endpoints that are critical and/or make changes to data)
allow JSON-only APIs (ie. only accept input through JSON on critical endpoints at least)
Just to add to above: Do not use method overrides and do not support old browsers.

Problem with form direct submitting

If I visit the link http://mega.1280.com/file/EKOZKE/, enter the captcha code and click the Download button, I can download the file.
I wonder if I can submit the form without clicking the 'Download' button? I mean typing the captcha code directly on the address bar and hit Enter?
I try http://mega.1280.com/file/EKOZKE/?code_security=xxxxxx where 'code_security' is the name of the textbox of the captcha code but it failed. Any ideas?
The form has a POST method. You can't emulate a POST request with a different url, that's what GET requests do.
Even if the server doesn't check the method of the request, you still have to provide every mandatory data. If you look at what is sent by the form, you'll see there are 3 other parameters (action, btn_download, file_id), and more importantly several cookies that the server need to recover your php session (PHPSESSID), which is in turn needed to match your security_code with the provided CAPTCHA.
Bottom line: you can emulate the request, but not by submitting a simple GET request. You have to use a real user agent, one that is able to send post requests and handle cookies.
...But of course, that's exactly what CAPTCHA are here to prevent you to do :-).
edit: to reply to your comment "I just want to find out the technique that this website use to submit form." :
This website doesn't submit the form, actually. It's your browser that submits the form, and it does so by conforming to HTML and HTTP standards. On the webpage, the form is coded
<form name="frm_download" method="post" action="">
So when you click on the "submit" button, your browser collects all the data from the inputs (text, hidden, whatever) and sends a HTTP POST request to the same url that the form originated from, with a bunch of HTTP headers (including a Cookie header that contains all the stored cookies information attached to this server domain) and a body containing the form data : a list of key/value pairs.
The server receives the request. It can check that it's actually a POST request. It can and will retrieve all submitted pairs of data (parameters). It can retrieve the cookies, and will do so to restore your php session. It will then compare your security_code parameter with the correct data stored in your php session. If the CAPTCHA matches, then it will send you a response containing the file pointed by your file_id parameter.