# `mix mob.audit_plugins`
[🔗](https://github.com/genericjam/mob_dev/blob/master/lib/mix/tasks/mob.audit_plugins.ex#L1)

Scans every activated Mob plugin's Elixir + C source for risky patterns
(see `MOB_PLUGIN_SECURITY.md`'s default ruleset).

    mix mob.audit_plugins
    mix mob.audit_plugins --plugin mob_demo_haptic_extras
    mix mob.audit_plugins --accept-medium

Rules implemented (in `MobDev.Plugin.Audit`):

  * `Code.eval_string/1,2,3` and `Code.compile_string/1,2`           (high)
  * `:erlang.binary_to_term/1` (the unbounded arity-1 form)          (high)
  * `String.to_atom/1` with a non-literal argument                   (medium)
  * `Application.put_env(:mob, ...)`                                 (medium)
  * `File.write/cp/rm_rf`, `:os.cmd`, `System.cmd`, `Path.expand("~")` (medium)
  * `system(3)`, `popen(3)`, `execve(2)`, `socket(2)` in NIF C       (high/medium)

Kotlin and Swift sources are reported as "not yet audited" — proper
parsers land in a follow-up commit.

## Options

  * `--plugin <name>` — scope the audit to one activated plugin.
  * `--accept-medium` — exit 0 when only mediums are found (highs still
    produce exit 2). Use after you've reviewed and decided to live with
    the medium findings.

## Exit code

  * `0` — no findings, or only `:low` findings, or `:medium` findings with
    `--accept-medium`.
  * `1` — at least one `:medium` finding (without `--accept-medium`).
  * `2` — at least one `:high` finding.

# `activated_plugins`

```elixir
@spec activated_plugins() :: [{atom(), Path.t(), map() | nil}]
```

Returns `{name, dir, manifest}` for every activated plugin, resolving names
through `Mix.Project.deps_paths/0`. Public for testing.

# `audit_all`

```elixir
@spec audit_all(atom() | nil) :: [MobDev.Plugin.Audit.report()]
```

Audits every activated plugin, optionally filtered to one name. Public for
testing — the matching CLI invocation is `mix mob.audit_plugins`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
