Security of JSON Web Tokens (JWT) (2024)

Security ofJSON Web Tokens (JWT)

Introduction

JSON Web Tokens (JWT) mechanisms for user authentication become more and more popular inthe applications. JWT gained particular popularity with the growing famousness ofthe microservice architecture: itentrusts the processing authentication data tothe microservices, and therefore allows toavoid various authorisation errors, increase productivity and improve application scalability.

However, improper use ofJWT can adversely affect application security. Wewill give examples ofusing JWT, analyse common errors inimplementing authentication schemes using JWT, consider the main types ofattacks onthese schemes, and give recommendations onhow toprevent them.

JWT format

This section covers the notion ofJSON Web Tokens, what they consistof, how they are exploited for user authentication and what the advantages are ofJWT compared with aclassic authentication scheme using sessions.

JWT structure

Inaccordance with RFC-7519, JSON Web Tokens (JWT) are one ofthe ways todisplay data for its transfer between two ormore parties asaJSON object.

Asarule, JWT consists ofthree parts:

  • Header
  • Payload
  • Signature

There are exceptions when JWT lacks asignature. This case will bereviewed later.

Each ofthe parts— header and payload— isanordinary JSON object that needs tobeadditionally encoded using base64url algorithm. Afterwards, the encoded parts are connected with each other and, based onthis, asignature isdetected that also becomes apart ofthe token.

Generally, atoken looks asfollows:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEzMzciLCJ1c2VybmFtZSI6ImJpem9uZSIsImlhdCI6MTU5NDIwOTYwMCwicm9sZSI6InVzZXIifQ.ZvkYYnyM929FM4NW9_hSis7_x3_9rymsDAx9yuOcc1I

You can see that the token has three parts divided bydots (picture 1).

Security of JSON Web Tokens (JWT) (1) Picture1. JSON Web Token (example from jwt.io)

Red text isthe header:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

Initially:

{"typ": "JWT","alg": "HS256"}

The purple part isthe payload:

eyJpZCI6IjEzMzciLCJ1c2VybmFtZSI6ImJpem9uZSIsImlhdCI6MTU5NDIwOTYwMCwicm9sZSI6InVzZXIifQ

Initially:

{ "id": "1337", "username": "bizone", "iat": 1594209600, "role": "user"}

The blue part isthe signature:

ZvkYYnyM929FM4NW9_hSis7_x3_9rymsDAx9yuOcc1I

Letus examine the details.

Header

Aheader isaservice part ofthe token. Ithelps the application todefine how toprocess the received token.

This part isaJSON object and has the following format:

{ "typ": "JWT", "alg": "HS256"}

Here are the following fields:

  • typ— atoken type, for example, JWT;
  • alg— the algorithm used togenerate the signature.

The value ofthe filed “typ” isoften ignored byapplications, however the standards recommend totake itinto account toprovide backward compatibility.

“alg” field isobligatory. Inthis case HS256 (HMAC-SHA256) algorithm has been used inwhich asingle secret key isused togenerate and verify the signature.

For JWT signature symmetric encryption/signature algorithms can beused, e.g. RS256 (RSA-SHA256). The standard allows using other algorithms, including HS512, RS512, ES256, ES512, none, etc.

“none” algorithm shows that the token has not been signed. Inthis token there isnopart containing asignature and itisimpossible todefine the authenticity ofsuch atoken.

Payload

Payload carries any information that helps anapplication tosomehow identify the user. Certain service fields can betransferred additionally but none ofthem are obligatory, and wewill not dwell onthem.

Inour case the payload contains the following JSON object:

{ "id": "1337", "username": "bizone", "iat": 1594209600, "role": "user"}

Inthis payload there are the following fields:

  • id— unique user identifier;
  • username— name ofthe user;
  • iat— aservice field, time oftoken generation inUnix time format;
  • role— role ofthe user. Itmay contain “admin”, “user”, “guest”, etc.

Asthe fields inthe payload part can berandom, the application can store almost any data inthis part. For example, the payload can store the user’s full name soasnot torequest this data every time from the database, and tospeed upthe application.

Signature

The signature isgenerated asfollows:

The signature and payload parts are encrypted bybase64url algorithm and afterwards united inasingle box using adot (“.”) asadivider.

Then the signature isgenerated byHMAC-SHA256 algorithm (inour example) and the signature isadded tothe initial box after adot.

Onapseudocode this algorithm looks asfollows:

signature = HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), SECRET_KEY)JWT = base64UrlEncode(header) + "." + base64UrlEncode(payload) + "." + base64UrlEncode(signature)

The application after receiving JWT from the user calculates the value ofthe signature and compares itwith the value that has been transferred inthe token. Ifthese values donot match, itmeans the token has been modified orgenerated byanuntrusted party and the application will neither accept nor trust such atoken.

The signature ofthe token inthe example can beverified using “test” secret key, for example, onjwt.io

Authentication using JWT

Authentication using JWT isquite simple.

Auser inserts his\her login data inthe application oratrusted authentication service. Incase ofsuccessful authentication, the service grants atoken tothe user containing information about this user (unique identifier, full name, role, etc.).

When further addressing the application, the token istransferred inthe user’s requests (incookies, request headers, post- orget-parameters, etc.).

After receiving the token, the application verifies its signature. Making sure the signature isvalid, the application extracts the user’s data out ofthe payload part and authorises the user.

JWT advantages

What are the advantages ofusing JWT compared with aclassic authentication scheme using sessions?

First, token use makes itpossible not tostore information about all the issued tokens. When auser addresses the application, he\she transfers their token. The application verifies the signature and extracts necessary fields out ofthe payload.

Second, the application does not have toissue and verify tokens byitself, asaseparate authentication service isoften used for these purposes.

Third, incase ofaseparate authentication service itispossible toorganise asingle-entry point tovarious services with the same login data. After going through the authentication procedure once, the user with the token will beable toget access tothose resources that trust this authentication service.

Finally, the application can store almost any data inthe payload part that can substantially increase the application efficiency, ifits architecture iscorrect.

The factors above resulted inJWT authentication scheme being widely used invarious corporate applications. Such ascheme isespecially popular inapplications using microservice architecture. With this approach, each service gets necessary user data directly from the token and does not waste time onacquiring this information from the database.

Attacks onJWT

This section will review the main attacks onJWT and recommendations will begiven onhow toprevent such attacks.

Token capture

User’s token capture may lead toseveral negative consequences.

First, asJWT istransferred openly, itisenough toapply base64UrlDecode function tothe payload part toreceive the initial data stored there. Obviously, acriminal having captured the token, will beable toextract the user’s data stored inthe token.

Inorder toavoid such athreat, the best practice isto:

  • Use asecure connection during token transfer;
  • Never transfer user’s sensitive data intokens, limiting oneself toimpersonal identifiers.

Second, the criminal having captured atoken will beable toreuse this token and access the application onbehalf ofthe user whose JWT has been captured.

The recommendations here will beasfollows:

  • Like inthe first case, touse secure connection during token transfer;
  • Tolimit the JWT lifetime and use refresh tokens.

Refresh tokens

Inmodern authentication schemes based onJWT, the user receives two tokens after authentication:

  • access token— JWT based onwhich the application identifies and authorises the user;
  • refresh token— arandom token torenew access token.

Access token inthis case has alimited lifespan (e.g., 1minute). Refresh token has alonger lifespan (day, week, month) but itisone-off and serves only torenew the user’s access token.

The authentication scheme inthis case looks asfollows:

  • the user goes through identification and receives access token and refresh token from the server;
  • when addressing the resource, the user transfers his access token inthe request, based onwhich the server identifies and authorises the client;
  • ifthe user’s access token expires, the user transfers his refresh token inthe request and gets new access token and refresh token from the server;
  • ifthe user’s refresh token expires too, the user must gothrough the identification process again.

Mining the key for signature symmetric algorithm

Incase ofsymmetric algorithm for signing JWT (HS256, HS512, etc.) acriminal can try tomatch the key phrase.

Having doneso, the criminal can manipulate the JWT tokens like the application does and therefore can get access tothe system onbehalf ofany registered user.

Inour example (see part 1ofthe article) a“test” box was used asthe key phrase tosign JWT. This key phrase issimple and short and can befound inall the main dictionaries for passwords mining. Acriminal can easily match the key phrase using John the Ripper or hashcat.

Inthis case the recommendations are asfollows:

  • touse and store the key phrases asconfidential information, having considerable length, consisting ofupper- and lower-case Latin letters, numbers and special symbols;
  • toprovide periodic change ofthe key phrase. This will beless convenient for the users, asthey will have togothrough identification again, but will help toavoid compromising the key information.

Using “none” algorithm

Aswehave already mentioned inthe first part ofthe article, use of“none” algorithm inJWT header shows that the token has not been signed. Such atoken lacks apart with the signature, and itisimpossible toverify authenticity ofthis token.

Letus review asimilar attack inour example. Our non-coded token looks asfollows:

header:{ "typ": "JWT", "alg": "HS256"}payload:{ "id": "1337", "username": "bizone", "iat": 1594209600, "role": "user"}signature:ZvkYYnyM929FM4NW9_hSis7_x3_9rymsDAx9yuOcc1I

Suppose, wewant the application toregardus asanadministrator. Weneed, therefore, tochange the field “role” inpayload for “admin”. But ifweintroduce these changes inthe token, its signature will become invalid and the application will not accept such JWT.

Tobypass this security mechanism, wecan try tochange the field “alg” inthe token header for “none”. Our token will look asfollows:

header:{ "typ": "JWT", "alg": "none"}payload:{ "id": "1337", "username": "bizone", "iat": 1594209600, "role": "admin"}

Asweare using “none” algorithm, there isnosignature inthis case. Our encoded JWT will look asfollows:

eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJpZCI6IjEzMzciLCJ1c2VybmFtZSI6ImJpem9uZSIsImlhdCI6MTU5NDIwOTYwMCwicm9sZSI6ImFkbWluIn0

This token will besent tothe server. Avulnerable application, after checking the JWT header and detecting “alg”: “none”, will accept this token without any verification asifitwere legitimate, and asaresult wewill gain administrator rights.

Asmethods ofprecaution against such attacks:

  • itisnecessary tokeep awhite list ofauthorised algorithms onthe application side and todismiss all tokens having asignature algorithm that isdifferent from the one authorised onthe server;
  • itisrecommended towork with one algorithm only, e.g., HS256or RS256.

Changing the signature algorithm

Incase ofusing asymmetric algorithms for token signature, the signature shall beperformed using aprivate service key and signature verification— using apublic service key.

Some libraries used for working with JWT contain logical errors— when receiving atoken signed with asymmetric algorithm (e.g., HS256) apublic service key will beused asakey phrase for verifying the signature. Asapublic service key isnot secret data, acriminal can easily get itand use for signing own tokens.

Toreview this example, wewill require anew JWT:

header:{ "alg": "RS256", "typ": "JWT"}payload:{ "id": "1337", "username": "bizone", "iat": 1594209600, "role": "user"}signature:YLOVSKef-paSnnM8P2JLaU2FiS8TbhYqjewLmgRJfCj1Q6rVehAHQ-lABnKoRjlEmHZX-rufHEocDxGUYiGMjMexUQ3zt-WqZITvozJ4pkvbV-mJ1nKj64NmqaR9ZkBWtmF-PHJX50eYjgo9rzLKbVOKYOUa5rDkJPHP3U0aaBXFP39zsGdOTuELv436WXypIZBeRq2yA_mDH13TvzegWCK5sjD4Gh177bCq57tBYjhGIQrDypVe4cWBPlvwFlmG8tdpWGu0uFp0GcbTAfLUlbTSuGROj88BY0XeUs0iqmGlEICES3uqNx7vEmdT5k_AmL436SLedE0VHcyxve5ypQ

When encoded, itwill look asfollows:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEzMzciLCJ1c2VybmFtZSI6ImJpem9uZSIsImlhdCI6MTU5NDIwOTYwMCwicm9sZSI6InVzZXIifQ.YLOVSKef-paSnnM8P2JLaU2FiS8TbhYqjewLmgRJfCj1Q6rVehAHQ-lABnKoRjlEmHZX-rufHEocDxGUYiGMjMexUQ3zt-WqZITvozJ4pkvbV-mJ1nKj64NmqaR9ZkBWtmF-PHJX50eYjgo9rzLKbVOKYOUa5rDkJPHP3U0aaBXFP39zsGdOTuELv436WXypIZBeRq2yA_mDH13TvzegWCK5sjD4Gh177bCq57tBYjhGIQrDypVe4cWBPlvwFlmG8tdpWGu0uFp0GcbTAfLUlbTSuGROj88BY0XeUs0iqmGlEICES3uqNx7vEmdT5k_AmL436SLedE0VHcyxve5ypQ

Asinthis case weuse RS256 algorithm for signature, wewill require both public and private keys.

Public key:

-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSvvkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHcaT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIytvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWbV6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9MwIDAQAB-----END PUBLIC KEY-----

Private key:

-----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCAQEAnzyis1ZjfNB0bBgKFMSvvkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHcaT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIytvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWbV6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9MwIDAQABAoIBACiARq2wkltjtcjskFvZ7w1JAORHbEufEO1Eu27zOIlqbgyAcAl7q+/1bip4Z/x1IVES84/yTaM8p0goamMhvgry/mS8vNi1BN2SAZEnb/7xSxbflb70bX9RHLJqKnp5GZe2jexw+wyXlwaM+bclUCrh9e1ltH7IvUrRrQnFJfh+is1fRon9Co9Li0GwoN0x0byrrngU8Ak3Y6D9D8GjQA4Elm94ST3izJv8iCOLSDBmzsPsXfcCUZfmTfZ5DbUDMbMxRnSo3nQeoKGC0Lj9FkWcfmLcpGlSXTO+Ww1L7EGq+PT3NtRae1FZPwjddQ1/4V905kyQFLamAA5YlSpE2wkCgYEAy1OPLQcZt4NQnQzPz2SBJqQN2P5u3vXl+zNVKP8w4eBv0vWuJJF+hkGNnSxXQrTkvDOIUddSKOzHHgSg4nY6K02ecyT0PPm/UZvtRpWrnBjcEVtHEJNpbU9pLD5iZ0J9sbzPU/LxPmuAP2Bs8JmTn6aFRspFrP7W0s1Nmk2jsm0CgYEAyH0X+jpoqxj4efZfkUrg5GbSEhf+dZglf0tTOA5bVg8IYwtmNk/pniLG/zI7c+GlTc9BBwfMr59EzBq/eFMI7+LgXaVUsM/sS4Ry+yeK6SJx/otIMWtDfqxsLD8CPMCRvecC2Pip4uSgrl0MOebl9XKp57GoaUWRWRHqwV4Y6h8CgYAZhI4mh4qZtnhKjY4TKDjxQYufXSdLAi9v3FxmvchDwOgn4L+PRVdMwDNms2bsL0m5uPn104EzM6w1vzz1zwKz5pTpPI0OjgWN13Tq8+PKvm/4Ga2MjgOgPWQkslulO/oMcXbPwWC3hcRdr9tcQtn9Imf9n2spL/6EDFId+Hp/7QKBgAqlWdiXsWckdE1Fn91/NGHsc8syKvjjk1onDcw0NvVi5vcba9oGdElJX3e9mxqUKMrw7msJJv1MX8LWyMQC5L6YNYHDfbPF1q5L4i8j8mRex97UVokJQRRA452V2vCO6S5ETgpnad36de3MUxHgCOX3qL382Qx9/THVmbma3YfRAoGAUxL/Eu5yvMK8SAt/dJK6FedngcM3JEFNplmtLYVLWhkIlNRGDwkg3I5Ky18Ae9n7dHVueyslrb6weq7dTkYDi3iOYRW8HRkIQh06wEdbxt0shTzAJvvCQfrBjg/3747WSsf/zBTcHihTRBdAv6OmdhV4/dD5YBfLAkLrd+mX7iE=-----END RSA PRIVATE KEY-----

For tests wewill utilise jwt.io (picture 2).

Security of JSON Web Tokens (JWT) (2) Picture2. Initial JWT

Asinprevious example, wemodify the token:

header:{ "typ": "JWT", "alg": "HS256"}payload:{ "id": "1337", "username": "bizone", "iat": 1594209600, "role": "admin"}

When encoded, the header and payload look asfollows:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEzMzciLCJ1c2VybmFtZSI6ImJpem9uZSIsImlhdCI6MTU5NDIwOTYwMCwicm9sZSI6ImFkbWluIn0

Weonly have toread the signature using apublic service key.

Tobegin, letus transfer the key tohex-representation (picture 3).

Security of JSON Web Tokens (JWT) (3) Picture3. hex-representation ofthe key

Then wegenerate asignature using openssl (picture 4).

Security of JSON Web Tokens (JWT) (4) Picture4. Generating signature for JWT

Weadd the value E1R1nWNsO-H7h5WoYCBnm6c1zZy-0hu2VwpWGMVPK2g toanalready existing box, and our token looks asfollows:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEzMzciLCJ1c2VybmFtZSI6ImJpem9uZSIsImlhdCI6MTU5NDIwOTYwMCwicm9sZSI6ImFkbWluIn0.E1R1nWNsO-H7h5WoYCBnm6c1zZy-0hu2VwpWGMVPK2g

Weinsert our public key into “secret” onjwt.io, and, aswecan see, JWT goes through verification successfully (remember tocheck the box “secret base64encoded”!) (picture 5)

Security of JSON Web Tokens (JWT) (5) Picture5. Successful JWT signature verification

Toprevent this attack, werecommend:

  • towork with one algorithm only, e.g. HS256or RS256;
  • toselect well-known and reliable libraries for working with JWT that are less likely tocontain logical errors intoken verification procedures.

Key identifiers manipulation

RFC-7515 standard describes “kid” header parameter (KeyID, key identifier). This standard also states that the format ofthis field isnot strictly defined, sothe developers can interpret ittotheir convenience, and this often leads tovarious mistakes.

Let’s take the following JWT header asanexample:

{ "alg" : "HS256", "typ" : "JWT", "kid" : "1337"}

Wesuppose that for token verification akey with 1337 identifier from the database will beused here. Incase ofencoding errors this field can bevulnerable toSQL injections:

{ "alg" : "HS256", "typ" : "JWT", "kid" : "1337' union select 'SECRET_KEY' -- 1"}

Inthis case “SECRET_KEY” box will beused asthe key phrase instead ofapotential key from the database toverify the key signature.

Inthe next example wesuppose that akey from “keys/service3.key” file will beused toverify the token.

{ "alg" : "HS256", "typ" : "JWT", "kid" : "keys/service3.key" }

There isapossibility that incase aparameter isnot validated, acriminal can perform Path Traversal (Directory Traversal) attack, and instead ofapotential route tothe file hecan transfer aroute toapublic file tothe “kid” field:

{ "alg" : "HS256", "typ" : "JWT", "kid" : "../../../images/public/cat.png" }

The criminal can access “cat.png” file and sign JWT using the contents ofthis file, asthis file ispublic (e.g., published onone ofthe service pages). The service, having received aroute in“kid” field to“cat.png” file uses its contents asakey file toverify the token signature (that will besuccessful asthe criminal has taken care ofthat beforehand).

Arecommendation toprevent such attacks issimple:

  • itisnecessary toalways validate and sanitise the data received from the user even ifithas been received asJWT.

Conclusion

JSON Web Tokens are very popular and are highly regarded for their convenience. Ifused correctly, JWT can prevent errors ofinadequate authorisation, allow simple and easy distribution ofinformation flows between the servers, organise asingle entry-point for various services with the same login data and even increase the service efficiency.

However, ifmisused, this technology may put entire systems atrisk, which may even result inanall-out compromise ofthe login credentials for all system users.

Toconclude, inorder tomake the JWT use safe and secure, itisrecommendedto:

  • Use secure connection when transferring tokens;
  • Never transfer users’ sensitive data inthe tokens;
  • Limit JWT lifespan and use “refresh tokens” mechanism;
  • Use long key phrases;
  • Keep awhite list ofauthorised signature algorithms onthe application side;
  • Work, ideally, with one signature algorithm only;
  • Choose well-known and reliable libraries for JWT operation;
  • Always validate and sanitise the data received from users.
Security of JSON Web Tokens (JWT) (2024)
Top Articles
How to save money, the fashion way: 18 genius tips from experts and style savants
How Does Airbnb Work as a Host? (2024) 5 Critical Tips For Hosts
Global Foods Trading GmbH, Biebesheim a. Rhein
Faint Citrine Lost Ark
Voordelige mode in topkwaliteit shoppen
What to Serve with Lasagna (80+ side dishes and wine pairings)
Linkvertise Bypass 2023
Needle Nose Peterbilt For Sale Craigslist
Roblox Character Added
South Ms Farm Trader
DIN 41612 - FCI - PDF Catalogs | Technical Documentation
4Chan Louisville
Mlb Ballpark Pal
Miss America Voy Forum
Otterbrook Goldens
Crossword Nexus Solver
Rachel Griffin Bikini
Dtab Customs
Saatva Memory Foam Hybrid mattress review 2024
Band Of Loyalty 5E
Richland Ecampus
Vandymania Com Forums
Rugged Gentleman Barber Shop Martinsburg Wv
Persona 5 Royal Fusion Calculator (Fusion list with guide)
Boscov's Bus Trips
Doublelist Paducah Ky
Marion City Wide Garage Sale 2023
Hampton University Ministers Conference Registration
Hannaford Weekly Flyer Manchester Nh
Booknet.com Contract Marriage 2
Craigslist Hunting Land For Lease In Ga
Saxies Lake Worth
Studentvue Calexico
O'reilly's In Monroe Georgia
Kleinerer: in Sinntal | markt.de
Dtlr On 87Th Cottage Grove
The Hoplite Revolution and the Rise of the Polis
Desirulez.tv
Selfservice Bright Lending
Cruise Ships Archives
Is Arnold Swansinger Married
Rochester Ny Missed Connections
Housing Intranet Unt
Orion Nebula: Facts about Earth’s nearest stellar nursery
Skip The Games Grand Rapids Mi
Mid America Irish Dance Voy
Walmart Car Service Near Me
Victoria Vesce Playboy
Wpne Tv Schedule
When Is The First Cold Front In Florida 2022
Worlds Hardest Game Tyrone
Duffield Regional Jail Mugshots 2023
Latest Posts
Article information

Author: Gov. Deandrea McKenzie

Last Updated:

Views: 6234

Rating: 4.6 / 5 (66 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Gov. Deandrea McKenzie

Birthday: 2001-01-17

Address: Suite 769 2454 Marsha Coves, Debbieton, MS 95002

Phone: +813077629322

Job: Real-Estate Executive

Hobby: Archery, Metal detecting, Kitesurfing, Genealogy, Kitesurfing, Calligraphy, Roller skating

Introduction: My name is Gov. Deandrea McKenzie, I am a spotless, clean, glamorous, sparkling, adventurous, nice, brainy person who loves writing and wants to share my knowledge and understanding with you.