Tag: security

  • Hashing Collisions

    One of the problems with hashing is that you can have collisions from values that are not very similar. This means that if you are using hashing as a way to identify similar values, you need to make further checks with the original data after the hash matches are gathered.

    This post will show a few examples of the collisions that can occur if you use the CHECKSUM() or BINARY_CHECKSUM() functions.

    If we examine this code:

    -- Checksum
    declare 
      @i varchar(200)
    , @j varchar(200);
    
    select @i = 'LE';
    select @j = 'AAAAAAAAAAAAAAAALE';
    
    select 
      Plaintext = @i
    , checksum = CHECKSUM(@i)
    UNION ALL 
    SELECT
      Plaintext = @j
    , checksum = CHECKSUM(@j);
    GO
    

    This returns a result like this:

    hashing2

    Note that these two values are the same as far as the checksum hash goes.

    If we switch to BINARY_CHECKSUM(), we can get similar results.

    -- binary_checksum is no better
    declare 
      @i varchar(200)
    , @j varchar(200)
    , @k varchar(200);
    
    
    select @i = 'LE'
    select @j = 'Ou'
    select @k = 'MU'
    
    select 
      Plaintext = @i
    , BINARY_CHECKSUM(@i)
    UNION ALL 
    SELECT
      Plaintext = @j
    , BINARY_CHECKSUM(@j)
    UNION ALL 
    SELECT
      Plaintext = @k
    , BINARY_CHECKSUM(@k)
    GO
    
    

    hashing3

    While these two functions can be useful, you do have to be careful with the results. A matching hash from these functions does not mean that the source data is the same.

  • Certificates Everywhere

    To me, certificates are the best way to secure communications and be aware of what’s allowed and what isn’t.

    One of the things that I think has been most disappointing to me in technology over the last few decades is the lack of progress is managing security keys and certificates. There hasn’t been a really good method designed that works well at scale for disparate organizations.

    Recently at the DevConnections conference, I saw a talk where Mark Minasi talked about the future of tablets and smartphones, where he mentioned the idea that we will use many devices in the future that don’t necessarily need to connect to the domain inside a company. They’ll still authenticate, but with certificates.

    That would be the ideal situation for me, a world where we individually have multiple certificates that identify us, and allow us to have secure communications, layers of security for different purposes, and a way to easily revoke, change, and add new certificates as needed. I’d be able to use easily manage certificates across devices to provide some level of authentication.

    As we move to the deep intermixing of user and company devices, it does start to make sense that we consider using a more ad hoc authentication scheme that can be deployed in a more distributed fashion, rather than the monolithic, authenticate to the domain completely or not at all, scheme we have now.

    I don’t have a solution worked out, but I know there are some very smart security people out there and I’d hope that they are working on a variety of solutions that will increase the security we have, while allowing us lots of flexibility.

    Steve Jones


    The Voice of the DBA Podcasts

    We publish three versions of the podcast each day for you to enjoy.

  • Ownership Chains in SQL Server

    Someone asked the question recently about allowing a user to run a process,but not execute the individual pieces of the process. I replied that ownership chains allow this, and then explained things. Here’s a short example of that.

    Let’s suppose I have a process that removes data from a table and then reloads it. Perhaps it’s a report, perhaps it’s a static look at inventory, it doesn’t matter. Can I allow a normal user to execute the entire process, but not the clear or load pieces?

    I can, and here’s how.

    Suppose I have a clear procedure:

    CREATE PROCEDURE dbo.spClear
    AS
    BEGIN
       select 'Clear'
    END
    go

    For the sake of this example, I don’t have any work here, but the "SELECT ‘Clear"’” could be replaced by a TRUNCATE TABLE or other statement.

    By default in SQL Server, I don’t have rights to execute procedures that I haven’t created. In this case, assume a db_owner created this procedure, so a normal user, Joe, would not be able to execute it. In fact, if I log in as Joe and run this, I get:

    SETUSER 'Joe' 
    go
    -- Fails
    EXEC spClear
    go
    

    Msg 229, Level 14, State 5, Procedure spClear, Line 1

    The EXECUTE permission was denied on the object ‘spClear’, database ‘db1’, schema ‘dbo’.

     

    That’s expected, and it’s good.

    Let’s also create a load procedure, as the db_owner.

    CREATE PROCEDURE dbo.spLoad
    as
    BEGIN
       select 'Load'
    END
    go

    Now to manage the process, let’s create a wrapper stored procedure that calls these. For the sake of tracking what’s happening, I have a few statements in there.

    CREATE PROCEDURE dbo.spRefresh
    AS
    BEGIN
       select 'Refresh start'
       EXEC spClear
       EXEC spLoad
       SELECT 'Refresh End'
    END
    go

    If I were to call this process, this is what I’d expect from the call stack:

    • a call spRefresh
    • a result set returning “Refresh Start’”
    • a call to spClear
    • a result set returning “Clear”
    • return to spRefresh
    • a call to spLoad
    • a result set returning “Load”
    • a return to spRefresh
    • a result set returning “Refresh End”
    • end of spRefresh

    Obviously I could have actual delete or truncates in the clear procedure and then some insert in the load procedure. If I attempt to run this as Joe, I get:

    Msg 229, Level 14, State 5, Procedure spRefresh, Line 1

    The EXECUTE permission was denied on the object ‘spRefresh’, database ‘db1’, schema ‘dbo’.

    Expected, because I haven’t granted Joe rights. Let’s do that and execute the procedure:

    GRANT EXECUTE ON dbo.spRefresh TO Joe
    go
    SETUSER 'Joe' 
    GO
    EXEC spRefresh

    I get what I expected for results:

    ownership_a

    I have rights to execute spRefresh. Since the same owner exists for all three objects, dbo in this case, I have a chain that permissions are not checked for spLoad and spClear. I can execute them in the context of spRefresh.

    What about separately?

    EXEC spLoad

    gets me:

    Msg 229, Level 14, State 5, Procedure spLoad, Line 1

    The EXECUTE permission was denied on the object ‘spLoad’, database ‘db1’, schema ‘dbo’.

    and

    EXEC spClear

    gets me

    Msg 229, Level 14, State 5, Procedure spClear, Line 1

    The EXECUTE permission was denied on the object ‘spClear’, database ‘db1’, schema ‘dbo’.

    A nice way to allow someone to execute a group of processes without allowing them to execute any individual one.

  • Restoring a Certificate

    I have written about creating a certificate and backing up a certificate, and the next step is the restoration of a certificate into a server instance. This post covers the basics of restoring a certificate.

    There is no RESTORE CERTIFICATE command because the CREATE CERTIFICATE command accomplishes the same thing. It is expected that many people will get a certificate from another company that is a trusted provider, and in that case, they would create their SQL Server internal certificates from the files provided by the vendor.

    However you get your certificate, it will come as two separate files. A .cer file, which is the public key for the certificate, and the .pvk file, for the private key of the certificate. These are the same files that are were created by the makecert.exe utility. They are also the files that were created by the backup in the last post.

    To restore the certificate, you perform the same procedure as the CREATE CERTIFICATE. For my exported certificate, I’ll execute:

    create certificate MySalaryCert
     from file = N'c:\EncryptionPrimer\MySalaryCert.cer'
     with private key
      ( file = N'c:\EncryptionPrimer\MySalaryCert.pvk'
      , decryption by password = N'AReallyStr0ngK#y4You'
       );
    
    

    This will load both the public and private sides of the encryption key into SQL Server and you can view them with this DDL:

    select
      name
    , certificate_id
    , pvt_key_encryption_type_desc
    , subject
    , expiry_date
    , start_date
    , thumbprint
    , pvt_key_last_backup_date
     from sys.certificates
    
    

    This will show you the results. There are other fields here, but these are the ones I look at to check that this is the proper key. Note that on CREATE, the last backup date is NULL, even if you created this from a file.

    cert2

    cert3

    Note that there are other uses for certificates in Windows. You can install them for IPSec, for SQL Server SSL communications, and more. If you use certificates for any purpose, be sure you can back them up, restore them, and properly manage passwords.