Search the site
OPERATIONS
Password guessing is slowed down on the sign-in your server already has, with no setup.
Add firewall rules, breached-password checks and GraphQL budgets where you need them.
ON THIS PAGE
Sign-in is rate limited by default
Refuse breached passwords
Block paths by country
Put a budget on GraphQL queries
Trust your proxy for the client address
Status
With a database, the generated server guards sign-in and sign-up: 5 failures per account and 100 per source in 15 minutes.
A refused sign-in takes at least 400 ms and says the same thing whether or not the account exists.
Too many failures answer with DV-EDGE-005 and a retry time.
DVCredentialGuard credentialGuard() => DVCredentialGuard(
provider: LocalAuthProvider(),
velocity: DVVelocityLimiter(
perAccount: const DVVelocityBudget(5, Duration(minutes: 15)),
),
// A range query sends 5 characters of the password's SHA-1, never the password.
breachedPasswords: DVRangeQueryBreachedPasswords.overHttp(
(String prefix) => Uri.parse('https://api.pwnedpasswords.com/range/$prefix'),
),
);Copy code to clipboard
Sign-up and a password change are refused with DV-EDGE-004 when the password is in the breach list.
The range query goes through DV.Http, so its host must be declared under dartvel.http.hosts.
If the service is down, sign-up goes ahead and logs it. Set breachCheckFailsClosed: true to refuse instead.
final DVWaf adminFirewall = DVWaf(
const <DVWafRule>[
DVWafRule(
name: 'admin-from-office-countries',
paths: <String>['/admin/**'],
from: DVWafSource.notIn(<String>['NG', 'GB']),
),
],
// Believed only when the request came through a trusted proxy.
countryOf: DVWaf.countryHeader('cf-ipcountry'),
);
final MiddlewareChain edgeChain = MiddlewareChain()..use(adminFirewall.middleware());Copy code to clipboard
The first rule that matches decides. A refusal is logged with DV-EDGE-003 and the rule's name.
A country header counts only from a proxy you trust. From anywhere else the country is unknown.
lint() lists rules that match everything, and rules that have matched nothing for 90 days.
# pubspec.yaml
dartvel:
api:
graphql:
maxDepth: 8
introspection: authenticated
persistedQueries: preferCopy code to clipboard
Depth and cost budgets are on by default, worked out from your models. A query over budget is refused with DV-EDGE-001.
persistedQueries: require answers only queries in the manifest, with DV-EDGE-002 for the rest.
# pubspec.yaml
dartvel:
server:
trustedProxies: [10.0.0.0/8]
forwardedHeader: x-forwarded-for
ipv6SourcePrefix: 64Copy code to clipboard
Forwarded headers are read only from a peer in trustedProxies. DARTVEL_TRUSTED_PROXIES sets the list at run time.
IPv6 clients are counted per /64 by default, so one host cannot dodge a limit by changing its address.
Partial
Spec section: Edge Security
Planned work and implementation limits
The WAF is not a middleware key or a pubspec setting. You add it to a MiddlewareChain you run.
Sign-in counts are kept per process, and there is no firewall or captcha provider adapter.
Generated clients do not send persisted query hashes yet.
FSL-1.1-MIT licensed. Built with Dartvel.
Dartvel is made by
To the bottom