I Tried Hacking LinkedIn’s Group Comment Delete Feature

There is a type of bug that may not have an official name, but I refer to as a “DOM Manipulation Exploit”.

DOM stands for Document Object Model. It’s what you’re looking at when you right click an element in a web page and click Inspect Element.

What many people may not realize is that common browsers, such as Chrome, offer you a way to change the DOM contents right there in the page.

This is fun for when you notice data being put in the webpage code, that would appear to be picked back up by the server later. That’s a valid thing for webservers to do, because then the webserver doesn’t have to “remember” every single thing.

But, it introduces an assumption: The assumption that the data being picked back up by the webserver is still correct.

Sometimes, this assumption leads to some interesting exploits.

This tactic is similar to what I did in a previous post, where I bypassed a fairly simple CAPTCHA.

Here’s what I tried:


I’d created a post in a common QA group, and asked some people to throw some test comments up there.

I noticed that in groups, I can delete my comments. For other peoples’ comments, that option isn’t available to me.

Here’s what comments look like, with the Delete link visible for me:

linkedin delete comment function
A challenger appears!

So I started digging around in the code to see what there was. I’ll walk you through what I did.

First let’s look at the code for that Delete link by doing a Right Click followed by Inspect Element (this is in Chrome by the way):

<a class="act" role="button" tabindex="0" data-li-disc-act="remove" data-li-disc-url="/groupItem?deleteComment=&gid=95831&type=member&item=6040123810408120321&commentID=6040127992653504512&ajax=true&csrfToken=ajax:3545935598622379644" data-li-disc-undo-url="&csrfToken=ajax:3545935598622379644">Delete</a>

That’s a gobba goo, but let’s see if there’s any info we can glean out of the next person’s comment–let’s look at the Report Spam link’s code as a guide:

<a class="act" role="button" tabindex="0" data-li-disc-act="flagInappropriate" data-li-disc-url="/groupItem?flag=&gid=95831&type=member&item=6040123810408120321&commentID=6040195730906370048&flagReason=inappropriate&ajax=true&csrfToken=ajax:3545935598622379644" data-li-disc-undo-url="/groupItem?unflag=&gid=95831&type=member&item=6040123810408120321&ajax=true&commentID=6040195730906370048&csrfToken=ajax:3545935598622379644">Report spam</a>

Ok, so there are some similarities here between the two links, so I want to see if I can change the Report Spam link into a Delete link, with the effect of being able to delete someone else’s comment as if it were actually one of my comments. Basically, I’m going to superimpose data from my Delete link, into the Report Spam link.

Remember I said there’s a bunch of information that gets pushed out so that the server doesn’t have to remember? Much of the payload here is made up of URLs that provide specific functions. The data-li-disc-act, data-li-disc-url and data-li-disc-undo-url fields in particular are what I’m going to mess with.

So I start by comparing some things. data-li-disc-act is easy enough–mine’s a remove and the other person’s is a flagInappropriate. Simple enough to change–just double click that field in the DOM inspector (right-click-inspect-element) and type in a new value:

<a class="act" role="button" tabindex="0" data-li-disc-act="remove" data-li-disc-url="/groupItem?flag=&gid=95831&type=member&item=6040123810408120321&commentID=6040195730906370048&flagReason=inappropriate&ajax=true&csrfToken=ajax:3545935598622379644" data-li-disc-undo-url="/groupItem?unflag=&gid=95831&type=member&item=6040123810408120321&ajax=true&commentID=6040195730906370048&csrfToken=ajax:3545935598622379644">Report spam</a>

Next, compare data-li-disc-url for both comments. This contains a variety of subfields, and it’s a query url, like ones you see that end with “&this=4&that=23&the_other=42”. That’s what the “&” turns into.

Here’s a breakdown of both, where I replaced each “&” token with a newline:



Of these, the only differences are the deleteComment vs. flag in the first subfield, and the flagReason subfield being present in the second one whereas it’s not in the first. The commentID is different too, but probably need to leave that alone, since it’s tied to that particular comment. I wouldn’t want to replace that and end up actually deleting my comment.

So we can make the appropriate replacements in the 2nd comment–change flagComment to deleteComment, and remove the flagReason parameter entirely:

<a class="act" role="button" tabindex="0" data-li-disc-act="remove" data-li-disc-url="/groupItem?deleteComment=&gid=95831&type=member&item=6040123810408120321&commentID=6040195730906370048&ajax=true&csrfToken=ajax:3545935598622379644" data-li-disc-undo-url="/groupItem?unflag=&gid=95831&type=member&item=6040123810408120321&ajax=true&commentID=6040195730906370048&csrfToken=ajax:3545935598622379644">Report spam</a>

All right, looking good so far. The next field is the data-li-disc-undo-url. There’s not a lot here, but here’s a breakdown between mine and the other’s:



Theirs has much more stuff, but for this to be a delete, it just has to look like mine.

The csrfToken contents are the same, so next we just pare down the 2nd comment’s data-li-disc-undo-url to have just that token:

<a class="act" role="button" tabindex="0" data-li-disc-act="remove" data-li-disc-url="/groupItem?deleteComment=&gid=95831&type=member&item=6040123810408120321&commentID=6040195730906370048&ajax=true&csrfToken=ajax:3545935598622379644" data-li-disc-undo-url="&csrfToken=ajax:3545935598622379644">Report spam</a>

Finally, just for grins and giggles, let’s change the text to say “Delete” instead of “Report spam”:

<a class="act" role="button" tabindex="0" data-li-disc-act="remove" data-li-disc-url="/groupItem?deleteComment=&gid=95831&type=member&item=6040123810408120321&commentID=6040195730906370048&ajax=true&csrfToken=ajax:3545935598622379644" data-li-disc-undo-url="&csrfToken=ajax:3545935598622379644">Delete</a>


Now to try it out. With that code in place in the DOM for that 2nd comment, here’s what you’ll see on the screen:

I'm sorry, my dear, but you know too much.
I’m sorry, my dear, but you know too much.

And if you click it, guess what happens!!:

Yes! YES!! Success!! The power!!!!11one KNEEL BEFORE ZOD
Yes! YES!! Success!! The power!!!!11one KNEEL BEFORE ZOD

Except… when we refresh the screen, now guess what happens:

oh well i tried

Sad Trombone–Womp Womp Womp Woooooomp

Oh well. I tried. Kudos to LinkedIn for preventing this type of attack here.

Actually, I really hoped it would have worked this time, while I was writing this post, and that maybe I did something different this time that I didn’t do last time.

No such luck. But it was fun!

Anyway, again, as in the CAPTCHA post mentioned further up, this is a legitimate way to find bugs. You have the ability to change things about the DOM right there in your browser (and if you’re looking for a fun exercise, try doing it using Javascript–great for automating DOM Manipulation tests) and get sites to do Weird Things(tm) that the designers likely didn’t expect.

I hope this post was as enjoyable to read as it was for me to write 🙂

Thanks for reading–Fritz

Hey, if you liked this post, consider following this blog by clicking the button along the right. You’ll get an email when a new post is hot off the Press. Thanks for coming by.


One thought on “I Tried Hacking LinkedIn’s Group Comment Delete Feature

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s