Jump to content

misc

uniGUI Subscriber
  • Posts

    97
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by misc

  1. Hello,
    i am currently converting an old source (v0.99...) to the newest uniGUI components.

    The code can be compiled after some adjustments but unfortunately the portal does not run. The log is full of errors.

    Unfortunately I can't get any further and maybe someone in the community has already gone through something similar.

    Here are the logs:

    xxx.exe: 00001D4C: 17:08:17 [HandleFileRequest[127.0.0.1]]:Access denied: D:\dev\Win32\Release\HandleEvent.
     

    Here the logs from HTTP Command Event:

    10.08.2020 17:08:17: [UniGUIServerModuleHTTPCommand]/127.0.0.1:8085/HandleEvent
    10.08.2020 17:08:17: [UniGUIServerModuleHTTPCommand]Ajax=1
    IsEvent=1
    Obj=O0
    Evt=cinfo
    ci=br=33;os=4;bv=84;ww=1920;wh=937
    _S_ID=2tk8ISSGRS1069497FD
    _seq_=0
    _uo_=O0
    _f_=1
    _fs_=401
    _fst_=Unauthorized

  2. Hi there,

     

    some of our customers are afraid about using RC4 in the cipher settings of our uniGUIServer. While the default from Indy10 (which is used in uniGUI) uses RC4 we tried to find a solution.

     

    In the OWASP (=open software security community) there is a cheat sheet about TLS Cipher Strings. We tried to implement the recommendations for a cipher string and we want to share this with you:

     

    Here is the link to the original document: https://www.owasp.org/index.php/TLS_Cipher_String_Cheat_Sheet

     

    Please read sections "Scenarios" in the link above to understand the different strength of cipher strings.

     

    Option 1 is to hard code the different cipher strings and provide it with a simple function:

    function GetCipherList(AStrength: Integer): WideString;
    const
      cCIPHER_LIST_1: WideString = 'DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256';
      cCIPHER_LIST_2: WideString = 'DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256';
      cCIPHER_LIST_3: WideString = 'ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA';
      cCIPHER_LIST_4: WideString = 'AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA';
      cCIPHER_LIST_5: WideString = 'DES-CBC3-SHA';
    
    begin
      case AStrength of
        // Advanced Plus (A+)
          1: Result := cCIPHER_LIST_1;
        // Advanced (A)
          2: Result := cCIPHER_LIST_1 + ':' + cCIPHER_LIST_2;
        // Broad Compatibility (
          3: Result := cCIPHER_LIST_1 + ':' + cCIPHER_LIST_2 + ':' + cCIPHER_LIST_3;
        // Widest Compatibility (C)
          4: Result := cCIPHER_LIST_1 + ':' + cCIPHER_LIST_2 + ':' + cCIPHER_LIST_3 + ':' + cCIPHER_LIST_4;
        // Legacy (C-)
          5: Result := cCIPHER_LIST_1 + ':' + cCIPHER_LIST_2 + ':' + cCIPHER_LIST_3 + ':' + cCIPHER_LIST_4 + ':' + cCIPHER_LIST_5;
        else
          Result := EmptyStr;
      end;
    end;
    
    procedure TServerModule.UniGUIServerModuleCreate(Sender: TObject);
    begin
      inherited;
      SSL.SSLOptions.CipherList := GetCipherList(1);
    end;
    

    Option 2 is to use a INI file and define the cipher string there. With this you are more flexible to quickly change the strenght and/or string itself.

     

    Comments welcome!

     

    Michael

    • Like 1
  3. ps. If you want to test it in your own environment just add this to your URL:

    If you test it in your project:
    
    http://<YOUR-IP>:<YOUR-PORT>/cache/<YOUR-PROJECT-EXE-NAME>/favicon.ico&%3Cimg%20src%3Da%20onerror%3Dalert(%22XSS-Attack%E2%80%9C)%3E
    
    If you create and run a Project1 test application:
    
    http://127.0.0.1:8077/cache/project1_exe/favicon.ico&%3Cimg%20src%3Da%20onerror%3Dalert(%22XSS-Attack%E2%80%9C)%3E
    
  4. The following URL is a proof of concept XSS payload. In this instance, an alert popup has been executed. This attack is possible as the URL entered by the user is copied into the "Access Denied" page and executed as a script:

     

    http://127.0.0.1:8077/cache/project1_exe/favicon.ico&%3Cimg%20src%3Da%20onerror%3Dalert(%22XSS-Attack%E2%80%9C)%3E

     

    Our fix or solution for this:

     

    We use the HTTPCommand Event in ServerModule. First of all we decode the Request URL with the TURLEncoder. With this we receive the clear text of the URL. Second we Encode the URL with the THTMLEncoder. After this we check if the original URL (in clear text) is different to the HTMLEncoded URL. If yes there are forbidden HTML Tags and we overwrite the Result and Cancel the Request. With this we are save to recognize all kind of HTML Tags in URL.

    uses
      UniGUIVars, System.NetEncoding;
    
    procedure TUniServerModule.UniGUIServerModuleHTTPCommand(ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo; var Handled: Boolean);
    const
      cResponseText = '<HTML>Forbidden characters in URI! Request cancled.</HTML>';
    var
      vURI1, vURI2: String;
      vURLEncoder: System.NetEncoding.TURLEncoding;
      vHTMLEncoder: System.NetEncoding.THTMLEncoding;
    begin
      inherited;
      try
        vURLEncoder := System.NetEncoding.TURLEncoding.Create;
        vHTMLEncoder := System.NetEncoding.THTMLEncoding.Create;
    
        vURI1 := vURLEncoder.Decode(ARequestInfo.URI);
        vURI2 := vHTMLEncoder.Encode(vURI1);
      finally
        vURLEncoder.Free;
        vHTMLEncoder.Free;
      end;
    
      if vURI1 <> vURI2 then
        begin
          AResponseInfo.ContentText := cResponseText;
          Handled := True;
        end;
    end;
    

    Michael

    post-1257-0-58544600-1494584199_thumb.png

  5. Hi,

     

    i'm not sure if it is possible to make a JS event (for example window.beforeClose) and call delphi code within this event? I need this for getting notified when the

    user closes the browser and/or browser window/tab.

     

    So basically i simply want to get noticed in the delphi code, when the browser-tab gets closed.

     

    thanks

  6. Hi Abaksoft,

     

    thanks for your idea, i like it but i have one scenario that could break up the idea:

    For example, if the system crashes, the i have more numbers in the table as connection count, so i know, the system

    of one user has crashed. The problem is i dont know which users system, what if one users system crashes and the others is working fine

    and another is trying to log in a second time.

     

    cheers

  7. Hi everyone,

     

    i'm having my project already set up, but i was thinking about the following.

     

    I want the a user-lock on login, that means, if a user is already logged in to the user-area or the user is logging in new, i dont want the same user to have another session.

     

    My idea is to add a field ('loggedIn') in my user-table of my database which i then use for the lock. BUT what if the session gets killed or the users database connection breaks up. Then i have a logged user which cant log in anymore.

     

    How do you handle this or whats your idea?

     

    Thanks

  8. Hello,

     

    i have a problem with a UniDBGrid with the following situation:

     

    Every time i make a SQL Call with "insert into" on my FireBird DB for the first time for a new user (of my cms, DB is not empty) and refresh the grid, the columns of my table are there but the entry is not. When i delete the entry (dbgrid is then empty) and make another call (insert into) and the same refresh method, the grid refreshes and i see the entry in the database. 

     

    My Question is, is this the right way?:

     

    1. SQL call: insert into...

    2. Database.ExecuteDirect(..)...

    3. DBGrid.DataSource.DataSet.Open;

    4. DBGrid.DataSource.DataSet.Refresh;

    5. DBGrid.Refresh;

     

    Do you have any other suggestions or ideas why it doesnt work on the first call?

  9. DelphiDeveloper helped me find the problem, which is also described here:
    http://www.sencha.com/forum/showthread.php?260320-4.2.0-Ext.suspendLayouts-causes-a-menu-to-be-not-rendered

     

    I used UniSession.AddJS('Ext.suspendLayouts()') in heavy control creation in order to eliminate unnecessary control painting, and in unhandled exceptions I dont reach UniSession.AddJS('Ext.resumeLayouts(true)');

     

    So solved this, not an uniGUI bug, but the global exception problem stll persists: How do I create a global exception handler?

     

    I tried this, but it is not called at all:
     

    procedure TMainForm.UniFormCreate(Sender: TObject);
    begin
      Application.OnException:= AppException;
    end;
    
    procedure TMainForm.AppException(Sender: TObject; E: Exception);
    //not called!
    begin
      UniGUIDialogs.ShowMessage(E.Message);
    end;
    
  10. Hello Farshad,

     

    as I am working heavily with databases, it is unfortunately very hard to catch every DB exception where it occurs. Also, when an exception occurs the app goes into some strange crash state, where the menus and some of the controls no longer work. Do you know anything about this? Why does it happen and how can I prevent it? Or in other words: if a database connection exception occurs (Zeos controls), why do the unigui menus no longer work. What does one thing have to do with the other?!

     

    And how can I handle the message problem? Any tricks? If I could show a message in the general UniGUIServerModuleException, then I could ask the user to restart the app, or even do it for him. At the moment, due to the crashed state after an exception, the user experiences the uniGUI application as unstable and with undetermined outcome.

    • Upvote 1
  11. I have an application that uses ZeosDb to access a mySQL database. When mySQL is restarted on the server, the app looses connection, and "Dataset.Active:= true;" raises an "ODBC call failed" exception, passing into the catch-all below:

    procedure TUniServerModule.UniGUIServerModuleException(Sender: TUniGUIMainModule; AException: Exception; var Handled: Boolean);
    begin
      if LikeList(AException.Message, ['*odbc*', '*sql server*']) then begin
        ShowMessage(rsDBReconnect);  //<--not shown
    
      end else
        ShowMessage(Sender.Name + ': ' + AException.Message);  //<--shown
    
      Handled:= true;
    end;
    

    Problem 1: the red message above is not displayed, even though we definitely pass here in debug mode. If a non-odbc error is encountered, the blue message is shown.

     

    Problem 2: after this event, all uniGUI menus are gone and the app does not really work anymore

     

    My guess is, that the exception itsself already puts the application into some strange state, where things like menus & dialogs dont work anymore.

     

    Any ideas how I can handle this?

     

  12. I dont know why this discussion about my project design is going on. And yes, creating controls at runtime in Delphi is a very common thing, and good practice or even necessary in many cases.

     

    But I feel that you prefer to complain than try the solutions we offer you.

     

    I found a solution myself without any Sencha tricks or misuse of components, posted it here to help others. I am not complaining about anything - all I wanted was to understand why my solution works and saves so much runtime. I am a Delphi programmer - I have no idea about how unGUI works (I have no source code), and I am not familiar with the extJS framework. Oliver was the only one who actually answered my question - everybody else seems to be complaing about my project design ;-)

     

    @ ZigZag: thank you again, those are some helpful suggestions and I will look into them.

    @ Farshad: I would love to send you a test case - I just don't have the time right now to extract the right lines of code from a 200.000 lines project. I hope maybe my observations together with others can help anyway.

    • Upvote 1
  13. Thank you Oliver, that's basically what I did and that explains it pretty well.

     

    Maybe Farshad can comment on this and suggest a better way. Might be good idea to have some kind of Client.PaintLocked until all controls are created. I've been missing this for the uniDBGrid as well. Every action leads to a painting of the grid, but again, maybe I'm missing something else here.

  14. @ Oliver: does this mean that everytime I create a control at runtime, the server "inserts" this into the client. That would mean, that for 100 creations the server has to insert 100 times in the client, whereas if I create all controls in a hidden form at runtime, then set the parent of my panel (containing the controls) to mainform, then this "big insertion" is done only once?

×
×
  • Create New...