Jump to content

How Safe is uniGUI?


Kattes

Recommended Posts

First of all, I would like to apologize for the somewhat lurid headline, but what happened to me yesterday made me doubt my more than 35 years of experience as a programmer.

But first things first, what happened? I was programming a registration application for a local event organizer for his guests. Basically a very simple application that collects people's personal information, writes it into a database and then generates a QR code to be displayed on the mobile device and later scanned upon entry.

To make sure that the code used for registration is unique, a 6-digit alpha string is generated and checked again with the database for uniqueness.

All this works without any problems. The generated string is also displayed correctly on the mobile devices, but then something completely crazy happens when the string is converted into a QR code. 

Because here it sometimes happens that the content of the QR code does not match the displayed string content. But it is not the case that some nonsense is then generated, it is a QR code with the identical content from another session!

It is simply not clear to me how this can happen. No global variables / or object instances are used and the code for generating the QR code also looks completely inconspicuous.

I would be very grateful for any ideas and suggestions, because you can imagine what happens when two people with identical QR codes suddenly appear at the entrance....

Link to comment
Share on other sites

Attached you will find the QRCode unit used and below, how it is used.

procedure TuFrameDetails.UnimFormCreate(Sender: TObject);
var
  QRCodeBitmap : tBitmap;
  sQR : string;
begin
  with UniMainModule do
  begin
    bSkip := true;
    sQR := sUserId + '-999999-'+ sTransRef;
    UnimLabelRef.Caption := sQR;
    try
      QRCodeBitmap := CreateQRCode(sQR);
      ResizeBitmap(QRCodeBitmap,8);
      UnimImageQR.Picture.Bitmap.Assign(QRCodeBitmap);
      QRCodeBitmap.Free;
    finally
      bSkip := false;
    end;
  end;
end;
function TuFrameDetails.CreateQRCode(qrTxt: string): tBitmap;
var
  QRCode: TDelphiZXingQRCode;
  Row, Column: Integer;
begin
  QRCode := TDelphiZXingQRCode.Create;
  result := tBitmap.Create;
  try
    QRCode.Data := qrTxt;
    QRCode.Encoding := qrAuto;
    QRCode.QuietZone := 4;
    result.SetSize(QRCode.Rows, QRCode.Columns);
    for Row := 0 to QRCode.Rows - 1 do
    begin
      for Column := 0 to QRCode.Columns - 1 do
      begin
        if (QRCode.IsBlack[Row, Column]) then
        begin
          result.Canvas.Pixels[Column, Row] := rgb(0,0,32);
        end else
        begin
          result.Canvas.Pixels[Column, Row] := clWhite;
        end;
      end;
    end;
  finally
    QRCode.Free;
  end;
end;

procedure TuFrameDetails.ResizeBitmap(var Bmp: tBitmap; Scale: double);
var
  BmpTemp: tBitmap;
begin
  BmpTemp := TBitmap.create;
  BmpTemp.PixelFormat := Bmp.PixelFormat;
  BmpTemp.Width := trunc(Bmp.Width * Scale);
  BmpTemp.Height := trunc(Bmp.Height * Scale);
  BmpTemp.Canvas.StretchDraw(Rect(0,0,BmpTemp.Width, BmpTemp.Height), Bmp);
  Bmp.Free;
  Bmp := BmpTemp;
end;

 

QRCode.zip

Link to comment
Share on other sites

hi

I have a event management system for events en festival is also create invites with qr-code but without any problem
What i do is when a user is added to the database i create a 19 digit unique 'barcode' number based on date+date...till milliseconds and the number
is stored in the database....you need it for scanning. you can do it on the OnNewRecord event of OnBeforePost

What i see from you code is that you created on the UnimFormCreate and possibe the same values are use for
creating the qrcode number.

I use fastreport to to create the qrcode imge...i have a report with the format off a general phone screen. 
Now can I set up other information besides the qr code like event name and entrance location and date/time

 

Link to comment
Share on other sites

Some more from my research...

procedure TuFrameDetails.UnimPanelSellMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  i,w,h : integer;
  s : string;
  QRCodeBitmap : tBitmap;
begin
  Randomize;
  s := '123456';
  for i := 1 to length(s) do
    s[i] := Chr(Ord('A')+ Random(26));
  with UniMainModule do
  begin
    sQR := sUserId + '-999999-'+ s;
    UnimLabelRef.Caption := sQR;
    QRCodeBitmap := CreateQRCode(sQR);
    try
      UnimImage1.Picture.Bitmap.Assign(QRCodeBitmap); // fits to string sQR from content 100% - but too small, so needs to be scaled to avoid antializing

      w := QRCodeBitmap.Width * 8;
      h := QRCodeBitmap.Height * 8;
      UnimImageQR.Picture.Bitmap.Width := w;
      UnimImageQR.Picture.Bitmap.Height := h;
      UnimImageQR.Picture.Bitmap.Canvas.StretchDraw(Rect(0,0,w,h), QRCodeBitmap);  // looks sharp, but content is not always in line with string sQR

    finally
      QRCodeBitmap.Free;
    end;
  end;
end;

So the problem happens if I try to use Strechdraw to the UnimImage bitmap. Also assigning a stretched bitmap does not work reliable. So in summary the content of UnumImage1 and UnimImageQR is sometimes (next to their size, which is obvious) different. In such a case  UnimImageQR shows something what happend in the past. I am using only one active browser window. 

Link to comment
Share on other sites

UserId is the record ID of the new created user record coming from the database and sTransferRef is randomly created 6 character string (as you can see from my last post - here the variable is called "s").
But the problem is coming from UnimImage component. It seems to load content coming from somewhere sometimes ?!?!?

error.png

Link to comment
Share on other sites

if a deviation is happening, it will happen in both parts of the string so  sUserId AND sTransferRef. This is so crazy, so I think I will make a test case for everybody, who is interesting in this case. 
Further news from my tests: If I increase the bitmap zoom factor from 8 to e.g. 80 the effect seams to go away !

Link to comment
Share on other sites

Attached you will find the simplified test-case. I have thrown out everything what is not needed. For testing the behavior you will need two running instances of the web-application. Best is to run it in two different Browser Windows. Click Refresh and a new QR-Code will generated. The sharp one is zoomed by factor 8. Once you have clicked refresh some times in the first browser window switch to the second one and click refresh here as long as you cannot see a difference in the QR-pattern. Sometimes it will take a while but I am pretty sure that you will see the effect, too.

TestCase.zip

Link to comment
Share on other sites

Sorry if I didn't make it clear. I will try to describe the effect again based on the testcase I created.
If you open the source code you will see that there is only one method, which is responsible to create a string, which then will be used to create a QR-Code bitmap using an external library. The content of the String is also assigned to a Label to make it visible. First part of the string is constant during a session and the last part varies with every mouse click on the refresh label.

The generated QR-Code bitmap will be assigned to two different unimImages. The first Image get the content of the QR-Code bitmap directly via :

UnimImage1.Picture.Bitmap.Assign(QRCodeBitmap);

The second UnimImage gets the content of the same QR-Code Bitmap via StretchDraw:

w := QRCodeBitmap.Width * 8;
h := QRCodeBitmap.Height * 8;
UnimImageQR.Picture.Bitmap.Width := w;
UnimImageQR.Picture.Bitmap.Height := h;
UnimImageQR.Picture.Bitmap.Canvas.StretchDraw(Rect(0,0,w,h), QRCodeBitmap);


So everybody now would think that next to the zoom level both images will look equal, but for whatever reason this is sometimes NOT the case.

If this happens the content of UnimImageQR is not something totally stupid, because if you scan the code with a QR-Scanner App its content string is something which was created before from a totally different session. So all this is totally unlogic and crazy, but it happens!

For whatever reason the zoom factor also plays a role here. A higher value than 8 seems to minimize the risk of this effect - don't ask me why. As some kind of a hotfix I am now using a zoom factor of 80 and only can pray that if the next event comes up it will not end in chaos again, with hundreds of visitors with doubled QR-Codes.

Link to comment
Share on other sites

Hi guys,

I really appreciate your help and support. It shows me again how important it is to have an active community of people willing to help.

Ultimately though, the QR code library is not the problem here. The problem comes from the UnimImage component, which is exhibiting this strange behavior. So I'm pretty sure that this effect also can occurs if you assign a different bitmap source to UnimImage. Of course, the effect is not so dramatic if it shows a puppy instead of a cat 🙂 .

Link to comment
Share on other sites

4 minutes ago, Kattes said:

Ultimately though, the QR code library is not the problem here.

Yes you are right.

5 minutes ago, Kattes said:

The problem comes from the UnimImage component, which is exhibiting this strange behavior. So I'm pretty sure that this effect also can occurs if you assign a different bitmap source to UnimImage. Of course, the effect is not so dramatic if it shows a puppy instead of a cat 🙂 .

I was not able to reproduce the issue. Sorry, maybe I didn't test well. 

Link to comment
Share on other sites

7 minutes ago, Kattes said:

Hi guys,

I really appreciate your help and support. It shows me again how important it is to have an active community of people willing to help.

Ultimately though, the QR code library is not the problem here. The problem comes from the UnimImage component, which is exhibiting this strange behavior. So I'm pretty sure that this effect also can occurs if you assign a different bitmap source to UnimImage. Of course, the effect is not so dramatic if it shows a puppy instead of a cat 🙂 .

Hello,

can You try to :

1. create QRCode 

2. Save to local File with name (QRDateTimeMiliseconds)

3. Load from file into image to show on end User

Link to comment
Share on other sites

23 minutes ago, irigsoft said:

Hello,

can You try to :

1. create QRCode 

2. Save to local File with name (QRDateTimeMiliseconds)

3. Load from file into image to show on end User

I had a similar idea, but to work with a MemoryStream instead of a file. Unfortunately, all these tests are very time-consuming and at the end I still don't know if the problem has really been solved or if I just didn't do enough tests to find the error.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...