Small Security Issues That Shouldn’t Be Ignored: EXIF Exposure and Rate-Limit Weaknesses
When we talk about web application security, the conversation usually revolves around vulnerabilities such as SQL Injection, Cross-Site Scripting, SSRF, IDOR, authentication bypass, or Remote Code Execution.
But application security is not only about finding critical vulnerabilities.
During security testing, we often come across smaller issues that may not immediately result in account takeover or remote code execution, but can still expose sensitive information or make other attacks easier.
Two good examples are EXIF data exposure and rate-limit weaknesses.
EXIF exposure can unintentionally reveal information embedded inside uploaded images, while missing or weak rate limits can allow attackers to automate sensitive functionality such as login attempts, username discovery, password-reset requests, and OTP verification.
Individually, these issues may sometimes have limited impact. However, when combined with other weaknesses, they can become much more interesting from an attacker's perspective.
EXIF Data Exposure
EXIF stands for Exchangeable Image File Format.
When we take a picture using a smartphone or digital camera, the image can contain much more information than what we see visually.
For example, an image may contain metadata such as:
- Camera manufacturer
- Camera model
- Date and time
- GPS coordinates
- Image dimensions
- Software used to modify the image
- Orientation
- Author or copyright information
For example, an image uploaded to a website may visually look like this:
profile.jpgBut internally, it could contain metadata such as:
Camera Make : Apple
Camera Model : iPhone
Date Created : 2026:09:29 18:21:13
GPS Latitude : XX.XXXX
GPS Longitude : XX.XXXX
Software : iOSThe user may never realize that this information is being uploaded along with the photograph.
Why can this become a security issue?
The problem occurs when an application accepts an image from a user and publishes the original file without removing unnecessary metadata.
Imagine a real-estate website where a user uploads a photograph of a property.
The application stores the original image and makes it publicly accessible:
https://example.com/uploads/property/photo.jpgIf the original EXIF metadata is still present, someone who downloads the image may be able to extract GPS coordinates.
A security tester can inspect the image using tools such as:
exiftool photo.jpgIf GPS information is present, the image may reveal the location where it was captured.
This becomes particularly interesting when the uploaded content is associated with sensitive locations such as homes, offices, restricted facilities, or private events.
EXIF Exposure Is Not Always a Vulnerability
It is important to understand the context.
The mere presence of EXIF metadata does not automatically mean that an application has a serious security vulnerability.
For example, a photography website may intentionally preserve camera information because it is part of the product's functionality.
The security concern becomes stronger when:
- Sensitive metadata is exposed unnecessarily.
- GPS coordinates are publicly accessible.
- The original image is accessible to unauthorized users.
- Users are not reasonably expecting the metadata to be published.
- The application handles sensitive photographs.
- The metadata exposes information that can create privacy or security risks.
Therefore, the impact depends heavily on what metadata is exposed and who can access it.
Testing for EXIF Exposure
During an authorized security assessment, a simple test can be performed.
Upload a test image containing known metadata and then download the image from the application.
Inspect it with:
exiftool downloaded-image.jpgLook for information such as:
GPS
Camera
Device
Date
Author
Software
CopyrightThen determine whether the application has:
- Removed the metadata
- Reprocessed the image
- Created a new sanitized copy
- Continued serving the original file
An important distinction is whether the application is serving the original uploaded file or a newly processed image.
A properly implemented image-processing pipeline can remove unnecessary metadata before the image becomes publicly accessible.
Rate-Limit Issues
The second category is rate-limit weaknesses.
Rate limiting is a security control that restricts how frequently a user, device, IP address, account, or other identifier can perform an operation within a specific period.
For example:
Password reset requests:
5 requests / 15 minutesThe exact values will depend on the application's requirements.
Rate limiting is particularly important for security-sensitive endpoints.
Common examples include:
/login
/forgot-password
/reset-password
/send-otp
/verify-otp
/register
/email-verificationWithout appropriate rate limiting, an attacker may be able to repeatedly interact with these endpoints using automation.
Username Enumeration
One common rate-limit-related issue is username enumeration.
Username enumeration occurs when an application allows someone to determine whether a particular username or email address exists.
Consider a login endpoint.
An attacker submits:
POST /login
username=admin@example.com
password=wrongpasswordThe application responds:
Invalid password.The attacker then tries:
POST /login
username=random@example.com
password=wrongpasswordAnd receives:
User does not exist.The difference between these responses tells the attacker that admin@example.com is a valid account.
The application has effectively created an account-discovery mechanism.
Username Enumeration Through Response Differences
The problem isn't limited to error messages.
Enumeration can happen through differences in:
- HTTP status codes
- Response body
- Response length
- Response timing
- Redirect behavior
- Headers
- Error codes
- JSON response fields
For example:
{
"error": "USER_NOT_FOUND"
}versus:
{
"error": "INVALID_PASSWORD"
}Even though the application may not explicitly say "this username exists," the difference allows an attacker to determine it.
Username Enumeration Through Forgot Password
Password-reset functionality is another common place where enumeration appears.
Consider:
POST /forgot-password
email=victim@example.comThe application responds:
Password reset email has been sent.Now the attacker submits:
POST /forgot-password
email=random@example.comAnd receives:
No account exists with this email address.The attacker can now distinguish valid accounts from invalid accounts.
A better approach is to provide a generic response:
If an account exists for this email address, further instructions will be sent.The same response can be returned regardless of whether the account exists.
This prevents the endpoint from becoming an easy account-enumeration oracle.
Missing Rate Limit on Forgot Password
Another common finding is a password-reset endpoint with no effective rate limiting.
For example:
POST /forgot-password
email=victim@example.comIf an attacker can repeatedly send this request without meaningful restrictions, the endpoint can be abused.
The consequences may include:
- Password-reset email flooding
- SMS flooding
- OTP generation abuse
- Increased infrastructure costs
- Abuse of third-party email/SMS providers
- User harassment
- Increased noise around legitimate password-reset messages
Imagine an endpoint that sends an email every time the request is submitted.
An automated client could repeatedly trigger:
Request
↓
Password-reset email
↓
Request
↓
Password-reset email
↓
Request
↓
Password-reset emailThis doesn't necessarily mean that the attacker can reset the victim's password.
However, the missing abuse control is still a security weakness.
Rate Limiting on OTP Generation
OTP functionality is another area where rate limiting is important.
For example:
POST /send-otp
phone=XXXXXXXXXXIf the endpoint generates and sends an OTP every time it is called, an attacker may repeatedly trigger OTP messages.
This can result in:
- SMS flooding
- Email flooding
- Financial costs for SMS providers
- User annoyance
- Abuse of verification infrastructure
The application should therefore control how frequently OTPs can be generated.
For example:
OTP requested
↓
Start cooldown
↓
Additional requests temporarily restricted
↓
OTP expiresThe exact timeout and limits should be based on the application's legitimate use case.
Missing Rate Limit on OTP Verification
OTP verification has a different problem.
Suppose an application uses a six-digit OTP.
There are:
1,000,000possible six-digit combinations.
If an application allows unlimited verification attempts, automated guessing becomes possible.
For example:
POST /verify-otp
otp=123456followed by:
POST /verify-otp
otp=123457and so on.
A secure implementation should limit failed attempts and expire the OTP.
Additional controls can include:
- Maximum verification attempts
- Short OTP lifetime
- OTP invalidation after successful use
- Temporary throttling
- Monitoring suspicious activity
- Binding the OTP to the relevant transaction or session
Login Rate Limiting
Login endpoints are probably the most obvious place where rate limiting is expected.
Without appropriate protections, attackers can automate large numbers of authentication attempts.
A simplified attack could look like:
Username
+
Password list
↓
Automated login requests
↓
Repeated authentication attemptsRate limiting can make automated attacks substantially more difficult.
However, simply implementing an IP-based limit is not always enough.
For example:
100 requests / IPcan potentially be bypassed by distributing requests across multiple IP addresses.
Applications may therefore need a combination of controls involving factors such as:
IP address
Account
Session
Device
Endpoint
Application-wide trafficThe appropriate design depends on the application's architecture and threat model.
Be Careful With Account Lockouts
There is also a balance to maintain.
Suppose an application locks an account after five failed login attempts.
An attacker who knows a victim's username could intentionally submit five incorrect passwords.
The victim's account becomes locked.
The security control has now become an availability problem.
For this reason, applications should carefully design authentication throttling rather than relying exclusively on permanent or easily triggered account lockouts.
Progressive delays, throttling, monitoring, and other controls can sometimes provide better protection while reducing the possibility of attackers intentionally locking legitimate users out.
Rate Limiting Is More Than Returning HTTP 429
A common misconception is:
SECURITY_ADVISORY"We return HTTP 429, therefore rate limiting is implemented."
Not necessarily.
A proper assessment should look at the actual behavior of the application.
For example:
Request 1 → Success
Request 2 → Success
Request 3 → Success
...
Request 20 → 429This suggests some form of rate limiting.
But additional questions should be asked.
Is the limit based only on IP?
Can it be bypassed by changing accounts?
Can it be bypassed by changing sessions?
Does the sensitive operation still happen before the 429 response?
Does the application continue sending emails or SMS messages?
Does the restriction apply consistently across different application nodes?
Does the restriction reset too easily?
The goal is to determine whether the control actually protects the underlying functionality.
How These Small Issues Can Become More Interesting
One of the most important lessons in application security is that vulnerabilities don't always exist in isolation.
Consider this scenario:
Username Enumeration
↓
Identify Valid Accounts
↓
Weak Login Rate Limiting
↓
Automated Authentication Attempts
↓
Potential Account CompromiseAnother example:
Username Enumeration
↓
Identify Valid Email
↓
Password Reset Endpoint
↓
Missing Rate Limiting
↓
Password-reset / OTP AbuseAnd another:
EXIF Metadata Exposure
↓
Sensitive Information Disclosure
↓
Additional Information About TargetNone of these chains automatically means that an account will be compromised.
The important point is that small weaknesses can provide useful capabilities that complement other vulnerabilities.
This is why security testing should not focus exclusively on individual vulnerability categories.
How Developers Can Prevent These Issues
For image uploads, applications should consider stripping unnecessary metadata before storing or publishing images.
A typical workflow could look like:
User Upload
↓
File Validation
↓
Image Processing
↓
Remove Unnecessary Metadata
↓
Re-encode Image
↓
Store Sanitized Image
↓
Serve ImageFor authentication and recovery functionality, applications should implement appropriate abuse controls around:
Login
Password Reset
OTP Generation
OTP Verification
Email Verification
Registration
Username RecoveryApplications should also avoid revealing whether an account exists through different messages, response codes, or observable behavior.
Security Testing Checklist
When testing an application, some simple questions can reveal these weaknesses quickly.
Image Uploads
- Does the application preserve the original image?
- Is EXIF metadata removed?
- Is GPS information exposed?
- Can unauthorized users access uploaded images?
- Is sensitive metadata publicly accessible?
Login
- Is there effective authentication throttling?
- Can valid usernames be identified?
- Are error responses consistent?
- Is throttling based only on IP?
Forgot Password
- Can usernames or email addresses be enumerated?
- Is there a generic response?
- Can the endpoint be called repeatedly?
- Are emails or SMS messages generated for every request?
- Are reset tokens properly protected?
OTP
- Can unlimited OTPs be generated?
- Can unlimited verification attempts be made?
- Does the OTP expire?
- Is it invalidated after successful use?
- Is there appropriate throttling?
Final Thoughts
Security isn't always about discovering a spectacular vulnerability.
Sometimes it is about noticing a small detail that developers overlooked.
An image that quietly exposes GPS coordinates.
A login endpoint that responds differently for valid and invalid usernames.
A password-reset endpoint that can be triggered thousands of times.
An OTP endpoint that accepts unlimited guesses.
Each issue may appear small when viewed independently.
But application security is about understanding how those small weaknesses affect the overall security of the system.
The best security assessments therefore don't stop at:
SECURITY_ADVISORY"Is this exploitable?"
They also ask:
SECURITY_ADVISORY"What information does this expose?"
SECURITY_ADVISORY"What security control is missing?"
SECURITY_ADVISORY"Can this functionality be abused automatically?"
SECURITY_ADVISORY"Can this weakness be combined with another issue?"
That mindset is often what separates a simple vulnerability scan from meaningful security testing.