views:

176

answers:

4

I'm making a program for registration on a website.
For this, I use C++Builder and Indy (TIdHTTP).

How it works:

  • Program receives registration page via GET and extracts CAPTCHA picture address from it;
  • downloads the CAPTCHA (GET) and serves it to user;
  • sends the data provided by user to the website in POST request.

Problem: The CAPTCHA code is always incorrect. This must be because somewhere between these three calls to website the CAPTCHA challenge changes.

To prevent this, these requests have to be connected somehow
So I think, some kind of sessions support is needed here...

Please tell me how this can be achieved, in Delphi or C++Builder

EDIT:

I found out that Session ID is stored in a cookie thanks to Runner

+1  A: 

To me sequence seems correct. Just check that when posting the CAPTCHA answer back, you provide the ID to tell which CAPTCHA that is.

To me it sounds like your POST is not recognized as a specific request. In other words you are probably not assocating the response with the specific user. When you first call GET and get the CAPTCHA back from the server, the server must provide you with the unique ID for the returned CAPTCHA. This can be a unique URL, a cookie, a field embeded in the HTML returned etc...

That is my guess from your description.

EDIT:

I have more info. It is obviously a PHP server. From the page provided by "BlaXpirit":

A visitor accessing your web site is assigned a unique id, the so-called session id. This is either stored in a cookie on the user side or is propagated in the URL.

So, if the ID is in the cookie, then I guess you are not sending the cookie back. You are the middle man here, It goes like this.

  1. You make a GET to the CAPTCHA server.
  2. You get back the response that contains the cookie
  3. You send the CAPTCHA back to the client, but do not send the cookie.

You should send the cookie to the client and then back to the CAPTCHA server, or have your own session management, store the CAPTCHA cookie, identify the client when he/she sends the response and send the cookie with the response back to the CAPTCHA server.

Runner
There is no way to "provide the ID", it is saved in website's $_SESSION data
BlaXpirit
The CAPTCHA system must know for who to process the answer. How does the user pass that info to the CAPTCHA system. In a POST hidden field, in a cookie data, something else...? The CAPTCHA system must inform you about such an ID after the first GET.
Runner
Maybe the URL itself is unique and so provides the ID info. Please post more info in your question, otherwise I am only guessing ;)
Runner
How website works: User goes to registration page, server creates a CAPTCHA and saves its unique code for this [session](http://duckduckgo.com/?q=php+session). When the user submits form, website checks user's input against the saved unique code.
BlaXpirit
@BlaXpirit; HTTP is a stateless protocol. To remember each client, server needs the clients to provide some unique identification to server. To do so, the clients should either send that ID inside the URL, or via a cookie, or a hidden field of HTML form. So you should first indicate what session management mechanism your server is using.
vcldeveloper
@vcldeveloper, Thanks that is what I am trying to find out also. Well put.
Runner
Oh, don't be so "smart", just go [*here*](http://php.net/manual/en/intro.session.php). And didn't you notice a link in my previous comment?
BlaXpirit
Ah, not being smart, but I don't like guessing. Yes in noticed the link and I saw it is PHP. But session data is internal PHP session on the server side. So I still stand beside my initial assumption. I updated my answer with new knowledge
Runner
Thanks for your last EDIT. It is helpful. But my question is "how this can be achieved in Delphi or C++Builder". Umm... I should try and do this by myself
BlaXpirit
If you are using Indy, then you have two classes, ARequestInfo: TIdHTTPRequestInfo and AResponseInfo: TIdHTTPResponseInfo. Inside you have Cookies property, that points to the coolection of cookies. Just google for a solution.
Runner
@BlaXpirit: read the page you linked to: "A visitor accessing your web site is assigned a unique id, the so-called session id. This is either stored in a cookie on the user side or is propagated in the URL." So the question is - HOW IS YOUR SERVER PROPAGATING THE ID TO THE CLIENT??? It is doing it via a cookie or via a URL? This is an important distinction. Without it, we cannot tell you how to make your Indy code work with the ID correctly.
Remy Lebeau - TeamB
I recently edited my question and wrote it there
BlaXpirit
+2  A: 

If the PHP session ID is being sent by the server in a cookie, then make sure you are using an up-to-date version of Indy. Indy 10's cookie handling has been broken for awhile, but I recently checked in new code for Indy's cookie management to address a lot of issues.

If the PHP session ID is being sent by the server in a hidden field of the registration form, then you need to make sure you are including the ID in the POST data you send back.

Remy Lebeau - TeamB
I think I'm using version 9
BlaXpirit
Then I would recommend upgrading to the latest Indy 10 snapshot if possible. Besides that, you still have not said how EXACTLY the server is delivering its session ID to your client. Even though PHP stores its session ID in its $_SESSION data, the ID still has to be round-tripped to the client and back so the server can match it back up on subsequent requests. If you are not willing or able to tell us how that ID is getting passed around at the HTTP layer, then you will have to give us he URL of the registration page so we can see it for ourselves...
Remy Lebeau - TeamB
...only then can we tell you how to make your Indy code work with it correctly.
Remy Lebeau - TeamB
I recently edited my question and wrote it there
BlaXpirit
Please right-click on TIdHTTP in the Form Designer to find out which version of Indy you have installed. Then use a packet sniffer, such as Wireshark, or Indy's own TIdLog... components, to verify that PHP really is sending a cookie and that TIdHTTP is not sending it back. Then please post the actual HTTP 'Set-Cookie' header and PHP URL(s) involved and I will compare it to Indy's cookie logic to see what is going wrong with it (I'm on the Indy development team).
Remy Lebeau - TeamB
I already wrote that I'm using version 9, and that the website uses cookies. I don't handle them in anyway, and I need to do it.
BlaXpirit
You wrote that you THINK you are using Indy 9. I told you how to verify that (right-click on TIdHTTP in the Form Designer). As for cookies, TIdHTTP handles cookies automatically for you (make sure the TIdHTTP.AllowCookies property is set to True). However, if TIdHTTP is not sending a cookie back to the server correctly, then that is likely a bug in Indy's cookie handling. That is why I asked you for a raw data capture from a packet sniffer so I can verify Indy's logic.
Remy Lebeau - TeamB
OMG, I have Indy 8.0.25
BlaXpirit
Then you need to upgrade to the latest Indy 9.0.50 snapshot, at least, if not to the latest Indy 10.5.8 snapshot (I recommend Indy 10, however that is a major upgrade from Indy 8 - Indy 9 would be more backwards compatible).
Remy Lebeau - TeamB
A: 

Use a IdCookieHandler and link it to the IdHTTP Object. Then all the cookie / session management stuff will automatically done by Indy.

This is the fast and cleanest solution if you want to work with real session support and web automation including signups.

maxedmelon
There is no IdCookieHandler component in Indy. The correct name is TIdCookieManager, and TIdHTTP already creates an instance of it internally if you do not provide your own explicitally.
Remy Lebeau - TeamB
Sorry, I mixed up the names. When using Delphi 7 and TIdHTTP, I had to explicitly create one and link the TIdHTTP to it. Don't know about newer versions......
maxedmelon
It seems like there's no such component
BlaXpirit
@maxedmelon: you do not need to create your own TIdCookieManager component. TIdHTTP creates one automatically if the TIdHTTP.AllowCookies property is true. @BlaXpirit: Yes, there is such a component.
Remy Lebeau - TeamB
A: 

Let me to guess, hmm... I bet you register Yahoo :) Anyway with most popular mail providers it isn't so easy, there are some javascripts that protect from automatic signups. These scripts can generate cookies or POST fields dynamically.

TaveL
You didn't guess. Bad answer
BlaXpirit