Differences

This shows you the differences between two versions of the page.

Link to this comparison view

it:ad:patterns:don_t_drop_your_pants_strategy [2019/03/24 12:02]
it:ad:patterns:don_t_drop_your_pants_strategy [2019/03/24 12:02] (current)
Line 1: Line 1:
 +# IT:​AD:​Patterns:​Don'​t Drop your pants Strategy #
 +
 +
 +
 +<callout type="​Navigation"​ class="​small">​
 +* [[../​|(UP)]]
 +{{indexmenu>​.#​2|nsort tsort}}
 +
 +
 +</​callout>​
 +
 +
 +<panel title="​Summary">​
 +
 +{{ https://​dl.dropbox.com/​u/​11851202/​PUBLIC/​SKYS/​Posted/​IT/​AD/​Design/​Patterns/​Security/​horde_of_invaders.png}}Security is *hard* with a capital H. 
 +
 +Mainly because there'​s only a handful of you developing the walls, while there'​s a whole horde of people banging away at your ports.
 +
 +So you want to ensure that you don't give them the *keys* to the place, right?
 +
 +
 +</​panel>​
 +
 +
 +## Process ##
 +
 +Even if you use an [[IT/#​AntiForgeryToken/​]],​ don't round trip your database keys/ids as [[IT/#​ClearText/​]].
 +
 +In other words, although you need to round trip to the end user an Id of some kind in the View Model being rendered, or the [[IT/#​ViewModel/​]] being sent up to the [[IT/#User Agent/]], don't send out a database *key*.
 +
 +Obfuscation won't help either.
 +
 +>​It'​s pretty common to see users send out compressed Guids -- guids collapsed to the shortest amount of string text as possible. But that's not enough to thwart a determined [[IT/#​Threat/​]].
 +
 +The very least you can do is combine it with a secret they don't have.
 +
 +### XOR ###
 +
 +A simple first step solution is using something like:
 +
 +
 +<sxh csharp>
 +void Main()
 +{
 + //Server
 + var secretId = new Guid("​2b6f0cc9-04d1-37be-2e17-30235f566409"​);​
 + secretId.Dump();​
 + byte[] secretBytes;//​ = secretId.ToByteArray();​
 + secretBytes = GetBytes( "​Special"​ + secretId.ToString("​D"​),​ 100);
 +
 +
 +
 + var sessionId = Guid.NewGuid();​
 + sessionId.Dump();​
 + var sessionBytes = sessionId.ToByteArray();​
 +
 +
 +
 + byte[] xor = new byte[sessionBytes.Length];​
 + for (int i=0;​i<​sessionBytes.Length;​i++)
 + {
 + xor[i] = (byte) (secretBytes[i]^ sessionBytes[i] );
 + }
 + var result =  ByteArrayToString(xor); ​
 +
 +//Send it out...
 +//...
 +//Get it back...
 + xor = StringToByteArray(result);​
 + var xor2 = new byte[sessionBytes.Length];​
 + for (int i=0;​i<​sessionBytes.Length;​i++)
 + {
 + xor2[i] = (byte) (xor[i] ^ secretBytes[i]);​
 + }
 +
 +            ​
 + Guid g = new Guid(xor2);
 + g.Dump();​
 + }
 +
 + public static byte[] StringToByteArray(String hex)
 + {
 + int NumberChars = hex.Length;
 + byte[] bytes = new byte[NumberChars / 2];
 + for (int i = 0; i < NumberChars;​ i += 2)
 + bytes[i / 2] = Convert.ToByte(hex.Substring(i,​ 2), 16);
 + return bytes;
 + }
 +
 + public static string ByteArrayToString(byte[] ba)
 + {
 + StringBuilder hex = new StringBuilder(ba.Length * 2);
 + foreach (byte b in ba)
 + hex.AppendFormat("​{0:​x2}",​ b);
 + return hex.ToString();​
 + }
 +
 +static byte[] GetBytes(string str, int length=0)
 +{
 +    if (length == 0){length = str.Length * sizeof(char);​}
 + byte[] bytes = new byte[length];​
 + var src = str.ToCharArray();​
 + System.Buffer.BlockCopy(src,​ 0, bytes, 0, Math.Min(length,​src.Length));​
 + return bytes;
 +}
 +static string GetString(byte[] bytes)
 +{
 + char[] chars = new char[bytes.Length / sizeof(char)];​
 + System.Buffer.BlockCopy(bytes,​ 0, chars, 0, bytes.Length);​
 + return new string(chars);​
 +}
 +// Define other methods and classes here
 + </​sxh>​
 +
 +
 +You can then compress/​obfuscate that to your hearts content afterwards.
 +
 +
 +### Addendum ###
 +
 +Note that using Guid's as an Id is always problematic...They'​re fast as heck when indexed -- the problem is that they are *random* and when a new record is created, the guid has to be inserted into the index table...somewhere...if it is near the top, it has to move down everything below it...you can see how that quickly gets slow. Much slower than an auto-incrementing integer that always sticks it at the end.
 +
 +Hence why I recommend looking at the DistributedIdentifierService in XActLib the next time you need a Guid that's *ordered* and unique across platforms (yup ;-).
 +
 +
 +