Introduction
Application security encompasses the measures, practices, and tools implemented to protect software applications from threats throughout their lifecycle. As cyber threats continue to evolve in sophistication, securing applications has become a critical priority for organizations. This cheatsheet provides a comprehensive guide to app security best practices for developers, security teams, and organizations to build and maintain secure applications in today’s threat landscape.
Core Security Principles
Defense in Depth
Implement multiple layers of security controls throughout your application:
- Input validation at client side
- Server-side validation
- API gateways
- Web Application Firewalls (WAF)
- Runtime Application Self-Protection (RASP)
- Database security controls
Principle of Least Privilege
| Layer | Implementation |
|---|---|
| Code | Minimize the scope of variables and functions |
| Application | Use role-based access control (RBAC) |
| Database | Create specific database users with minimal permissions |
| Infrastructure | Use service accounts with limited scope |
| API | Implement granular API permissions |
Secure by Default
- Start with restrictive configurations
- Require explicit opt-in for risky features
- Disable unnecessary services and components
- Use secure defaults for all configurable security parameters
- Make secure choices the path of least resistance
Trust Nothing (Zero Trust)
- Verify every request regardless of source
- Authenticate and authorize all users and services
- Validate all data inputs
- Apply least privilege consistently
- Enforce access controls at each layer
Secure Coding Practices
Input Validation
| Validation Type | Description | Example (JavaScript) |
|---|---|---|
| Whitelist/Allow list | Accept only known good inputs | const validStatus = ['active', 'pending', 'closed']; if (!validStatus.includes(status)) { throw new Error('Invalid status'); } |
| Type checking | Ensure inputs are of expected types | if (typeof userId !== 'number') { throw new Error('User ID must be a number'); } |
| Length/Range checks | Verify inputs are within acceptable limits | `if (password.length < 8 |
| Format validation | Check inputs match expected patterns | if (!/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/.test(email)) { throw new Error('Invalid email format'); } |
| Context-specific validation | Validate based on business rules | if (userAge < 18 && accountType === 'adult') { throw new Error('Must be 18+ for this account type'); } |
Output Encoding
| Context | Encoding Method | Example |
|---|---|---|
| HTML | HTML entity encoding | function encodeHTML(text) { return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, '''); } |
| JavaScript | JavaScript escaping | function escapeJS(text) { return JSON.stringify(text).slice(1, -1); } |
| URL | URL encoding | encodeURIComponent(data) |
| SQL | Parameterized queries | db.query('SELECT * FROM users WHERE id = ?', [userId]) |
| XML | XML encoding | function encodeXML(text) { return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, '''); } |
Common Vulnerabilities Prevention
SQL Injection Prevention
✅ Do:
- Use parameterized queries or prepared statements
// Node.js with MySQLconnection.query('SELECT * FROM users WHERE id = ?', [userId]);// Java with JDBCPreparedStatement stmt = connection.prepareStatement("SELECT * FROM users WHERE id = ?");stmt.setInt(1, userId);ResultSet rs = stmt.executeQuery(); - Use ORMs with security features
// Sequelize (Node.js)User.findByPk(userId);
❌ Don’t:
- Concatenate strings to build SQL queries
// VULNERABLE - DON'T DO THISconst query = "SELECT * FROM users WHERE id = '" + userId + "'";
Cross-Site Scripting (XSS) Prevention
✅ Do:
- Encode HTML output based on context
- Implement Content Security Policy (CSP)
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'"> - Use modern frameworks with automatic escaping
// React automatically escapes valuesreturn <div>{userProvidedText}</div>;
❌ Don’t:
- Insert raw user input into HTML
// VULNERABLE - DON'T DO THISelement.innerHTML = userInput; - Use dangerous JavaScript functions with user input
// VULNERABLE - DON'T DO THISeval(userInput);document.write(userInput);
CSRF (Cross-Site Request Forgery) Prevention
✅ Do:
- Use anti-CSRF tokens
<form action="/transfer" method="post"> <input type="hidden" name="_csrf" value="random-token-here"> <!-- other form fields --></form> - Validate Origin/Referer headers
- Implement SameSite cookie attribute
Set-Cookie: sessionid=abc123; SameSite=Strict; Secure; HttpOnly
❌ Don’t:
- Rely solely on cookies for authentication
- Allow state-changing operations via GET requests
Server-Side Request Forgery (SSRF) Prevention
✅ Do:
- Validate and sanitize URLs
- Use allow lists for domains/IP ranges
- Implement network-level blocks
❌ Don’t:
- Allow requests to internal resources
- Blindly follow redirects
Authentication & Authorization
Authentication Best Practices
| Practice | Implementation |
|---|---|
| Multi-factor Authentication (MFA) | Require at least two verification factors:<br>- Something you know (password)<br>- Something you have (phone/token)<br>- Something you are (biometrics) |
| Password Policies | – Minimum length (12+ characters)<br>- Complexity requirements<br>- Check against compromised passwords<br>- Regular password rotation for sensitive systems |
| Secure Credential Storage | – Use strong, adaptive hashing algorithms (bcrypt, Argon2)<br>- Salt passwords<br>- Never store plaintext credentials |
| Account Lockout | – Implement temporary lockouts after failed attempts<br>- Use exponential backoff for retry delays<br>- Alert on suspicious authentication patterns |
| Session Management | – Generate strong session IDs<br>- Implement idle and absolute timeouts<br>- Invalidate sessions after password changes<br>- Allow users to view and terminate active sessions |
Secure Password Hashing Examples
// Node.js with bcrypt
const bcrypt = require('bcrypt');
const saltRounds = 12;
// Hashing
const hashedPassword = await bcrypt.hash(password, saltRounds);
// Verification
const isMatch = await bcrypt.compare(password, hashedPassword);
# Python with Argon2
from argon2 import PasswordHasher
ph = PasswordHasher()
# Hashing
hash = ph.hash(password)
# Verification
try:
ph.verify(hash, password)
# Password is correct
except:
# Password is incorrect
Authorization Best Practices
Role-Based Access Control (RBAC)
// Define roles and permissions
const roles = {
admin: ['read', 'write', 'delete', 'manage_users'],
editor: ['read', 'write'],
viewer: ['read']
};
// Check permission
function hasPermission(user, permission) {
const userRole = user.role;
return roles[userRole] && roles[userRole].includes(permission);
}
// Use in routes/controllers
function deleteResource(user, resourceId) {
if (!hasPermission(user, 'delete')) {
throw new Error('Unauthorized');
}
// Proceed with deletion
}
Attribute-Based Access Control (ABAC)
// More complex policy check
function canAccessResource(user, resource, action) {
// Resource ownership check
if (resource.ownerId === user.id) {
return true;
}
// Department-based check
if (user.department === resource.department && hasPermission(user, action)) {
return true;
}
// Time-based restriction
const currentHour = new Date().getHours();
if (currentHour < 9 || currentHour > 17) {
return false;
}
return false;
}
OAuth 2.0 & OpenID Connect
| Grant Type | Use Case | Security Considerations |
|---|---|---|
| Authorization Code | Web applications | – Use PKCE for public clients<br>- Validate redirect URIs |
| Implicit | Legacy browser-based apps | – Being deprecated<br>- Use Authorization Code with PKCE instead |
| Client Credentials | Service-to-service | – Securely store client secret<br>- Limit scope |
| Resource Owner Password | Legacy/migration | – Avoid if possible<br>- Limit to first-party apps |
| Device Code | Limited input devices | – Short verification codes<br>- Limited lifetime tokens |
Secure Data Handling
Data Classification
| Classification | Examples | Protection Measures |
|---|---|---|
| Public | Marketing materials, public APIs | Basic integrity controls |
| Internal | Employee directory, internal docs | Access controls, basic encryption |
| Confidential | Customer data, business plans | Strong encryption, strict access controls |
| Restricted | Passwords, payment data, PII | Highest security, encryption at rest and in transit, audit trails |
Encryption Best Practices
| Type | Implementation | Examples |
|---|---|---|
| Encryption at Rest | – Encrypt databases, file systems<br>- Secure key management<br>- Consider hardware security modules (HSMs) | – Transparent Data Encryption (TDE)<br>- File system encryption<br>- Encrypted backups |
| Encryption in Transit | – TLS 1.2+ for all connections<br>- Strong cipher preferences<br>- Certificate validation | – HTTPS everywhere<br>- TLS for database connections<br>- API encryption |
| End-to-End Encryption | – Encrypt data at the source<br>- Decrypt only at intended destination | – Signal Protocol<br>- PGP<br>- Customer-managed keys |
Encryption Code Examples
// Node.js symmetric encryption with AES
const crypto = require('crypto');
function encrypt(text, key) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
const authTag = cipher.getAuthTag().toString('hex');
// Return IV + Auth Tag + Encrypted Data
return iv.toString('hex') + authTag + encrypted;
}
function decrypt(encryptedData, key) {
const iv = Buffer.from(encryptedData.substring(0, 32), 'hex');
const authTag = Buffer.from(encryptedData.substring(32, 64), 'hex');
const encryptedText = encryptedData.substring(64);
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
decipher.setAuthTag(authTag);
let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
Secure Key Management
- Use key management services (KMS) provided by cloud providers
- Implement key rotation policies
- Separate storage for keys and encrypted data
- Use hardware security modules for critical keys
- Follow the principle of least privilege for key access
API Security
API Security Checklist
| Category | Best Practices |
|---|---|
| Authentication | – Use OAuth 2.0 or API keys<br>- Implement token-based auth<br>- Consider certificate-based authentication for service-to-service |
| Authorization | – Implement granular permissions<br>- Validate authority for each request<br>- Use scopes to limit token permissions |
| Rate Limiting | – Set request rate thresholds<br>- Implement graduated response (delay → block)<br>- Use token bucket or leaky bucket algorithms |
| Input Validation | – Validate request parameters and body<br>- Implement schema validation<br>- Sanitize all inputs |
| Output Control | – Use clear error messages without sensitive details<br>- Implement response filtering/sanitization<br>- Apply output-specific encoding |
REST API Security Headers
| Header | Purpose | Example |
|---|---|---|
| Authorization | Provide credentials | Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5... |
| Content-Type | Specify request/response format | Content-Type: application/json |
| X-Content-Type-Options | Prevent MIME-sniffing | X-Content-Type-Options: nosniff |
| Strict-Transport-Security | Enforce HTTPS | Strict-Transport-Security: max-age=31536000; includeSubDomains |
| X-Frame-Options | Prevent clickjacking | X-Frame-Options: DENY |
| Cache-Control | Control caching behavior | Cache-Control: no-store, max-age=0 |
| X-Rate-Limit | Communicate rate limits | X-Rate-Limit-Limit: 100 |
GraphQL Security
- Implement depth limiting to prevent nested query attacks
- Use query cost analysis for complexity-based throttling
- Leverage persisted queries for production environments
- Apply field-level authorization
- Avoid exposing error details that reveal schema information
// Apollo Server with depth limiting
const server = new ApolloServer({
typeDefs,
resolvers,
validationRules: [
depthLimit(5), // Limit query depth
costAnalysis({
maximumCost: 1000,
variables: {},
defaultCost: 1,
}),
],
});
Mobile App Security
Android Security Best Practices
| Area | Recommendations |
|---|---|
| Data Storage | – Use Android Keystore for keys and credentials<br>- Implement file-level encryption<br>- Avoid storing sensitive data in SharedPreferences<br>- Securely delete temporary files |
| Network Communication | – Implement certificate pinning<br>- Enforce TLS 1.2+<br>- Verify server certificates<br>- Detect and prevent proxy usage for sensitive operations |
| Authentication | – Support biometric authentication<br>- Implement secure device attestation<br>- Use OAuth 2.0 with PKCE for API auth<br>- Implement app-level MFA |
| Code Protection | – Obfuscate code with ProGuard/R8<br>- Implement anti-tamper checks<br>- Detect rooted devices<br>- Apply string encryption for sensitive values |
| WebView Security | – Disable JavaScript if not needed<br>- Avoid addJavascriptInterface for Android < 4.2<br>- Verify URLs before loading<br>- Handle file access securely |
Android Certificate Pinning Example
// OkHttp Certificate Pinning
val client = OkHttpClient.Builder()
.certificatePinner(
CertificatePinner.Builder()
.add("api.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.add("api.example.com", "sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=")
.build()
)
.build()
iOS Security Best Practices
| Area | Recommendations |
|---|---|
| Data Storage | – Use Keychain for sensitive data<br>- Implement Data Protection API (NSFileProtection)<br>- Avoid storing secrets in NSUserDefaults<br>- Use secure coding for serialization |
| Network Communication | – Implement App Transport Security (ATS)<br>- Use certificate pinning<br>- Validate server certificates<br>- Protect against MITM attacks |
| Authentication | – Leverage Face ID/Touch ID<br>- Implement secure device check<br>- Use secure enclave for biometric auth<br>- Support app-level MFA |
| Code Protection | – Implement jailbreak detection<br>- Add runtime integrity checks<br>- Use code signing<br>- Apply binary obfuscation techniques |
| Privacy | – Request minimum permissions<br>- Provide clear privacy descriptions<br>- Implement proper data deletion<br>- Support privacy management |
iOS Keychain Usage Example
// Save to Keychain
func saveToKeychain(key: String, data: Data) -> Bool {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecValueData as String: data,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemDelete(query as CFDictionary)
let status = SecItemAdd(query as CFDictionary, nil)
return status == errSecSuccess
}
// Retrieve from Keychain
func loadFromKeychain(key: String) -> Data? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne
]
var dataTypeRef: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)
if status == errSecSuccess {
return dataTypeRef as? Data
} else {
return nil
}
}
Cloud & Infrastructure Security
Container Security
| Phase | Practice | Implementation |
|---|---|---|
| Build | Minimize image size | – Use minimal base images (Alpine, distroless)<br>- Multi-stage builds<br>- Remove development tools |
| Build | Scan images | – Use tools like Trivy, Clair, Snyk<br>- Block images with critical CVEs<br>- Automate scanning in CI/CD |
| Deploy | Use immutable containers | – Never modify running containers<br>- Redeploy for updates<br>- Use SHA-specific image references |
| Runtime | Apply least privilege | – Non-root users<br>- Read-only file systems<br>- Minimal capabilities |
| Runtime | Implement network policies | – Pod-to-pod communication restrictions<br>- Default deny rules<br>- Use service meshes for mTLS |
Docker Security Example
# Multi-stage build for minimal attack surface
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production image with minimal footprint
FROM node:18-alpine
RUN apk --no-cache add dumb-init
ENV NODE_ENV production
WORKDIR /app
COPY --from=build /app/dist /app/dist
COPY --from=build /app/node_modules /app/node_modules
# Create non-root user
RUN addgroup -g 1001 nodejs && adduser -u 1001 -G nodejs -s /bin/sh -D nodejs
USER nodejs
# Use dumb-init as entrypoint for proper signal handling
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/server.js"]
# Apply security labels
LABEL org.opencontainers.image.vendor="Company Name"
LABEL org.opencontainers.image.source="https://github.com/company/repo"
LABEL org.opencontainers.image.revision="commit-sha"
Serverless Security
| Concern | Mitigation |
|---|---|
| Function permissions | – Apply least privilege IAM roles<br>- Scope permissions to specific resources<br>- Regularly audit and prune permissions |
| Dependency security | – Scan dependencies for vulnerabilities<br>- Use lockfiles to prevent dependency confusion<br>- Minimize third-party dependencies |
| Environment variables | – Use secret management services<br>- Encrypt sensitive environment variables<br>- Rotate secrets regularly |
| Code injection | – Validate and sanitize all event data<br>- Avoid dangerous functions (eval, exec)<br>- Implement strong input validation |
| DoS protection | – Set appropriate timeouts<br>- Implement circuit breakers<br>- Use throttling and concurrency limits |
Cloud Security Controls
| Control Type | Recommendations |
|---|---|
| Identity & Access Management | – Use managed identity services<br>- Implement just-in-time access<br>- Enable MFA for all users<br>- Apply service control policies |
| Network Security | – Implement private endpoints<br>- Use security groups and NACLs<br>- Enable VPC flow logs<br>- Apply zero-trust network access |
| Data Protection | – Enable default encryption<br>- Use customer-managed keys for sensitive data<br>- Apply object-level permissions<br>- Implement backup encryption |
| Monitoring & Auditing | – Enable cloud trail/audit logs<br>- Set up anomaly detection<br>- Configure automated remediation<br>- Implement compliance reporting |
| Threat Detection | – Deploy cloud security posture management<br>- Enable threat intelligence feeds<br>- Use behavior analytics<br>- Implement automated response |
Security Testing
Testing Types and Tools
| Test Type | Purpose | Tools |
|---|---|---|
| Static Application Security Testing (SAST) | Analyze source code for security flaws | – SonarQube<br>- Checkmarx<br>- Semgrep<br>- ESLint Security Plugin |
| Dynamic Application Security Testing (DAST) | Test running applications for vulnerabilities | – OWASP ZAP<br>- Burp Suite<br>- Arachni<br>- Acunetix |
| Interactive Application Security Testing (IAST) | Combines SAST and DAST for runtime analysis | – Contrast Security<br>- Seeker<br>- InsightAppSec<br>- Hdiv |
| Software Composition Analysis (SCA) | Identify vulnerable dependencies | – Snyk<br>- OWASP Dependency-Check<br>- WhiteSource<br>- Black Duck |
| Penetration Testing | Simulate attacks to find vulnerabilities | – Metasploit<br>- Kali Linux tools<br>- Cobalt Strike<br>- Manual testing |
| Fuzzing | Send random/malformed inputs to find bugs | – AFL++<br>- LibFuzzer<br>- Peach Fuzzer<br>- BooFuzz |
Security Testing in CI/CD
# GitHub Actions security workflow
name: Security Scan
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: npm ci
- name: Run SAST scan
uses: github/codeql-action/analyze@v2
with:
languages: javascript
- name: Run dependency scan
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
- name: Run container scan
uses: aquasecurity/trivy-action@master
with:
image-ref: 'my-app:latest'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Run OWASP ZAP scan
uses: zaproxy/action-full-scan@v0.4.0
with:
target: 'https://staging-app.example.com'
Security Monitoring & Incident Response
Security Monitoring Components
| Component | Purpose | Implementation |
|---|---|---|
| Logging | Record security-relevant events | – Centralized log collection<br>- Structured logging format<br>- Log integrity protection |
| Monitoring | Detect suspicious activities | – Real-time metrics<br>- Anomaly detection<br>- Health checks |
| Alerting | Notify on security events | – Prioritized alerts<br>- Alert thresholds<br>- Escalation paths |
| SIEM | Aggregate and analyze security data | – Log correlation<br>- Threat intelligence integration<br>- Compliance reporting |
| Runtime Protection | Detect and block attacks | – Web Application Firewalls<br>- Runtime Application Self-Protection<br>- API gateways |
Security Logging Best Practices
| Log Type | What to Log |
|---|---|
| Authentication | – Success/failure events<br>- IP addresses<br>- User identifiers<br>- Timestamp and timezone<br>- Authentication method |
| Authorization | – Access attempts (success/failure)<br>- Resource identifiers<br>- User/service identities<br>- Actions attempted |
| Data Access | – Records accessed<br>- Query parameters (sanitized)<br>- Result counts<br>- Access patterns |
| System Changes | – Configuration modifications<br>- Account changes<br>- Permission changes<br>- System state changes |
| Security Events | – Detected threats<br>- Block actions<br>- Security control changes<br>- Scan results |
Incident Response Plan
Preparation
- Document systems and assets
- Establish IR team and roles
- Create communication templates
- Develop playbooks for common incidents
Detection & Analysis
- Monitor security alerts
- Perform initial triage
- Determine scope and impact
- Classify incident severity
Containment
- Isolate affected systems
- Block attack vectors
- Preserve evidence
- Implement temporary workarounds
Eradication
- Remove malicious components
- Patch vulnerabilities
- Reset compromised credentials
- Validate system integrity
Recovery
- Restore from clean backups
- Verify system functionality
- Monitor for recurring issues
- Phase in normal operations
Post-Incident
- Conduct root cause analysis
- Document lessons learned
- Update security controls
- Enhance detection capabilities
Compliance & Regulatory Considerations
Common Regulations by Region
| Region | Regulations | Key Requirements |
|---|---|---|
| Global | ISO 27001, SOC 2 | – Information security management<br>- Risk assessment<br>- Access controls<br>- Vulnerability management |
| United States | HIPAA, PCI DSS, CCPA | – Healthcare data protection<br>- Payment card security<br>- Consumer privacy rights |
| European Union | GDPR | – Data protection by design<br>- Consent for processing<br>- Data subject rights<br>- Breach notification |
| Asia Pacific | PDPA (Singapore), APPI (Japan) | – Personal data protection<br>- Cross-border transfer rules<br>- Breach notification |
Key Compliance Controls for Applications
| Control | Implementation |
|---|---|
| Access control | – Role-based access<br>- Multi-factor authentication<br>- Least privilege<br>- Regular access reviews |
| Data protection | – Encryption (at rest and in transit)<br>- Data minimization<br>- Secure deletion<br>- Data classification |
| Audit logging | – Security event logging<br>- User activity tracking<br>- Log protection and retention<br>- Tamper-evident logs |
| Security testing | – Vulnerability scanning<br>- Penetration testing<br>- Security code reviews<br>- Regular assessments |
| Incident response | – Detection capabilities<br>- Response procedures<br>- Notification processes<br>- Recovery plans |
Resources for Further Learning
Organizations & Standards
OWASP (Open Web Application Security Project)
NIST (National Institute of Standards and Technology)
CIS (Center for Internet Security)
Books & Publications
- “The Web Application Hacker’s Handbook” by Dafydd Stuttard and Marcus Pinto
- “Agile Application Security” by Laura Bell, Jim Bird, and Michael Brunton-Spall
- “Threat Modeling: Designing for Security” by Adam Shostack
- “Cloud Security: A Comprehensive Guide to Secure Cloud Computing” by Ronald L. Krutz and Russell Dean Vines
Online Resources
- PortSwigger Web Security Academy – Free interactive web security training
- Troy Hunt’s Blog – Web security insights and analysis
- Google’s Web Security Guide
- AWS Security Best Practices
- Mozilla Web Security Guidelines
