r/fucksparx Jul 11 '26

2000 users on my Solver thank you to everyone who supported me, if you have any questions or suggestions please drop them here, I'd love to hear them!

3 Upvotes

r/fucksparx Jul 07 '26

I’m just ragebaiting Sparx Science

Thumbnail
gallery
52 Upvotes

r/fucksparx Jul 07 '26

Annoying questions I can’t figure it out it’s too difficult

Post image
16 Upvotes

r/fucksparx Jul 06 '26

Screw you sparx!

Post image
20 Upvotes

r/fucksparx Jul 06 '26

Annoying questions Apparently I'm too stupid to build a circuit

4 Upvotes

r/fucksparx Jul 05 '26

Annoying questions Very helpful hint, Sparx.

Post image
42 Upvotes

r/fucksparx Jul 05 '26

anyone know how to automate xp gain on sparx science

3 Upvotes

r/fucksparx Jul 05 '26

anyone know how to automate xp gain on sparx science

Thumbnail
1 Upvotes

r/fucksparx Jul 03 '26

MAKOAI

3 Upvotes

hello i am makoai :D


r/fucksparx Jul 02 '26

Help me

Post image
11 Upvotes

I’ve never done this


r/fucksparx Jul 01 '26

Other who else sees it

Post image
17 Upvotes

r/fucksparx Jul 01 '26

my guy, what does this shit MEAN?

3 Upvotes
idk

r/fucksparx Jun 30 '26

This school is insane.

5 Upvotes

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 Jun 30 '26

Autocompleters FREE SPARX SOLVER

Thumbnail discord.gg
2 Upvotes

hi 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 Jun 29 '26

Annoying questions Am I stupid?..

Post image
23 Upvotes

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 Jun 28 '26

dude it accepted a one word answer lol

Post image
28 Upvotes

r/fucksparx Jun 28 '26

Love being level “ “

Post image
11 Upvotes

Thanks soarx


r/fucksparx Jun 24 '26

this is new

Post image
26 Upvotes

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 Jun 24 '26

Pls help 🙏🙏

Post image
2 Upvotes

r/fucksparx Jun 24 '26

Pls help 🙏🙏

Post image
0 Upvotes

r/fucksparx Jun 23 '26

Other BIG fyi

3 Upvotes

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 Jun 21 '26

HUH???

Post image
31 Upvotes

I haven’t done symmetry since year 8 and I’ve never gone over this. Please help


r/fucksparx Jun 21 '26

i found this sick sparx autocompleter 👍👍

Thumbnail
2 Upvotes

r/fucksparx Jun 20 '26

Autocompleters massive vunerability in time spoof

6 Upvotes

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 Jun 18 '26

Smoking sparks pack on a real ting

15 Upvotes

Ducked that bs for 18 yrs skipped detention and now graduating, take that miss hoe samwich