JSON Web Tokens (JWT) are quickly becoming a great way of authorising users to perform certain actions but a lot of things can go wrong as well in the implementation. We are going to build a JWT lab that does not check if the signature is valid but not before we give you an overview of what a JWT token looks like.
THE SERVER GETS ERASED EVERY 24 HOURS
add the following code to your file:
<?php
include('instructions.php');
function generate_jwt($headers, $payload, $secret = 'secret', $encoding = 'SHA256') {
$headers_encoded = base64url_encode(json_encode($headers));
$payload_encoded = base64url_encode(json_encode($payload));
$signature = hash_hmac('SHA256', "$headers_encoded.$payload_encoded", $secret, true);
$signature_encoded = base64url_encode($signature);
$jwt = "$headers_encoded.$payload_encoded.$signature_encoded";
return $jwt;
}
function base64url_encode($str) {
return rtrim(strtr(base64_encode($str), '+/', '-_'), '=');
}
function is_jwt_valid($jwt, $secret = 'secret') {
// split the jwt
$tokenParts = explode('.', $jwt);
$header = base64_decode($tokenParts[0]);
$payload = base64_decode($tokenParts[1]);
$signature_provided = $tokenParts[2];
// check the expiration time - note this will cause an error if there is no 'exp' claim in the jwt
$expiration = json_decode($payload)->exp;
$is_token_expired = ($expiration - time()) < 0;
// build a signature based on the header and payload using the secret
$base64_url_header = base64url_encode($header);
$base64_url_payload = base64url_encode($payload);
$signature = hash_hmac('SHA256', $base64_url_header . "." . $base64_url_payload, $secret, true);
$base64_url_signature = base64url_encode($signature);
// verify it matches the signature provided in the jwt
$is_signature_valid = ($base64_url_signature === $signature_provided);
if ($is_token_expired || !$is_signature_valid) {
return FALSE;
} else {
return TRUE;
}
}
function getBody($jwt,$secret = 'secret'){
// split the jwt
$tokenParts = explode('.', $jwt);
$header = base64_decode($tokenParts[0]);
$payload = base64_decode($tokenParts[1]);
$signature_provided = $tokenParts[2];
is_jwt_valid($jwt,$secret);
return $payload;
}
function getFlag($jwt){
$body = json_decode(getBody($jwt));
if($body->canViewFlag=="True"){
echo "Good job!! The flag is flag{1_L0v#3_Ch33s3!}";
}else{
echo "You can not read the flag";
}
}
$headers = array('alg'=>'HS256','typ'=>'JWT');
$payload = array('canViewFlag' => "False", 'exp'=>(time() + 60));
$jwt = generate_jwt($headers, $payload);
header("Authorization: Bearer $jwt");
echo "The server gave you the following JWT: <br> $jwt";
echo "<hr>";
?>
<form>
<label for="JWT">Your JWT:</label><br>
<input type="text" id="JWT" name="JWT"><br>
<input type="submit">
</form>
<?php
if(isset($_GET['JWT'])){
echo getFlag($_GET['JWT']);
}
?>