Token导航 LogoToken导航TokenDH.com
研究检索敏感数据github未标认证来源可访问许可证需确认审计提醒

vgv-static-securityvgv 静态安全

Agent Skill

用于辅助安全审计、权限检查、凭据风险、认证流程和常见漏洞排查。它适合让 Agent 梳理敏感配置、检查依赖风险、分析鉴权逻辑或生成安全复核清单。使用时不能把工具输出直接当最终结论,涉及密钥、令牌、用户数据或生产系统时,应先确认最小权限、脱敏方式和操作边界。

总安装

524

周安装

21

GitHub Stars

102

下载量

170
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:vgv-static-security(vgv 静态安全)
来源仓库:https://github.com/verygoodopensource/very_good_ai_flutter_plugin
仓库路径:skills/vgv-static-security
安装命令:
npx skills add https://github.com/verygoodopensource/very_good_ai_flutter_plugin --skill vgv-static-security
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/verygoodopensource/very_good_ai_flutter_plugin --skill vgv-static-security

简介

用于辅助安全审计、权限检查和认证流程排查。

  • 适合梳理敏感配置、分析鉴权逻辑或生成安全复核清单。
  • 通过 npx skills add 命令从指定 GitHub 仓库安装使用。
  • 不能将工具输出直接当最终结论,涉及密钥或生产系统时应先确认最小权限。
  • vgv-static-security 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

Security

Flutter apps compile all Dart code directly into a binary that runs on untrusted devices. This skill covers static security review for Flutter/Dart codebases, anchored to the VGV Security in Mobile Apps guide and the OWASP Mobile Top 10. Every finding in this skill is something detectable by reading source code — no pen-testing or runtime analysis.

Core Standards

Apply these standards to ALL Flutter security work:

  • Never hardcode secrets — API keys, tokens, and passwords in source code or config files are compiled into the binary and extractable via reverse engineering; serve them from a backend service
  • Use package:flutter_secure_storage for sensitive on-device dataSharedPreferences is plaintext and unencrypted; never store tokens, PII, or session data there
  • All network calls over HTTPS — plain HTTP transmits data in cleartext; never disable certificate validation (the only exception is during development with a local test server)
  • Use Random.secure() for security-sensitive randomnessdart:math's Random() is a pseudo-random number generator, not cryptographically secure
  • Use established crypto packages — never implement custom cryptography; use package:crypto or package:dart_crypt
  • Enforce auth at the repository layer — widget-only auth checks are client-side and bypassable by anyone with access to the device
  • No sensitive data in logsprint(), log(), and debugPrint() output is readable on-device and in crash reporting tools
  • Keep dependencies free of known vulnerabilities — never suppress security advisories without documented justification; scan pubspec.lock with osv-scanner before every release
  • Set android:allowBackup="false" — the Android default silently allows adb backup to extract app data, bypassing package:flutter_secure_storage

Secrets & API Keys

API keys, tokens, and credentials hardcoded in source files or bundled config files are extractable from the compiled binary through reverse engineering. Every secret must be served from a backend service at runtime.

Files to check: Dart source files, google-services.json, .env, *.plist, AndroidManifest.xml, Info.plist.

// ❌ Hardcoded API key — extractable from binary
const apiKey = 'sk-abc123';
const mapboxToken = 'pk.your-token-here';

// ❌ Secret in config — bundled into the app
// google-services.json:
// "api_key": [{ "current_key": "AIzaSy..." }]
// ✅ Fetched from a backend service at runtime — the only safe option
final apiKey = await secretsService.fetchApiKey();

Never commit .env files or files containing real credentials to version control. Use .gitignore to exclude them and a secrets management service instead. Note: --dart-define / String.fromEnvironment compile values into the binary as plaintext and are extractable via reverse engineering — they are not a safe alternative to backend-served secrets.

Secure Data Storage

Sensitive data written to the device must be encrypted. iOS Keychain and Android Keystore provide hardware-backed encrypted storage — package:flutter_secure_storage wraps both.

// ❌ JWT stored in SharedPreferences — plaintext, unencrypted
final prefs = await SharedPreferences.getInstance();
prefs.setString('auth_token', jwt);

// ❌ Sensitive value in a local file — no encryption
await File('${dir.path}/user.json').writeAsString(jsonEncode(user));
// ✅ package:flutter_secure_storage — backed by iOS Keychain / Android Keystore
const storage = FlutterSecureStorage();
await storage.write(key: 'auth_token', value: jwt);
final token = await storage.read(key: 'auth_token');
await storage.delete(key: 'auth_token');

Use SharedPreferences only for non-sensitive user preferences (theme, locale, onboarding state). Never store passwords, session tokens, PII, or private keys there.

Network Security

All communication between a Flutter app and a backend must be encrypted in transit. Plain HTTP exposes data to interception on any network the user connects to.

// ❌ Plain HTTP base URL
final dio = Dio(BaseOptions(baseUrl: 'http://api.example.com'));

// ❌ Certificate validation disabled — vulnerable to MITM attacks
final client = HttpClient()
  ..badCertificateCallback = (cert, host, port) => true;
// ✅ HTTPS base URL
final dio = Dio(BaseOptions(baseUrl: 'https://api.example.com'));

Implement certificate pinning (package:http_certificate_pinning) for endpoints that handle authentication, payments, or personal data. Only accept certificates signed by the expected certificate authority.

Authentication

Authentication controls must be enforced server-side. Client-side checks (in widgets or routing) are UI conveniences only — they can be bypassed by anyone with physical or debugger access to the device.

Server-side enforcement: the server must validate the token on every request. A 401 response from the API is the authoritative auth gate — not a widget conditional.

Biometric authentication: use package:local_auth for biometric gating of sensitive in-app flows — do not invoke platform channels directly.

Use Firebase Authentication or Auth0 for credential management — do not build custom authentication flows.

Cryptography

Custom cryptographic implementations almost always contain subtle bugs. Use peer-reviewed packages and avoid weak or deprecated algorithms.

// ❌ Cryptographically insecure random — dart:math Random is not CSPRNG
import 'dart:math';
final sessionId = Random().nextInt(1 << 32).toRadixString(16);
final iv = List.generate(16, (_) => Random().nextInt(256));

// ❌ Weak hash algorithm — MD5 and SHA-1 are broken for security use
import 'dart:convert';
final hash = md5.convert(utf8.encode(password)).toString();

// ❌ Hardcoded encryption key
const encryptionKey = 'my-secret-key-123';
// ✅ Cryptographically secure random — Random.secure()
import 'dart:math';
final sessionId = Random.secure().nextInt(1 << 32).toRadixString(16);
final iv = List.generate(16, (_) => Random.secure().nextInt(256));

// ✅ Strong hash via package:crypto
import 'package:crypto/crypto.dart';
import 'dart:convert';
final hash = sha256.convert(utf8.encode(data)).toString();

// ✅ Encryption key from secure storage, not source code
final key = await storage.read(key: 'encryption_key');

Avoid: MD5, SHA-1, DES, RC4, ECB mode. Prefer: SHA-256+ for hashing, AES-GCM for encryption, SHA-512-crypt for password storage.

Input Validation

All data from user input must be validated before it reaches a repository or API. Raw TextEditingController.text values sent directly to a backend are an injection risk and may submit malformed data.

// ❌ Raw controller text sent directly to API
ElevatedButton(
  onPressed: () => context.read<AuthBloc>().add(
    LoginRequested(
      email: _emailController.text,
      password: _passwordController.text,
    ),
  ),
  child: const Text('Login'),
);
// ✅ Validated FormzInput values — only valid data reaches the Bloc
class Email extends FormzInput<String, EmailValidationError> {
  const Email.pure() : super.pure('');
  const Email.dirty([super.value = '']) : super.dirty();

  @override
  EmailValidationError? validator(String value) {
    final emailRegex = RegExp(r'^[^@]+@[^@]+\.[^@]+$');
    if (value.isEmpty) return EmailValidationError.empty;
    if (!emailRegex.hasMatch(value)) return EmailValidationError.invalid;
    return null;
  }
}

// In the widget — only submit when the form is valid
if (state.status.isValidated) {
  context.read<AuthBloc>().add(
    LoginRequested(email: state.email.value, password: state.password.value),
  );
}

Use package:formz for all form validation. Define a FormzInput subclass per field with explicit validation rules and length limits.

Logging & Error Exposure

Log output is readable via USB debugging, crash reporting SDKs, and device analytics. Sensitive values that appear in logs are effectively transmitted to any tool connected to the device.

// ❌ Token in log output
debugPrint('Auth token: $token');
log('User data: ${jsonEncode(user)}');
print('Request headers: $headers'); // headers may contain Bearer tokens

// ❌ Exception message exposes internals to the UI
catch (e) {
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text(e.toString())), // may include stack traces or SQL
  );
}
// ✅ Log only non-sensitive identifiers
debugPrint('Login attempt for userId: ${user.id}');

// ✅ Sanitize exception messages before surfacing to UI
catch (e, stackTrace) {
  log('Login failed', error: e, stackTrace: stackTrace); // full detail for crash tools
  emit(state.copyWith(status: LoginStatus.failure)); // generic message to UI
}

Never log: tokens, passwords, full user objects, HTTP request headers (which contain Authorization), or PII (email, phone, SSN).

Dependency Vulnerabilities

Third-party packages are compiled directly into the app binary. A vulnerable or malicious package affects every user on every platform. This is OWASP Mobile Top 10 M2 (Inadequate Supply Chain Security).

  • Run dart pub get to surface GitHub Advisory Database hits
  • Any ignored_advisories entry in pubspec.yaml must have a documented justification comment
  • Scan pubspec.lock with osv-scanner before every release
  • Run dart pub outdated to check for available security patches

See references/supply-chain.md for advisory detection examples, osv-scanner installation, typosquatting signals, and transitive permission creep checks. See references/binary-protection.md for obfuscation, Android backup, and runtime integrity.

Additional Resources

See references/packages.md for the package quick reference and severity triage guide. See references/crypto.md for certificate pinning implementation, biometric authentication example, and password hashing with package:dart_crypt.

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

36.11%
按下载量换算61

Claude

31.07%
按下载量换算53

Cursor

20.06%
按下载量换算34

Gemini CLI

8.55%
按下载量换算15

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

可疑

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills