Introduction
I’ll be honest with you:
I didn’t wake up one morning thinking “Let me reverse-engineer TikTok today.”
It started with something much simpler:
“I just want to upload videos to TikTok programmatically…
why is this so damn hard?”
No matter what I tried — simple requests, faked headers, even stolen cookies — TikTok kept slamming the door in my face.
But every failure taught me something.
Every blocked request revealed the next security layer.
So I dug in.
I became the “hacker” TikTok didn’t want.
And in this post, I’ll take you through the exact journey — from the most naive HTTP request… all the way to running TikTok’s own obfuscated JavaScript in a Node VM to generate browser signatures.
All code here comes from my real TikTok automation stack (based on my repo:
github.com/mrzaizai2k/auto_tiktok).
Table of Contents
- Raw Request — My First Dumb Attempt
- User-Agent — “Fine, I’ll Pretend to Be Chrome”
- Cookies — The Real Passport
- Browser Signatures — When TikTok Got Serious
- Summary
- Final Thoughts
- Resources
Raw Request
đź§ What I Tried
The first time I tried calling TikTok’s API, I thought it would be as easy as:
import requests
print(requests.get("https://www.tiktok.com/api/whatever").text)
TikTok looked at me like:
“Bro, who even are you?”
No headers.
No cookies.
No browser identity.
Instant block.
To understand why, I built a minimal FastAPI to simulate what TikTok sees when a bot sends a naked request:
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
@app.get("/api/data")
def get_data(request: Request):
# no checks, no identity
return {"data": "public info"}
This is how the early internet worked.
And this is why it died.
User-Agent
“I’ll wear Chrome’s clothes… surely that will work.”
I added:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
My FastAPI simulation:
@app.get("/api/data")
def get_data(request: Request):
ua = request.headers.get("User-Agent")
if not ua:
raise HTTPException(403, "Missing UA")
return {"data": "public info"}
And my crawler:
import requests
requests.get(url, headers={"User-Agent": "Mozilla/5.0"})
This worked…
…for exactly 5 minutes.
Because any idiot can fake a UA.
Including me.
So TikTok uses the next level.
Cookies
“Fine, TikTok, you want identity? Here’s my passport.”
Cookies are small pieces of data the server sets in your browser.
When I login to TikTok on Chrome, the browser stores cookies like:
sessionidmsTokentt-target-idccsrf_session_id
These aren’t random strings — they’re TikTok’s way of saying:
“This browser is logged in. We know this guy.”
To get these cookies, I use this extension (the best one I’ve found):
👉 J2Team Cookies (Chrome)
It exports cookies into a neat JSON file — perfect for automation.
Then in Python:
cookies = load_cookies_from_file("cookies/tiktok.json")
session = requests.Session()
session.cookies.set("sessionid", session_id, domain=".tiktok.com")
session.cookies.set("tt-target-idc", dc_id, domain=".tiktok.com")
Now TikTok was finally willing to talk to me.
For a while.
Because cookies can still be:
- stolen
- copied
- reused
- shared
TikTok needed something harder.
Browser Signatures
“Prove you’re a real browser or get lost.”
This is where TikTok gets nasty.
Even with:
- Valid cookies
- Valid User-Agent
TikTok still blocks you unless you generate:
X-Bogus_signature-
msTokenvalidation - device/environment fingerprints
- obfuscated JS crypto outputs
TikTok literally sends JavaScript that only a real browser can execute.
So to bypass it…
I used their own JavaScript.
👉 Running TikTok’s JS in a Node VM
This is my real browser.js (the one doing the magic):
// Browser.js
const Signer = require("./index");
var url = process.argv[2];
var userAgent = process.argv[3];
(async function main() {
try {
const signer = new Signer(url, userAgent);
await signer.init();
const sign = await signer.sign(url);
const navigator = await signer.navigator();
let output = JSON.stringify({
status: "ok",
data: {
...sign,
navigator: navigator,
},
});
console.log(output);
await signer.close();
} catch (err) {
console.error(err);
}
})();
And this is how my Python script calls it:
def subprocess_jsvmp(js, user_agent, url):
proc = subprocess.Popen(['node', js, url, user_agent], stdout=subprocess.PIPE)
return proc.stdout.read().decode('utf-8')
Every API request needs this signature.
Without it — TikTok spits on you.
With it — you suddenly become “a real browser.”
This is exactly how I upload videos automatically:
signatures = subprocess_jsvmp(js_path, user_agent, sig_url)
tt = json.loads(signatures)["data"]
headers = {
"User-Agent": user_agent,
"X-Bogus": tt["x-bogus"],
"_signature": tt["signature"],
}
Now TikTok believes me.
And lets me upload videos through automation.
Summary
| Layer | What I Did | Why It Failed |
|---|---|---|
| Raw request | Called API directly | “Who are you?” |
| User-Agent | Pretended to be Chrome | Too easy to fake |
| Cookies | Exported real TikTok cookies | Reusable → insecure |
| Browser Signatures | Ran TikTok’s own JS | Finally works |
Final Thoughts
There are even more authentication methods out there:
- OAuth
- JWT tokens
- PKCE
- Rotating keys
- Device-bound tokens
If you want, I can continue this series:
👉 Hit follow + drop a comment if you want the next chapter.
Resources
- My TikTok uploader code: auto_tiktok → tiktok.py
Top comments (1)
This post honestly feels like a small masterclass in modern web security. I love how you walk through the evolution rather than explaining each technique in isolation. Seeing the server code vs crawler code side-by-side makes everything click — especially how each layer becomes useless once hackers figure out a workaround.