1. Introduction
When developing a service, there are times when the time spent contemplating the aftermath is longer than that spent implementing the interface.
I experienced this while developing the review feature for a recent tourist attraction content service.
The review feature allows users to write their own reviews and upload photos.
The feature itself seems relatively simple. Users input review content and upload images, which are then saved to the server, and the saved data is displayed back on the screen.
At first, I focused on ensuring that the reviews were registered and retrieved correctly. However, after completing the implementation, I found many more questions arose when looking at it from an operational perspective.
-
What happens if a user inputs a string they didn't expect?
-
What happens if HTML tags or script-like inputs are saved?
-
What if a file is uploaded as an image but is not actually an image?
-
What if the file information and the actual stored data differ during the review editing process?
Features that seemed fine in the development environment revealed several areas for improvement when viewed from an operational standpoint.
In this article, I would like to share the experiences regarding the improvements made to the review feature,input validation, image upload validation, and data integrity managementduring the development process.
2. Issues Discovered in the Production Environment
The review feature is a representative function that allows users to create content themselves.
Unlike the admin interface, users may find it difficult to predict what values to input, and may use the functionality in ways not intended by the developer.
I found the following issues while reviewing based on the operating environment.
Especially, the review feature is an area where users input directly, so it includes not only normal usage scenarios, but also Considering unexpected inputs and exceptions as wellI had to.
|
Classification |
Found issue |
impact |
|---|---|---|
|
Text input |
Strings with the same meaning can be stored in different forms |
Data quality degradation |
|
User input |
HTML tags and script forms can be entered |
Security and operational risks |
|
File Upload |
Determine Image Type Only by MIME Type |
Possibility of Incorrect File Upload |
|
Image Editing |
File Information and Data Information May Be Inconsistent |
Data Consistency Issues |
3. Apply Validation on Text Input Values
The first aspect I improved was the handling of input values for the review body and the author's name.
Initially, we were storing the user-inputted strings as they were.
However, it became apparent that strings with the same meaning could be stored in different forms depending on the input method.
For instance, Full-width Characters and Half-width Charactersmay appear similar to the user, but the system recognizes them as different data.
If this type of data accumulates, it can lead to unexpected issues during search or data management processes.
To address this, before saving String normalization processAdded.
String normalized = Normalizer.normalize(value, Normalizer.Form.NFKC).trim();
if (normalized.indexOf('<') >= 0 || normalized.indexOf('>') >= 0) {
throw new IllegalArgumentException("Review text cannot contain angle brackets.");
}
NFKC (Normalization Form Compatibility Composition)Normalized the string using the applied method, and modified it to restrict saving when < or > characters are included.
In the beginning, the main purpose was to prevent the input of obscene phrases or unnecessary tags.
However, we also considered the possibility that inputs in the form of HTML tags or scripts could be saved during the review process.
Even if there are no immediate issues in the current service structure, when stored data is utilized in other screens or functionalitiesPossibility of issues such as XSS (Cross Site Scripting) occurringThere is.
As a result, this validation has become a task that considers not only simple special character restrictions but also data quality and service stability.
4. Dual Validation Structure of Frontend and Backend
One more aspect I considered while applying input validation was where to perform the validation.
At first, I thought it was sufficient to validate only on the backend.
However, the user could only check for errors after pressing the save button, which was disappointing from a user experience perspective.
So we applied the same validation rules in the front end as well.
const hasUnsafeReviewText = (value: string) => {
const normalized = value.normalize('NFKC');
return normalized.includes('<') || normalized.includes('>');
};
In the front end, we validate the input as soon as the user enters it to provide quick feedback, and in the back end, we set it up to perform final validation using the same rules just before saving.
The roles of each area are as follows.
|
Classification |
role |
|---|---|
|
frontend |
Immediate validation and user feedback provided |
|
backend |
Final validation and data protection just before saving |
After applying this structure, we were able to ensure both user experience and data stability.
Especially Backend validation is essential because frontend validation alone cannot prevent direct API calls or bypass requests.I was able to reconfirm that it is possible.
5. From MIME type validation to actual image validation
The part I was most concerned about in this task was image upload validation.
In the initial implementation, the file's Check only the MIME typewas doing.
For example, if the type is passed as image/png or image/jpeg, it was determined to be an image file.
I thought it was sufficient at the time.
However, during the review process, the question arose: 'Is the file that was transmitted as an image really an image?'
The MIME type is just the information provided by the client and does not guarantee the actual content of the file.
To complement this, the frontend has been modified to first validate whether the file is in JPEG, PNG, GIF, or BMP format by checking the file signature.
And in the backend, we implemented a validation logic to check if the image can actually be decoded.
private boolean isDecodableRasterImage(MultipartFile file) {
try (InputStream inputStream = file.getInputStream()) {
BufferedImage image = ImageIO.read(inputStream);
return image != null
&& image.getWidth() > 0
&& image.getHeight() > 0;
} catch (IOException e) {
return false;
}
}
By extending the validation criteria from MIME types to actual image data, To prevent situations where files instead of images are uploaded more reliablyI could.
6. Data Integrity Management When Modifying Images
Personally, the most impressive task for me was the improvement of the image editing feature.
Users can perform the following tasks during the review editing process.
-
Maintain existing image
-
Delete some existing images
-
Add new images
-
Delete all existing images
To the user, it seems like a simple editing tool, but in reality, multiple data changes occur simultaneously.
Actual file, file identification information (clipId), thumbnail information, review datamust always maintain the same state.
If only some information is changed, there could be a situation where the actual file is deleted but the review data remains, or conversely, the data is deleted but the file continues to exist.
To prevent this,clearly distinguish between files to keep and files to deleteand organized the logic to ensure related data changes together.
Additionally, improvements were made to remove thumbnail information and related identification information when the last image is deleted.
While carrying out this task, I realized that maintaining the consistency of relationships between data might be more important than implementing the functionality.
7. Application results
Through this improvement work, we were able to achieve the following effects.
|
Improvement items |
Application results |
|---|---|
|
String normalization |
Improved data consistency |
|
Blocking HTML tags |
Reduced risk of XSS |
|
Enhanced image validation |
Preventing incorrect file uploads |
|
Dual validation on frontend and backend |
Improved user experience and reliability |
|
Data integrity management |
Reduced file information discrepancies |
Looking at individual tasks, they may seem like small modifications.
However, in a real operating environment, thesesmall validation logics can have a significant impact on service qualityI have experienced that.
8. Conclusion
During this work, I felt again that feature implementation and operational stability are perspectives that differ from each other.
It is hard to say that the service is complete just because the screen is functioning normally.
Even if the user inputs something unexpected, the system must operate reliably, and various data must always maintain a consistent state.
In particular,Input value validation and data integrity managementare areas that users find hard to feel directly.
However, I believe that these invisible aspects ultimately determine the quality of the service.
Through this experience, I was able to once again recognize the importance of thinking not only about feature implementation but also about how data is stored and managed and what problems might arise during operational processes.
In the future, I will continue to practice development that takes into account the operational environment, not just stopping at feature implementation.
zero