Wednesday, 15 November 2017

How to interview for a Senior Developer

This is based on my experiences in the UK, trying to recruit quality people into Senior positions. My conclusion, there is a very big difference between how people view themselves and how I view the role of Senior Developer. The average salary request for a Senior Dev in the UK (outside of London) is about £50K+ ($65K+), which for many companies is a lot of money to pay out in addition to the recruiters fees, which can be anything up to about 25% of that yearly salary and all of this before you even know whether the person is any good.

I am an employer and I get nervous when I interview someone. They are usually polite and of course they can do the job that you need them to do but the simple truth is that the recruiter and the potential recruit have a virtually zero-risk opportunity to talk themselves up to convince me they can do the job. If I take the risk on them and they are not very good, I either have to let them go at 3 months, losing several thousand in recruiters fees and potentially wasting a lot of time on a person who takes more than they are bringing to the company.

If you are that person who is applying for a role at my company, what am I going to ask you?

Firstly and hopefully this shouldn't be a shock, I am going to ask you about your experience in the areas of the job description. Example: This position requires a strong interest or experience in web application security. "Tell me about your experience in web application security", "I haven't done much". "Then why are you here wasting my time just on the hope that somehow you will convince me that I should still take you on?"

We even had a guy apply for a Development Manager position and all of my questions about, "What will you need to do as a Manager that you don't currently do as a Developer?" basically caused responses along the lines of "erm...", "hmmm.." as if the person hadn't even asked himself what a Development Manager actually does.

Secondly, I will ask what it is that makes you Senior (even if you are not a Senior, I would still ask you what separates you from the crowd) and I am fed up with the number of times that the answer is basically, "It means I have more experience", "What experience do you have that a Junior doesn't?". "Ermm...."

What do you know about Dependency Injection? IoC Containers? Test-Driven-Development? Deployment? The cloud? Node js? Angular?. These are all things that I would expect a Senior Developer to understand. Not to be super-experienced: we don't all get to do these at work - but anyone with any decent interest in web design meets these subjects all across the web. Even if you don't know exactly what it is, do you not even know the basics of why an IoC container might be useful? If not, why not?

Thirdly, I will ask why you are special. So you know some stuff about .Net and you have been programming for 15 years? Top tip: I don't care about anything before the last 5 years because we don't use Web Forms, VBA or FoxPro here! We are a startup and it takes commitment, interest and passion. Don't have a blog? Why not? Your own web site? Involved in any clubs outside of work? Developer hangout events? Member of an Institution?

The simple reality is that for most of the people we have interviewed, the sum total of their CV is: I have been writing code for average companies for X years and there is nothing that demonstrates that I am anything other than a sheep who will do what I'm told but I never think of the bigger picture and my job is largely just to pay the bills.

Even though the market for Developers in the UK is massive and the supply is terrible, I will not take any person on who is asking for £50K just because they have 15 years in the business. If you want that Senior Developer job, you should love coding. You should love it so much that you can easily demonstrate how much you love it. How you owned stuff in your previous job, you were the go-to person, you built stuff, fixed stuff, upgraded it, especially when you weren't asked to do it!

.Net MVC Controller Action 404 only on one system!

We have an existing web app that is running successfully in production. We deployed it to a new machine and any action we try and access on a certain controller returns a 404 (an IIS one, not the custom 404 page that we use in the app). The Home controller and another controller seemed to work as expected.

Logging proved fruitless, perhaps because the underlying problem was masking the logs.

Long story short: The controller that wasn't working had a default constructor (that was creating some services). One of these services was failing (as it happens due to the format of a connection string being incorrect), which caused the constructor to fail and rather than a 500, IIS/.Net was producing a 404 instead!

Because of the lack of usable logs, I had to keep commenting things in and out to work out what was actually going wrong (as well as adding an empty 'test' action to remove any other possible variables).

Tuesday, 24 October 2017

Address labels in PHP without special software

This sounded like a simple job. Print out address labels from a database in a certain format (8 x 2 labels on a page) in a way that can then be printed directly onto the label sheets. Easy right?

Not so much. HTML and CSS3 is supposed to add a load of print functionality and physical sizes but they don't work well at all. Browser treat them all differently, Chrome applies margins in addition to what you set in CSS so everything gets squashed and whatever I tried, it didn't seem to make sense. On top of that, the Developer tools allow you to render using the print css but this does not really allow a real print preview while tweaking the styles.

Fortunately, I chanced upon a suggestion to use FPDF, a PHP library to generate PDFs in code. It looked easy enough although unfortunately, you cannot simply create a fixed size "cell" and wrap text in it. A Cell is one line of text and multi-cell will simply create more cells for each new line of text. Not quite right but fortunately, using the position functions setX, setY etc. the maths is relatively simple to keep track of column number, row number and then work out where to add a new page.

Use the following code as a reference - note it is from Yii 2 framework and so some of this won't be relevant to you. Then check out the notes below for additional help.

public function actionAddresslabels()
{
    $request = \Yii::$app->request;

    // Set defaults for layout
    $cols = $request->get('cols', 2);           // Number of columns
    $rows = $request->get('rows', 8);           // Number of rows
    $top = $request->get('top', 8);             // Top margin in mm
    $left = $request->get('left', 5);           // Left margin in mm
    $vspacing = $request->get('vspacing', 0);   // Spacing vertically between each label in mm (excludes outside margins)
    $hspacing = $request->get('hspacing', 2.5);   // Spacing horizontally between columns in mm (excludes outside margins)
    $padding = $request->get('padding', 3);

    // Compute some numbers
    $pageSize = $rows * $cols;
    $colSpacing = (210.0 - (2*$left) + $hspacing) / ($cols);
    $rowSpacing = (297.0 - (2*$top) + $vspacing) / ($rows);

    $dataProvider = new ActiveDataProvider([
        'query' => User::find()
            ->joinWith(['applications'])
            ->where(['year' => Date('Y')]),
        'pagination' => false,
    ]);

    // Load data into local variables for loop
    $models = $dataProvider->getModels();
    $modelCount = $dataProvider->getCount();
    $currentModel = 0;
    $currentY = 0;
    $currentX = 0;

    // Basic setup of PDF
    $pdf = new FPDF();
    $pdf->SetLeftMargin($left + $padding);
    $pdf->SetTopMargin($top + $padding);
    $pdf->SetFont('Arial','',11);
    $pdf->SetAutoPageBreak(false);

    // For each cols x rows of addresses, add a page and render them correctly
    while ( $currentModel < $modelCount )
    {
        if ( $currentModel % $pageSize === 0)
        {
            $pdf->AddPage();
            $currentX = $left + $padding;
            $currentY = $top + $padding;
        }
        $pdf->SetXY($currentX,$currentY);
        $pdf->SetLeftMargin($currentX);
        $model = $models[$currentModel];
        $this->writeAddressLabel($pdf, $model);
        $currentY += $rowSpacing;
        if ( $currentY > (297 - 20) )
        {
            $currentY = $top + $padding;
            $currentX += $colSpacing;
        }
        $currentModel++;
    }

    $this->layout = false;
    \Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
    $pdf->Output();
    \Yii::$app->end();
}


  • The first section allows you to pass different values from the defaults into the query string for this action.
  • $padding allows all the text to be in from the top-left corner of each label and needs to be included in various calculations
  • The second section does some calculations for page size (number of labels total per page), column and row spacing are the pitch values so include the gutters between the labels.
  • The ActiveDataProvider is simply how I am querying the people to produce labels for. What I end up with is an array of objects ($models) that I will pull the individual address parts from.
  • $modelCount is simply used to control how long the loop below will continue for
  • The next section sets some static values for the PDF instance. The margins will shift all of the setXY stuff in from the edges of the page.
  • The main loop goes through all of the "users" in my models array 1 by one. 
  • The first section inside the loop uses mod arithmetic to see whether the current item is the first on a page, in which case a new page is created, and the X and Y positions are reset (they are relative to the current page, not the entire document).
  • The cursor is then positioned with SetXY
  • SetLeftMargin is called to ensure the current column has a hard left edge, otherwise the text becomes indented.
  • The method WriteAddressLabel is a helper method in my class that simply contains a number of calls to $pdf->Write(5,$model->town.PHP_EOL); With some wrapped in if ( $model->address3 !== "") so that they are not printed if blank. In your code, they might equate to null but in my code, they are blank strings if not set.
  • After the address is written, the Y position is moved down by a label pitch and then if this goes below the bottom of the page (hard-coded for A4 paper size 297mm minus a margin), then the column is incremented, Y is reset back to the top. We do not need to check for the column overflowing the page, since the mod arithmetic at the top of the loop will automatically create a new page when we have written the total number of items on the page.
  • The 4 lines below the loop are partly methods to tell Yii to output the correct format and not render a HTML layout and the call to $pdf->Output() closes the document and sends it to the standard output, which in this case is the response object.


Monday, 16 October 2017

JWT, JWE, JWS in .Net - Pt 3 - JWE

JWE is the encrypted version of a JWT. Encryption provides a way to ensure privacy of the data from an attacker and if using a pre-shared key, a very strong way of transmitting private data.

The .Net version of the JWT libraries does not also require a signature to be applied, you could assume that the data has integrity if you use an AEAD algorithm for encryption - which you should. However, it appears that you cannot validate the token if it does not have a signature - I'm not sure if there is a way to do that or whether it does not make sense to validate a token with no signature?

Fortunately, to produce a JWE in .Net is very similar to producing a JWS, although you need to generate a cryptographically secure symmetrical key as well as using a certificate to sign it. Naturally, all of this has overhead so although encryption-by-default can be useful, it does come at a price, especially for high-volume systems.

To create a key (the Content Encryption Key - CEK) , you can either just use RNGCryptoServiceProvider from the System.Security.Cryptography namespace like this:

var crng = new RNGCryptoServiceProvider();
var keyBytes = new byte[32];   // 256 bits for AES256
crng.GetBytes(keyBytes);

Or you can hash some other piece of data using SHA256 to stretch it. Be careful with this method since you need the input to the SHA function to already be cryptographically secure random or an attacker could discover a pattern and work out how you generate your keys! For instance, do not stretch a numeric userid or guid. In my case, I was stretching a 32 character randomly generated "secret" from an oauth credential to create my pre-shared key.

var keyBytes = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes("some data to stretch"));

Be careful with SHA256 and other cryptography classes for thread safety. It might be quicker to pre-create certain types like SHA256 but if ComputeHash is not thread safe, you might break something when used by multiple threads. I believe some forms of the .Net cryptography classes are thread safe and others are not.

Once you have your CEK, the only extra step is to create EncryptingCredentials as well as SigningCredentials:

var symSecurityKey = new SymmetricSecurityKey(keyBytes);
var creds = new EncryptingCredentials(symSecurityKey, SecurityAlgorithms.Aes256KW, SecurityAlgorithms.Aes256CbcHmacSha512);

Note that you need to use algorithms that are supported in .Net (I can't guarantee that the SecurityAlgorithms enum equates to what is supported), that the selected algorithms match the length of the key provided (i.e. 32 bytes for AES256) and that the second algorithm, which is used to encrypt the actual data is a type that includes authenticated data - i.e. a signature for the encrypted data to verify it was not tampered with before decrypting (such as GCM or HMACSHA). If you choose the wrong length of key, the call to CreateSecurityToken will throw a ArgumentOutOfRangeException. The first algorithm is the one that will be used to encrypt the key itself before it is added to the JWE token.

You can use RSA-OAEP for the first parameter but this is not the same as when it is used for the JWE. Firstly, it will only use a 256 bit key for RSA to match the second algorithm (the size of the key) but also, it will need a public key to encrypt and the recipient of the token will need the related private key to decrypt the CEK.

By providing the SigningCredentials and EncryptingCredentials to the call to CreateSecurityToken(), the library will create the token, sign it and then encrypt this as the payload in an outer JWE. This means that the header for the JWT will only contain data about the encrypting parameters (alg, enc etc) and only after it is decrypted, will the signing parameters be visible.

As mentioned before, you do not have to set a SigningCredential but when I tried this, the call to ValidateToken failed which sounds like it cannot validate data that is only encrypted, which might be possible to bypass (since the encrypted data already requires the use of an authenticated algorithm),

Validating is otherwise the same as it is for JWS, except for also setting the value of the TokenDecryptionKey in the TokenValidationParameters in the same way as it was set when it was created.

JWT, JWE, JWS in .Net - Pt 2 - Validating JWS

Fortunately, validating a JWS (and for that matter, a JWE) is very straight-forward thanks to JwtSecurityTokenHandler.ValidateToken().

Quite simply, you take the serialized string, create a TokenValidationParameters object with the relevant fields filled in to validate and then call ValidateToken, it looks like the following. Note that the same code is used for JWS and JWE tokens, the only difference is whether you fill in the TokenDecryptionKey property. This shows both:

 private ClaimsPrincipal ValidateToken(string tokenString, byte[] keybytes)  
 {  
   var signingkey = new X509SecurityKey(new X509Certificate2(certFilePath,certPassword));  
   var jwt = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(tokenString);  
   // Verification  
   var tokenValidationParameters = new TokenValidationParameters()  
   {  
     ValidAudiences = new string[]  
     {  
       "123456"  // Needs to match what was set in aud property of token
     },  
     ValidIssuers = new string[]  
     {  
       "https://logindev.pixelpin.co.uk"  // Needs to match iss property of token
     },  
     IssuerSigningKey = signingkey,  
     TokenDecryptionKey = keybytes == null ? null : new SymmetricSecurityKey(keybytes)  
   };  
   SecurityToken validatedToken;  
   var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();  
   return handler.ValidateToken(tokenString, tokenValidationParameters, out validatedToken);  
 }  

In my method (in a Unit Test), I simply return the ClaimsPrincipal that is returned from ValidateToken() but you could also get the validated and decrypted token that is returned as an out parameter if you wanted to continue to use it.

Also note that I am simply loading the same pfx I used to sign the token to validate it, whereas in real like, you are likely to visit the url of the issuer and perhaps https://theurl.com/.well-known/jwks and find the public key for the signed data using the kid property from the token.

This method allows the caller to pass null for the keybytes if only validating a signed JWS or real key bytes matching the encryption key used for the JWE. This is for pre-shared keys only. In a later post, I will talk about extracting the encryption key, which is actually embedded in a JWE and does not need to be pre-shared.

In part 3, we'll look at JWE (encrypted JWT)

Friday, 13 October 2017

JWT, JWE, JWS in .Net

JWT in .Net

When I first approached the idea of doing JWT (json web tokens) in .Net, it all seemed a little confusing.

Firstly, it IS confusing because Microsoft have started with a Microsoft.IdentityModel.Tokens namespace, which was eventually migrated into System.IdentityModel.Tokens, deprecating the original namespace but THEN, they added new functionality in System.IdentityModel.Tokens version 5 that references NEW code in Microsoft.IdentityModel.Tokens (which is resurrected). All the usual chaos has started since some things are the same (most class names), some are different. Some code written for v4 of System.IdentityModel.Tokens will not work in version 5. Anyway...

The Basics

Before you can understand how to do this, you should know what json is (JavaScript Object Notation), which is a fairly small way to move data around - much smaller than xml for instance, but it is generally web friendly.

You should also understand the basic concepts of signing and encryption.

Signing using asymmetric key encryption (RSA, DSA etc) allows you to create a packet of data, sign it with your private key and send it to a recipient. Even though the data is NOT private because it is NOT encrypted, the recipient can use your PUBLIC key to verify the signature that you applied to the data, which provides 2 protections (assuming keys are secure etc.) Firstly, it provides integrity of the data. An attacker could not modify the data and leave a valid signature since the private key needed to produce the signature is not available to the attacker. The recipient would know this when they validate the token and should/must discard the data if the signature fails. Secondly. signing provides non-repudiation, which means the sender cannot deny signing the data unless they admit to losing their private keys to an attacker.

It is also possible to sign the data with a symmetrical key, which would be useful if the sender and receiver already have a securely shared secret, which would therefore remove the need to perform asymmetrical signing/verifying, which is computationally expensive. (See Amey's answer here). Obviously this means that either party or anyone who is given this secret can also sign data so is not normally used.

Encryption is about obscuring the real data so an attacker cannot read the data when it is at rest or in transit. With encryption, it is assumed that either there is a securely shared key or that the same key can be derived using something like Diffie-Hellman key exchange.

JWT is an abstract idea that is made concrete in 2 sub-types.

JWS is a form of JWT for signed data, it is not encrypted.

JWE is an encrypted and signed form of JWT.

JWS - Json Web Token Signed

JWS is relatively straight-forward. It is composed of a json header with typ, alg and kid to identify the type ("jwt"), algorithm (signing algorithm, for example "RS256" or a URL for RSA) and the key identifier so the recipient knows which key can be used to verify the signature.

You will need the namespaces:

using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Cryptography.X509Certificates;

You can create a header either explicitly in .Net or you can allow the helper method CreateSecurityToken to do it for you:

Method 1: Create the JwtHeader yourself (from certificate in this case)

var key = new X509SecurityKey(new X509Certificate2(certFilePath,certPassword));
var algorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";     // RS256
var creds = new SigningCredentials(key, algorithm);
var header = new JwtHeader(creds);

Method 2: Use CreateJwtSecurityToken helper method

var handler = new JwtSecurityTokenHandler();
var token = handler.CreateJwtSecurityToken(issuer, audience, null, creationTime, creationTime.AddSeconds(lifetime), creationTime, creds);
// token now has header automatically

In method 2, the payload is being populated at the same time as the header.

After the header is the payload, which is another json dictionary (a claims list) with some standard claims such as nbf (not before), exp (expiry), iss (issuer) and aud (audience i.e. recipient) as well as any other additional claims that you wish to send. Issuer can be any string that is relevant but if you are using public key discovery, it is useful to use a URL that can be used to lookup .well-known/jwks to see a list of keys related to key ids (kid in the header of the JWT)

If using the first method, you can create the payload in a number of ways but this is probably the easiest:

var payload = new JwtPayload(
    token.Issuer,
    token.Audience,
    null,
    token.CreationTime.UtcDateTime,
    token.CreationTime.AddSeconds(token.Lifetime).UtcDateTime);

payload.AddClaims(token.Claims);
var handler = new JwtSecurityTokenHandler();
var token = new JwtSecurityToken(header, payload);

token is simply an object that contains the data to serialize into JWT.

The second method above already shows how to add the required payload (nbf,exp,iss,aud) in the same call to CreateJwtSecurityToken. Other claims would need to be added afterwards simply by calling token.Payload.AddClaims().

Once these are created, the data is combined and the signature computed across the data using the specified algorithm and key. Once this is done, each of these is base64 encoded and concatenated with a period (.) into 3 blocks. This part is really easy because if you have specified your key correctly, you simply tell the handler to write the token:

var serializedJwt = handler.WriteToken(token);

The result might look something like this:

eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNyc2Etc2hhMjU2Iiwia2lkIjoiMjVGN0Y2NThDQ0E2NjI2QjRENTdBNEExQTMyOUUyMjBDMjNEQUI3QSIsInR5cCI6IkpXVCJ9
.eyJuYmYiOjE1MDc5MTA0NDAsImV4cCI6MTUwNzkxMDQ3MCwiaXNzIjoicHAiLCJhdWQiOiIxMjM0NTYiLCJteWRhdGEiOiJzb21ldGhpbmdpbmhlcmUifQ
.TNSLgLuj-j9eSC5HiQqS86LLjZ6ZJnGoMAkGMsTqY-pjptQ8qItmrrSE3bf12E5aYHfNr4IWmSdY4-qkQRUXmtb-Ev2c0wE5NkABYqRdAok-AHuBUcRds7VrEQTanB69sKAhtEIZHshLPc4D9IMlYpc2opOzTCBGIB15mX0HodF6hdP6-LeaEeM-rR8v6bnmMsuvzu3GSGOSvPRm_yvZv25ywp4IzEYlbmLcw6NBJt4fx_8ZSEvIQtvCYtMgtAkFbiJ85Lo3sY7m8o8w84ChIG4AgDQi-woRwGU-3RFouppmAgjqPMCgMYn5Tt7Q3rjVtAgulMv0z0tVNvmOVg0zt04sI-CJIkgimAdaNM-O35Lyh4DzPasOXM_HsZ5_3EQoQn1pVRNU_6iBy4X1vGTRNICZon0x3v2MLvQQskaKfbUkSEqs1mceKXgu3cp6GRdT18z1ZUduP5hNYrysCvXtYjmcmmjC-RbnjgNcv3vC51gZvoyQ5OvmtBIvYv_QF14paV1uIxxd8Z_P0z0Z4RrNokUkWwb2n4RYOmW0Ihs7HR-1ba6Cervh7noGM9MQnbSD9lLHu9aQRp9Jl7vS4YPJI98IizYOzCndRcDKpv9LsJNJgXX3OVpxaUqbEiRVGcYMu7m72mdj4kNAyO86JejnaEgkFItUSg8jAU6DnkBwDHU

NOTE: The spec uses URL friendly base 64, which means + becomes -, / becomes _ and the = symbol is stripped from the end.

In part 2, we'll describe how to validate the token on the other end.

SecurityTokenEncryptionFailedException: IDX10615: Encryption failed. No support for: Algorithm

Microsoft.IdentityModel.Tokens.SecurityTokenEncryptionFailedException: IDX10615: Encryption failed. No support for: Algorithm when trying to create an instance of Microsoft.IdentityModel.Tokens.EncryptingCredentials()

I tried variations for parameter 2 (alg) but none seemed to work. I was really foxed until I found the source code online and realised that I was passing in the signing key (RSA256) rather than the encryption key (AES256) for the first parameter!

The code will attempt to use the key's crypto factory to lookup the specified algorithm and obviously that won't work when trying to specify AES on an RSA key.

Just a typo!

While I'm here, the algorithms for alg and enc need to be the same length because they will use the same key (parameter 1).