Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@ updates:
- npm
- dependencies

- package-ecosystem: npm
directory: /apps/am-i-being-recorded
schedule:
interval: daily
cooldown:
default-days: 7
labels:
- npm
- dependencies

- package-ecosystem: npm
directory: /apps/secure-semgrep
schedule:
interval: daily
cooldown:
default-days: 7
labels:
- npm
- dependencies

- package-ecosystem: github-actions
directory: /
schedule:
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ pnpx am-i-hacked . # or: npx am-i-hacked .
```

[![CI](https://github.com/IsaacBell/secure-devtools/actions/workflows/ci.yml/badge.svg)](https://github.com/IsaacBell/secure-devtools/actions/workflows/ci.yml)
[![npm](https://img.shields.io/npm/v/am-i-hacked)](https://www.npmjs.com/package/am-i-hacked)
[![npm am-i-hacked](https://img.shields.io/npm/v/am-i-hacked?label=am-i-hacked)](https://www.npmjs.com/package/am-i-hacked)
[![npm am-i-being-recorded](https://img.shields.io/npm/v/am-i-being-recorded?label=am-i-being-recorded)](https://www.npmjs.com/package/am-i-being-recorded)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

**Status:** actively maintained. `am-i-hacked` 2.0.0 is the current release, renamed from `am-i-compromised`. macOS and Linux.
**Status:** actively maintained. `am-i-hacked` 2.0.1 and `am-i-being-recorded` 1.0.0 are the current releases. macOS and Linux.

## Tools

| Tool | What it checks | How to run |
| --- | --- | --- |
| [`am-i-hacked`](apps/am-i-hacked/README.md) | A project folder, for malicious-code indicators: editor tasks that run on folder open, payloads disguised as asset files, obfuscation, capture code paired with an exfiltration endpoint, `.env` files in the git index, risky `package.json` scripts. With `--system`, this machine: login and startup items and their code signatures, crontab, shell startup files, AI-tool config, running processes. | `pnpx am-i-hacked` |
| [`am-i-being-recorded`](apps/am-i-being-recorded/README.md) | Which browser extension is behind a screen-recording indicator, and what else on the machine can capture you. | From this repository |
| [`am-i-being-recorded`](apps/am-i-being-recorded/README.md) | Which browser extension is behind a screen-recording indicator, and what else on the machine can capture you. | `pnpx am-i-being-recorded` |
| [`secure-semgrep`](apps/secure-semgrep/README.md) | Semgrep rules and loadout packs for AI-agent, bash and web code. Needs `semgrep`. | From this repository |

Agent skills in [`skills/`](skills/): [quarantine-review](skills/quarantine-review/SKILL.md) (inspect an untrusted repository without running any of it), [third-party-skill-intake](skills/third-party-skill-intake/SKILL.md) (vet a skill or plugin from a URL without running its installer), [login-item-triage](skills/login-item-triage/SKILL.md) and [jujutsu](skills/jujutsu/SKILL.md).
Expand Down
19 changes: 19 additions & 0 deletions apps/am-i-being-recorded/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog

Newest first.

## 1.0.0 - 2026-10-05

- Initial release. Audits screen/tab capture surfaces and the browser extensions that can start them on macOS and Linux.
- Reads Chromium-family profile directories (Brave, Chrome, Chromium, Edge, Vivaldi) and flags extensions with `desktopCapture`, `tabCapture`, `debugger`, `nativeMessaging`, `userScripts`, or `management` permissions, each at a calibrated severity.
- Combination rules: `desktopCapture` + broad host permissions escalates to HIGH; any capture permission + `offscreen` escalates to HIGH (persistent-capture shape).
- Only the newest version directory of each extension is reported per profile; stale Chromium copies are skipped.
- Localised extension names (`__MSG_key__`) are resolved from `_locales`; unresolvable names fall back to `(unknown)`.
- Live context (not findings): macOS — `screensharingd` / `replayd` status and camera, microphone, and screen-recording TCC grants with code-signer and Team ID. Linux — which process holds a `/dev/video*` camera device via `lsof`.
- `--strict` gate mode: exits `1` when any finding at or above the severity floor is reported.
- `--min-severity LEVEL` floor filter (CRITICAL / HIGH / MEDIUM / LOW, default LOW).
- `--no-live` skips the platform live checks; used by the test suite.
- Zero npm runtime dependencies. Plain bash, `jq`, and optionally `sqlite3` / `lsof`.
- 23 bats tests covering the extension pass, combination rules, severity filtering, localisation, and error paths.

Install: `pnpm add -D [email protected]`, or run without installing: `pnpx [email protected]`
71 changes: 51 additions & 20 deletions apps/am-i-being-recorded/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# am-i-being-recorded

[![npm version](https://img.shields.io/npm/v/am-i-being-recorded)](https://www.npmjs.com/package/am-i-being-recorded)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![CI](https://github.com/IsaacBell/secure-devtools/actions/workflows/ci.yml/badge.svg)](https://github.com/IsaacBell/secure-devtools/actions/workflows/ci.yml)

Find out **which browser extension is recording your screen** — and what else on
the machine can capture you.

```sh
pnpx am-i-being-recorded # or: npx am-i-being-recorded
```

The sibling of [`am-i-hacked`](https://www.npmjs.com/package/am-i-hacked):
that one audits your *code*, this one audits your *machine*.

Expand All @@ -14,6 +19,31 @@ extension responsible. A purple indicator that says "Brave Browser is recording
your screen" is accurate but not actionable. This tool turns that attribution
back into a name.

## Installation

Requires `jq` to read extension manifests. Everything else is preinstalled on
macOS and most Linux distros.

```sh
# macOS
brew install jq

# Debian/Ubuntu
apt-get install jq
```

Run without installing:

```sh
pnpx am-i-being-recorded
```

Install as a dev dependency:

```sh
pnpm add -D am-i-being-recorded # or: npm install -D am-i-being-recorded
```

## What it checks

**Browser extensions (macOS and Linux).** Reads Chromium-family profile
Expand All @@ -40,21 +70,13 @@ Only the newest installed version of an extension is reported once per profile;
Chromium leaves older version directories behind, and they are not loaded.

**Live context (not findings).** On macOS: whether `screensharingd` and
`replayd` are running, and which apps hold camera/microphone/screen-recording
grants in the TCC privacy database, each with its code signer and Team ID
(`signed: Zoom Video Communications, Inc. [BJ4HAAB9B3]`, `unsigned`, `ad-hoc
signed`). An unsigned app holding a capture grant is worth a look. On Linux: which process holds a camera
device. These lines are context for a human; findings come only from extension
capabilities, so there is no "known good app" allowlist to maintain.

## Requirements

| Dependency | Needed for | Install |
| --- | --- | --- |
| `bash` 4+ | running the tool | preinstalled on macOS/Linux |
| `jq` | reading extension manifests | `brew install jq` / `apt-get install jq` |
| `sqlite3` | macOS TCC grants (optional) | preinstalled on macOS |
| `lsof` | Linux camera holders (optional) | preinstalled on most distros |
`replayd` are running, and which apps hold camera, microphone, and
screen-recording grants in the TCC privacy database, each with its code signer
and Team ID (`signed: Zoom Video Communications, Inc. [BJ4HAAB9B3]`,
`unsigned`, `ad-hoc signed`). An unsigned app holding a capture grant is worth
a look. On Linux: which process holds a `/dev/video*` camera device. These
lines are context for a human; findings come only from extension capabilities,
so there is no "known good app" allowlist to maintain.

## Usage

Expand All @@ -72,7 +94,7 @@ am-i-being-recorded --strict
am-i-being-recorded --root ./fixtures --no-live
```

The command is also installed as a short alias, `aibr`.
The command is also installed as the short alias `aibr`.

Findings are severity-tagged and printed highest first. The default mode is
**evidence**: findings are reported and the exit status stays `0`. `--strict`
Expand Down Expand Up @@ -107,14 +129,23 @@ An extension installed in several profiles shows up once per profile.
scope.
- This is not a malware scanner. Treat it as triage that names a suspect.

## Development
## Contributing

Bug reports and pull requests are welcome at
<https://github.com/IsaacBell/secure-devtools/issues>.

```sh
pnpm test # bats test suite
# Clone the monorepo and work inside this package
cd apps/am-i-being-recorded
pnpm test # bats test suite (runs against synthetic fixtures, not your real browser data)
pnpm lint # shellcheck
pnpm format:check # shfmt
pnpm check # all of the above
```

The test suite drives the filesystem pass against synthetic profile trees, so
it runs without touching the host's real browser data and passes on Linux CI.
The test suite drives the filesystem pass against synthetic profile trees so it
runs without touching the host's real browser data and passes on Linux CI.

## License

MIT — see [LICENSE](LICENSE).
5 changes: 4 additions & 1 deletion apps/am-i-being-recorded/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "am-i-being-recorded",
"version": "0.1.0",
"version": "1.0.0",
"description": "Audit screen/tab capture surfaces and the browser extensions that can start them",
"license": "MIT",
"author": "Isaac Bell <[email protected]>",
Expand All @@ -14,6 +14,8 @@
},
"homepage": "https://github.com/IsaacBell/secure-devtools/tree/main/apps/am-i-being-recorded",

"funding": "https://ko-fi.com/ibell",

"os": [
"darwin",
"linux"
Expand All @@ -27,6 +29,7 @@
"files": [
"bin",
"README.md",
"CHANGELOG.md",
"LICENSE"
],

Expand Down
Loading