Security isn't optional anymore. One vulnerability can compromise user data, destroy trust, and end careers. Yet many developers still overlook fundamental security practices in their rush to ship features.
After reviewing hundreds of codebases, I've identified five critical vulnerabilities that appear repeatedly across projects. Let's fix them.
1. Exposed Sensitive Data in Frontend Code
The Problem: Developers often hardcode API keys, secrets, or configuration directly in frontend code. Remember: anything in your frontend is visible to users.
Bad Practice (Angular):
// ❌ Never do this
export class AuthService {
private apiKey = 'sk_live_51H7xKj2eZvKYlo2C...';
private secretToken = 'my-secret-key-123';
}
Correct Approach:
- Store secrets in environment variables
- Use Angular environment files for configuration
- Never commit sensitive data to version control
// ✅ Correct way
export class AuthService {
private apiUrl = environment.apiUrl;
// API key stays on backend only
}
Backend (Spring Boot):
// ✅ Use application.properties or environment variables
@Value("${api.secret.key}")
private String apiSecretKey;
2. SQL Injection Vulnerabilities
The Problem: Concatenating user input directly into SQL queries opens the door to SQL injection attacks that can expose or destroy your entire database.
Bad Practice (Spring Boot):
// ❌ Dangerous - allows SQL injection
@GetMapping("/users")
public List<User> getUsers(@RequestParam String name) {
String query = "SELECT * FROM users WHERE name = '" + name + "'";
return jdbcTemplate.query(query, new UserRowMapper());
}
An attacker could send: name='; DROP TABLE users; --
Correct Approach:
// ✅ Use parameterized queries
@GetMapping("/users")
public List<User> getUsers(@RequestParam String name) {
String query = "SELECT * FROM users WHERE name = ?";
return jdbcTemplate.query(query, new UserRowMapper(), name);
}
// ✅ Even better - use Spring Data JPA
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByName(String name);
}
3. Cross-Site Scripting (XSS) Attacks
The Problem: Displaying user-generated content without sanitization allows attackers to inject malicious scripts.
Bad Practice (Angular):
// ❌ Dangerous if userComment contains scripts
@Component({
template: `<div [innerHTML]="userComment"></div>`
})
export class CommentComponent {
userComment: string;
}
Correct Approach:
// ✅ Angular sanitizes by default with interpolation
@Component({
template: `<div>{{ userComment }}</div>`
})
// ✅ If you must use innerHTML, sanitize explicitly
import { DomSanitizer } from '@angular/platform-browser';
constructor(private sanitizer: DomSanitizer) {}
getSafeHtml(html: string) {
return this.sanitizer.sanitize(SecurityContext.HTML, html);
}
Backend Validation (Spring Boot):
// ✅ Validate and sanitize input
@PostMapping("/comments")
public Comment createComment(@Valid @RequestBody CommentDTO dto) {
String sanitized = StringEscapeUtils.escapeHtml4(dto.getContent());
return commentService.create(sanitized);
}
4. Broken Authentication & Session Management
The Problem: Weak password policies, insecure token storage, or missing token expiration create easy targets for attackers.
Bad Practice (Angular):
// ❌ Storing JWT in localStorage (vulnerable to XSS)
localStorage.setItem('token', response.token);
Better Approach:
// ✅ Use httpOnly cookies (set from backend)
// Frontend just makes authenticated requests
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler) {
// Cookie sent automatically by browser
return next.handle(req);
}
}
Backend (Spring Boot):
// ✅ Proper JWT implementation
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
Authentication auth = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
request.getUsername(),
request.getPassword()
)
);
String jwt = jwtUtils.generateToken(auth);
// Set httpOnly cookie
ResponseCookie cookie = ResponseCookie.from("token", jwt)
.httpOnly(true)
.secure(true)
.path("/")
.maxAge(3600)
.sameSite("Strict")
.build();
return ResponseEntity.ok()
.header(HttpHeaders.SET_COOKIE, cookie.toString())
.body(new AuthResponse("Login successful"));
}
5. Missing Input Validation
The Problem: Trusting client-side validation alone. Attackers can bypass frontend checks easily.
Bad Practice:
// ❌ Only frontend validation
@Component({
template: `
<input type="email" [(ngModel)]="email" required>
<button (click)="submit()">Submit</button>
`
})
Correct Approach:
Frontend (Angular):
// ✅ Frontend validation for UX
export class FormComponent {
form = new FormGroup({
email: new FormControl('', [Validators.required, Validators.email]),
age: new FormControl('', [Validators.min(18), Validators.max(120)])
});
}
Backend (Spring Boot):
// ✅ Always validate on backend
@PostMapping("/users")
public User createUser(@Valid @RequestBody UserDTO dto) {
return userService.create(dto);
}
@Data
public class UserDTO {
@NotBlank(message = "Email is required")
@Email(message = "Invalid email format")
private String email;
@Min(value = 18, message = "Must be at least 18")
@Max(value = 120, message = "Invalid age")
private Integer age;
@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$")
private String password;
}
Key Takeaways
- Never trust the frontend - All security checks must happen on the backend
- Use parameterized queries - Prevent SQL injection by default
- Sanitize all user input - Both frontend and backend
- Secure authentication - Use httpOnly cookies, strong passwords, token expiration
- Validate everything twice - Frontend for UX, backend for security
Action Items
- [ ] Audit your codebase for hardcoded secrets
- [ ] Review all database queries for SQL injection risks
- [ ] Implement proper input validation on all endpoints
- [ ] Move JWT tokens from localStorage to httpOnly cookies
- [ ] Add backend validation even where frontend validation exists
Security is not a feature—it's a foundation. These fixes might take a few hours, but they could save you from catastrophic breaches.
What security practices have you implemented in your projects? Share your experiences in the comments.
#WebDevelopment #CyberSecurity #Angular #SpringBoot #SoftwareEngineering #Programming
Top comments (0)