Jump to content

How do you deal with the problem of plaintext?


huayan889

Recommended Posts

It is a security problem detected by a third party. The code is very simple:

procedure TUniLoginFrm.LoginButClick(Sender: TObject);
begin

...

    UniQuery1.Active := false;
    UniQuery1.SQL.Text := 'select * from ss_customer_info where (customer_id=' + chr(39) +
    UniEdit1.Text + chr(39) + ') and  (admin_id =' + chr(39) + UniEdit2.Text + chr(39) +
    ') and  (admin_pass=' + chr(39) + MD5(cl_decrypt(uniedit2.text)) + chr(39) + ')';
    UniQuery1.Open;

.....    
end;

Link to comment
Share on other sites

8 hours ago, huayan889 said:

UniQuery1.SQL.Text := 'select * from ss_customer_info where (customer_id=' + chr(39) +
    UniEdit1.Text + chr(39) + ') and  (admin_id =' + chr(39) + UniEdit2.Text + chr(39) +
    ') and  (admin_pass=' + chr(39) + MD5(cl_decrypt(uniedit2.text)) + chr(39) + ')';

By security reason it's better to use parameters in query. This ignore SQL injections.

I see that You use https, and third party can read raw of encrypted data ? - So we have man in the middle attack and all for him is readable ?!?

@Sherzod - do You have some proposal for this ?

 

Perhaps your problem with plain text is that: Your browser loads http content on the site (thus there are web attacks) and after loading this http content all data is readable. There are security topics and their solutions in the forum.
It is recommended to ensure that you always load https content and how to do it in unigui

Link to comment
Share on other sites

Examples:

Strict Transport Security: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
Always redirect to https !!!

forum with problem: https://superuser.com/questions/1107285/hsts-not-working-with-chrome
>>> the solution  of the problem: "For others who are seeing a similar issue - it may be because your browser has not yet accessed the site over HTTPS. Try accessing it over HTTPS and then again over HTTP. If HSTS is correctly implemented, then that last request should fail. MDN explains it nicely:"
>>> or this: "The problem was that i had no CA in chrome trusted store. Added exception manually. It looks like for such a scenario chrome does not honor HSTS headers. Once added CA to the trusted store everything is working fine - i also see my domain in chrome://net-internals/#hsts. Thanks ! "

"How do we make Browser go from HTTP to HTTPS without a ReDirect Script ", maybe this will help : https://www.thesslstore.com/blog/clear-hsts-settings-chrome-firefox/
google docs: https://www.chromium.org/hsts
 

Link to comment
Share on other sites

HTTPS is the business data of encrypted transport layer. Our packet capture is the application layer data, that is, the local data. When we process the account password, it has not reached the transport layer. So adding certificate can't solve the problem of account password plaintext transmission.

Link to comment
Share on other sites

1 hour ago, huayan889 said:

HTTPS is the business data of encrypted transport layer. Our packet capture is the application layer data, that is, the local data. When we process the account password, it has not reached the transport layer. So adding certificate can't solve the problem of account password plaintext transmission.

I am not security expert and my expertise of web security is too low, but what do You think for this, it is possible to use s-http for encrypted transport layer:

https://en.wikipedia.org/wiki/Secure_Hypertext_Transfer_Protocol

 

"S-HTTP encrypts only the served page data and submitted data like POST fields, leaving the initiation of the protocol unchanged. Because of this, S-HTTP could be used concurrently with HTTP (unsecured) on the same port, as the unencrypted header would determine whether the rest of the transmission is encrypted."

"In S-HTTP, the desired URL is not transmitted in the cleartext headers, but left blank; another set of headers is present inside the encrypted payload. In HTTP over TLS, all headers are inside the encrypted payload and the server application does not generally have the opportunity to gracefully recover from TLS fatal errors (including 'client certificate is untrusted' and 'client certificate is expired')."

 

Or what do you think is the best method to address the issue of "plaintext"

 

I'm also looking for various security vulnerabilities. 

I want to make unigui application more secured , and I know that "If the security problem is not solved, the system is not allowed to go online" is real live problem

Link to comment
Share on other sites

Would you test the code I will send you. If possible with feedback from read data?

I need some time to find a way to protect the application layer and return the code to you.
If you are clear with a method that can be applied to protect the layer, I would be happy to share and find a solution together

I'm not on the unigui team!

Link to comment
Share on other sites

17 hours ago, irigsoft said:

Would you test the code I will send you. If possible with feedback from read data?

I need some time to find a way to protect the application layer and return the code to you.
If you are clear with a method that can be applied to protect the layer, I would be happy to share and find a solution together

I'm not on the unigui team!

I can test the code you sent, 315795176& qq.com , replace with @&

Link to comment
Share on other sites

2 minutes ago, huayan889 said:

I can test the code you sent, 315795176& qq.com , replace with @&

Please try it

Hi,

I make some code for testing.

procedure TUniServerModule.UniGUIServerModuleHTTPCommand(
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo;
  var Handled: Boolean);

var
  sSessionID      : String;
  sAjaxValues    : TStringList;

begin

sSessionID := ExtractSessionId(ARequestInfo.UnParsedParams); //get Active Session ID


TRY
If (sSessionID <> '')
//UniServerModule.ProtectDataList.Values [sSessionID + 'User']  -  use it to save user
//UniServerModule.ProtectDataList.Values [sSessionID + 'Pass']   - use it to save pass (ProtectDataList=TStringList)


then begin
sAjaxValues := TStringList.Create;
sAjaxValues.Delimiter := '&';
sAjaxValues.StrictDelimiter := True;
sAjaxValues.DelimitedText := ARequestInfo.UnparsedParams;  //save UnparsedParams - plaintext data
TRY
  //if (POS (UniServerModule.ProtectDataList.Values [sSessionID + 'User'],sAjaxValues.Values ['_fp_']) > 0)
  //AND (TRIM (UniServerModule.ProtectDataList.Values [sSessionID + 'User']) <> '')
  if (sAjaxValues.IndexOfName ('_fp_') > 0)
  then begin
    sAjaxValues.Values ['_fp_'] := Stringreplace (sAjaxValues.Values ['_fp_'],UniServerModule.ProtectDataList.Values [sSessionID + 'Pass'], (MD5(UniServerModule.ProtectDataList.Values [sSessionID + 'Pass'],'123')),[rfReplaceAll,rfIgnoreCase]);
    ARequestInfo.UnparsedParams := sAjaxValues.DelimitedText;
    UniServerModule.ProtectDataList.Values [sSessionID + 'User'] := '';
  end;
  //if (POS (UniServerModule.ProtectDataList.Values [sSessionID + 'Pass'],sAjaxValues.Values ['_fp_']) > 0)
  //AND (TRIM (UniServerModule.ProtectDataList.Values [sSessionID + 'Pass']) <> '')
  if (sAjaxValues.IndexOfName ('_fp_') > 0)
  then begin
    sAjaxValues.Values ['_fp_'] := Stringreplace (sAjaxValues.Values ['_fp_'],UniServerModule.ProtectDataList.Values [sSessionID + 'Pass'],(MD5(UniServerModule.ProtectDataList.Values [sSessionID + 'Pass'],'123')),[rfReplaceAll,rfIgnoreCase]);
    ARequestInfo.UnparsedParams := sAjaxValues.DelimitedText;
    UniServerModule.ProtectDataList.Values [sSessionID + 'Pass'] := '';
  end;
  sAjaxValues.Clear;
  sAjaxValues.Free;
EXCEPT

END;
end;

end;

 

This will replace values of user and passward in Raw.
Please send me feedback with result.

Link to comment
Share on other sites

So, resolution is this:

 

uses HTTPApp;

//

procedure TUniServerModule.UniGUIServerModuleBeforeInit(Sender: TObject);
begin

//create list with elements for encriptions

ProtectDataList := TStringList.Create;

//We can load all names from file with settings
ProtectDataList.loadfromFile ('file with names of elements');

end;

 

procedure TForm_General.UniFormReady(Sender: TObject);
begin
//Add Components for encryption in Application Layer
if UniServerModule.ProtectDataList.IndexOfName (UniEditUser.Name) <= 0 then
    UniServerModule.ProtectDataList.Add (UniEditUser.Name + '=' + UniEditUser.JSName) //add JSName of Element for UserName
else UniServerModule.ProtectDataList.Values [UniEditUser.Name] := UniEditUser.JSName; 

if UniServerModule.ProtectDataList.IndexOfName (UniEditPass.Name) <= 0 then
    UniServerModule.ProtectDataList.Add (UniEditPass.Name + '=' + UniEditPass.JSName) //add JSName of Element for UserPass
else UniServerModule.ProtectDataList.Values [UniEditPass.Name] := UniEditPass.JSName;
end;

 

procedure TUniServerModule.UniGUIServerModuleHTTPCommand(
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo;
  var Handled: Boolean);

var
  fpName,fpValue,
  fpCompName            : String;
  sAjaxValues               : TStringList;
  I,J                               :  Integer;

begin

// if there is "_ft_" data on request, we will replace everything in it

If (POS ('_fp_',ARequestInfo.UnparsedParams)> 0)
AND (UniServerModule.ProtectDataList.Count > 0)
then begin
sAjaxValues := TStringList.Create; //create list with all values from request
sAjaxValues.Delimiter := '&';
sAjaxValues.StrictDelimiter := True;
sAjaxValues.DelimitedText := uniGUIJSUtils.URIDecode(ARequestInfo.UnparsedParams); //decode URL data from ARequestInfo
TRY
  if (sAjaxValues.IndexOfName ('_fp_') > 0)
  then begin
      //for a list of items for which we want the data to be encrypted
      for J := 0 to UniServerModule.ProtectDataList.Count - 1 do begin
        fpCompName := UniServerModule.ProtectDataList.ValueFromIndex [J]; //get JSName of component in Request
        fpName := sAjaxValues.Values[fpCompName]; //find data for jsname in Request
        fpValue := '';
        if fpName <> '' then begin
          for I := Length (fpName) downto 1 do begin
              case fpName [I] of
                   '%' : begin                        
                        delete (fpValue,1,2); //delete the last 2 characters, they were always% 02, so if% is found, delete 02
                        break;
                   end
                   else fpValue := fpName [I] + fpValue;
              end;
          end;//for I
          //replace value for component  , 123 is new value of data. This can be replaced with MD5 (fpValue)
          sAjaxValues.Values[fpCompName] := StringReplace (sAjaxValues.Values[fpCompName],fpValue,'123',[]);
         sAjaxValues.Values ['_fp_'] := HTTPEncode ('&' + sAjaxValues [sAjaxValues.IndexOfName(fpCompName)]);          //URL encoded all data for '_fp_'
          sAjaxValues.Delete (sAjaxValues.IndexOfName (fpCompName)); 

          ARequestInfo.UnparsedParams := sAjaxValues.DelimitedText; //set new values
        end;//If
      end;//for J
  end;//If
  sAjaxValues.Clear;
  sAjaxValues.Free;

EXCEPT

END;
end;

end;

 

This will replace in Request values in uniEditUser and uniEditPass with '123'.

Please send me feedback with third party test results.

Link to comment
Share on other sites

7 hours ago, irigsoft said:

So, resolution is this:

 

uses HTTPApp;

//

procedure TUniServerModule.UniGUIServerModuleBeforeInit(Sender: TObject);
begin

//create list with elements for encriptions

ProtectDataList := TStringList.Create;

//We can load all names from file with settings
ProtectDataList.loadfromFile ('file with names of elements');

end;

 

procedure TForm_General.UniFormReady(Sender: TObject);
begin
//Add Components for encryption in Application Layer
if UniServerModule.ProtectDataList.IndexOfName (UniEditUser.Name) <= 0 then
    UniServerModule.ProtectDataList.Add (UniEditUser.Name + '=' + UniEditUser.JSName) //add JSName of Element for UserName
else UniServerModule.ProtectDataList.Values [UniEditUser.Name] := UniEditUser.JSName; 

if UniServerModule.ProtectDataList.IndexOfName (UniEditPass.Name) <= 0 then
    UniServerModule.ProtectDataList.Add (UniEditPass.Name + '=' + UniEditPass.JSName) //add JSName of Element for UserPass
else UniServerModule.ProtectDataList.Values [UniEditPass.Name] := UniEditPass.JSName;
end;

 

procedure TUniServerModule.UniGUIServerModuleHTTPCommand(
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo;
  var Handled: Boolean);

var
  fpName,fpValue,
  fpCompName            : String;
  sAjaxValues               : TStringList;
  I,J                               :  Integer;

begin

// if there is "_ft_" data on request, we will replace everything in it

If (POS ('_fp_',ARequestInfo.UnparsedParams)> 0)
AND (UniServerModule.ProtectDataList.Count > 0)
then begin
sAjaxValues := TStringList.Create; //create list with all values from request
sAjaxValues.Delimiter := '&';
sAjaxValues.StrictDelimiter := True;
sAjaxValues.DelimitedText := uniGUIJSUtils.URIDecode(ARequestInfo.UnparsedParams); //decode URL data from ARequestInfo
TRY
  if (sAjaxValues.IndexOfName ('_fp_') > 0)
  then begin
      //for a list of items for which we want the data to be encrypted
      for J := 0 to UniServerModule.ProtectDataList.Count - 1 do begin
        fpCompName := UniServerModule.ProtectDataList.ValueFromIndex [J]; //get JSName of component in Request
        fpName := sAjaxValues.Values[fpCompName]; //find data for jsname in Request
        fpValue := '';
        if fpName <> '' then begin
          for I := Length (fpName) downto 1 do begin
              case fpName [I] of
                   '%' : begin                        
                        delete (fpValue,1,2); //delete the last 2 characters, they were always% 02, so if% is found, delete 02
                        break;
                   end
                   else fpValue := fpName [I] + fpValue;
              end;
          end;//for I
          //replace value for component  , 123 is new value of data. This can be replaced with MD5 (fpValue)
          sAjaxValues.Values[fpCompName] := StringReplace (sAjaxValues.Values[fpCompName],fpValue,'123',[]);
         sAjaxValues.Values ['_fp_'] := HTTPEncode ('&' + sAjaxValues [sAjaxValues.IndexOfName(fpCompName)]);          //URL encoded all data for '_fp_'
          sAjaxValues.Delete (sAjaxValues.IndexOfName (fpCompName)); 

          ARequestInfo.UnparsedParams := sAjaxValues.DelimitedText; //set new values
        end;//If
      end;//for J
  end;//If
  sAjaxValues.Clear;
  sAjaxValues.Free;

EXCEPT

END;
end;

end;

 

This will replace in Request values in uniEditUser and uniEditPass with '123'.

Please send me feedback with third party test results.

Just let the third party company test, the result is the same.
This problem can only be solved by encrypting the information from the browser.

Link to comment
Share on other sites

1 hour ago, huayan889 said:

Just let the third party company test, the result is the same.
This problem can only be solved by encrypting the information from the browser.

Thanks,

On the web i found many softwares for this purpose (encrypt data from browser), may be unigui can't make this by default.

 

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...