Let’s take a look at we can tell the world about our friends new mastery: Bow Hunting.

First: Find all your friends.

Easy enough, the LinkedIn API allows you to query all of them. Adjust the count to your total amount of friends, and then sit back an relax.

https://www.linkedin.com/connected/api/v2/contacts?start=0&count=10

Second: Get your CSRF token

Don’t worry, this one is easy. We’ll even use the LinkedIn client-side API to parse our cookies. This token is required to post to the API.

LI.readCookie(‘JSESSIONID’);

Third: Find the request payload for an endorsement, for Bow Hunting.

Pop open the network tab of the dev tools of choice, and watch what happens when you endorse a friend. You’ll see this form data:

{

‘endorsedItemName-0’:’Bowhunting’,

‘endorsedItemType-0’:’skill’,

‘endorsedItemId-0’:’35690',

‘recipientType-0’:’member’,

‘recipientId-0’: 12343242,

‘endorse’:’Endorse’,

‘endorsementCount’:’1'

}

Also check out the request headers for these inclusions:

‘X-IsAJAXForm’: 1,

‘X-LinkedIn-traceDataContext’: ‘X-LI-ORIGIN-UUID=SOMELONGASSNUMBER==’

Want to endorse your favorite friends for something else? Look up the endorsedItemId-0 here: https://www.linkedin.com/ta/skill?query=barking

We have access to all member’s of our friends list, and the API to endorse them. Now all we need is Jquery

Spoiler alert, you might not need Jquery. But if the developers at LinkedIn are giving you access to it in the global namespace, why not?

Tying it all together…. (don’t actually do this.)

Go to a LinkedIn page. Any page. Open the Javascript console. Enter this:

(function(){

'use_strict';

const count = 200; //How popular are you?

const dontEndorseIfTheyWorkHere = "YOUR COMPANY";

const csrf = LI.readCookie('JSESSIONID').replace(/"/gi,'');

let userIDs = [];

let step = 0;

{complete: data => parse(data)}

); $.ajax(` https://www.linkedin.com/connected/api/v2/contacts?start=0&count=${count}` {complete: data => parse(data)}); function parse(data) {

userIDs = data.responseJSON.values.filter(shouldWeEndorse);

endorseForBowhunting();

} function shouldWeEndorse(user) {

return user.company.name !== dontEndorseIfTheyWorkHere;

}



var URL = ` function endorseForBowhunting() {var URL = ` https://www.linkedin.com/profile/endorse?_ed=0_crpQwclsqh40t8SP-6xKj6Xa8ECCs2_PCAxX_TMp93v2_X1nEvjx2hy1Tjmyz49eU_nQPZuodD3JQTX0n0nv3Q6XGJLmk-V8LmDIS6J5BzQ&csrfToken=${csrf}` var testData = {

'endorsedItemName-0':'Bowhunting',

'endorsedItemType-0':'skill',

'endorsedItemId-0':'35690',

'recipientType-0':'member',

'recipientId-0': userIDs[step].memberId,

'endorse':'Endorse',

'endorsementCount':'1'

}; $.ajax(URL, {

method: 'POST',

headers: {

'X-IsAJAXForm': 1,

'X-LinkedIn-traceDataContext': 'X-LI-ORIGIN-UUID=SOMELONGASSNUMBER=='

},

data: testData,

complete: res => {

step++;

if(step < userIDs.length) {

endorseForBowhunting();

}

}

});

}



}());

The code above will:

Get a list of all your connections.

Filter out people if they work at the same place you do, because it would embarrassing if you endorsed the director’s director.

Send a fancy new endorsement to literally everyone else using AJAX.

But why?

I could tell you that client-side web security is an important part of modern web development, but you already know to never trust the client. No one is going to convince people to open themselves up to malicious code by pasting arbitrary Javascript in their console… well not unless you ask Facebook.

So you’re telling me this giant blob of JS wont give me free coins in Farmville?

Sometimes it’s fun just to poke around websites and see how their client APIs are structured. It’s always a little surprising when you see a large portion of the code base exposed in the global namespace, because developing without a proper build system and modules is a living hell. Those things typically fix this problem by concealing the most important elements of your application through scoping. It’s a lot harder to prevent your REST endpoints from being hit by the client in ways that you didn’t anticipate though. You can prevent CSRF attacks (LinkedIn is) with tokens, but your users are still able to use the dev tools.