Siwes
Siwes
P)
BY GROUP 2
SUBMITTED TO
THE
UNIVERSITY OF TECHNOLOGY
SUPERVISED BY
Dr. (Mrs) O.M ALADE
MEMBER LIST
Secure coding practices are essential for developing robust and secure software applications. By following
secure coding guidelines, developers can reduce the likelihood of vulnerabilities and protect against
common security threats. Secure coding practices refer to a set of guidelines, techniques, and best
practices that software developers follow to write code that is resistant to security vulnerabilities and
protects against potential attacks. The primary goal of secure coding practices is to develop robust and
secure software applications that safeguard sensitive data, maintain privacy, and mitigate security risks.
Secure coding practices involve incorporating security considerations into the entire software development
life cycle, from design and implementation to testing and maintenance. By adhering to these practices,
developers can reduce the likelihood of introducing security vulnerabilities and make it harder for attackers
to exploit weaknesses in the application.
Here are some important secure coding practices and guidelines to consider:
1. Input Validation: Validate all input data received from users, whether it's from forms, APIs, or other
sources. Implement input validation checks to ensure that data is of the expected type, length, and format.
This helps prevent common vulnerabilities like SQL injection and cross-site scripting (XSS).
2. Output Encoding: Encode output data appropriately before displaying or storing it. This prevents
malicious content from being executed in the context of the application or altering the intended behavior.
Use output encoding techniques specific to the output context, such as HTML encoding for web
applications.
3. Authentication and Authorization: Implement secure authentication mechanisms to verify the identity
of users and prevent unauthorized access. Enforce strong password policies, consider multi-factor
authentication, and avoid storing passwords in plain text. Implement role-based access control to ensure
that users only have access to the resources they need.
4. Session Management: Securely manage user sessions to prevent session hijacking and session fixation
attacks. Use secure session handling techniques, such as generating unique session IDs, setting session
timeouts, and destroying sessions after logout.
5. Secure Communication: Ensure that all communication channels between different components or
systems are secured using encryption. Use protocols like HTTPS/TLS for web applications to protect data in
transit. Avoid sending sensitive information, such as passwords or API keys, over insecure channels.
6. Error Handling and Logging: Implement proper error handling mechanisms to avoid exposing sensitive
information to potential attackers. Provide user-friendly error messages without revealing implementation
details. Implement secure logging practices to capture relevant information for troubleshooting and
security analysis.
7. Secure Database Access: Use prepared statements or parameterized queries to prevent SQL injection
attacks. Avoid dynamically constructing SQL queries by concatenating user inputs. Implement the principle
of least privilege for database access, ensuring that database accounts have only the necessary
permissions.
8. Secure Configuration Management: Maintain secure configurations for all components of the
application, including the web server, application server, database, and third-party libraries. Disable
unnecessary services, use secure defaults, and keep software components up to date with security
patches.
9. Secure File Handling: Validate and sanitize file uploads to prevent malicious files from being uploaded
and executed on the server. Store uploaded files in a secure location with restricted access. Avoid storing
sensitive information in files or logging files.
10. Regular Security Testing: Perform regular security testing and code reviews to identify vulnerabilities
and weaknesses in the application code. Use automated tools, such as static code analyzers and
vulnerability scanners, in addition to manual review processes.
Remember that secure coding is an ongoing process. Stay updated with the latest security best practices,
follow secure coding standards, and foster a security-aware development culture within your organization.
Secured coding Guidelines and Standards
Secure coding guidelines and standards provide developers with specific recommendations and best
practices to follow when writing code to minimize security vulnerabilities and protect against potential
attacks. Here are some widely recognized secure coding guidelines and standards:
1. OWASP Top Ten: The OWASP Top Ten is a well-known list of the most critical web application security
risks. It provides guidance on how to prevent common vulnerabilities such as injection attacks, cross-site
scripting (XSS), and insecure direct object references. You can find the OWASP Top Ten at:
https://owasp.org/www-project-top-ten/
2. CERT Secure Coding Standards: The CERT Secure Coding Standards, developed by the CERT
Coordination Center at Carnegie Mellon University, offer specific coding guidelines for various
programming languages. They cover topics such as input validation, memory management, and secure
error handling. You can access the CERT Secure Coding Standards at:
https://wiki.sei.cmu.edu/confluence/display/seccode/SEI+CERT+Coding+Standards
3. MISRA C: The MISRA C coding standard provides guidelines for writing secure and reliable C
programming language. It focuses on reducing programming errors and ensuring code safety and
security. The standard is widely used in safety-critical industries such as automotive and aerospace.
More information can be found at: https://www.misra.org.uk/
4. cert Oracle Secure Coding Standard for Java: The CERT Oracle Secure Coding Standard for Java offers
guidelines specifically for secure coding in Java. It covers topics such as input validation, authentication,
and secure use of cryptographic functions. You can find the standard at:
https://wiki.sei.cmu.edu/confluence/display/java/SEI+CERT+Oracle+Coding+Standard+for+Java
5. Microsoft Secure Coding Guidelines: Microsoft provides secure coding guidelines for various
programmming languages and platforms, including C++, .NET, and ASP.NET. Their guidelines cover
topics such as secure input handling, authentication, and data protection. You can access Microsoft's
secure coding guidelines at: https://docs.microsoft.com/en-us/previous-versions/msp-n-p/
6. NIST SP 800-64: NIST Special Publication 800-64 provides guidance on secure software development. It
covers various aspects of the software development life cycle and offers recommendations for secure
coding, testing, and maintenance. You can find the publication at:
https://csrc.nist.gov/publications/detail/sp/800-64/rev-2/final
It's important to note that these guidelines and standards are not exhaustive, and there may be specific
guidelines for different programming languages and frameworks. It's recommended to refer to the official
documentation and resources provided by the organization or community supporting the language or
framework you are using.
Coding standards and guidelines specific to the Python programming language:
1. Code Formatting: - Follow the official Python style guide, known as PEP 8
(https://www.python.org/dev/peps/pep-0008/), for consistent and readable code formatting.- Use
four spaces for indentation (avoid tabs) and ensure lines do not exceed 79 characters in length. -
Use meaningful variable and function names that follow the snake_case naming convention.
2. Comments and Documentation:- Include inline comments to explain complex code logic or provide
context when necessary. Document classes, functions, and modules using docstrings that follow the
conventions outlined in PEP 257.Consider using a documentation generator like Sphinx
(https://www.sphinx-doc.org/) to generate professional-looking documentation.
3. Import Statements:- Import modules and packages on separate lines and order them
alphabetically. Avoid wildcard imports (`from module import *`) as they can pollute the namespace.
Explicitly list imported names to enhance readability and avoid potential naming conflicts.
4. Error Handling: Use try-except blocks for handling exceptions and errors, providing specific
exception types whenever possible. Avoid using bare `except` statements without specifying the
exception type, as this can hide errors and make debugging difficult. Log or raise exceptions
appropriately to provide useful error messages for troubleshooting.
5. Function and Class Design: Follow the single responsibility principle, where functions and classes
should have a clear and focused purpose. Keep functions and methods short and modular, aiming
for a maximum of 20 lines of code. Consider using type hints (introduced in Python 3.5) to improve
code clarity and enable static analysis tools.
6. Testing: Write unit tests using a testing framework like unittest or pytest to ensure code
correctness and maintainability. Aim for high test coverage, including edge cases and error
scenarios. Incorporate continuous integration (CI) tools to automate testing and enforce code
quality check
7. Performance and Efficiency: Use built-in functions and libraries for common operations rather than
reinventing the wheel. Optimize performance-critical sections using techniques like algorithmic
improvements and caching. Profile and benchmark code to identify performance bottlenecks and
optimize accordingly.
8. Version Control and Collaboration: Use a version control system like Git for source code
management, enabling collaboration and easy rollback. Follow proper version control practices,
including frequent commits, meaningful commit messages, and separate branches for new features
or bug fixes. Collaborate effectively by utilizing code reviews, pull requests, and issue tracking
systems.
9. Maintainability and Readability: Keep the codebase clean, organized, and easy to understand.
Break down complex tasks into smaller functions or classes with clear responsibilities. Remove
commented-out code, unused imports, and redundant code to maintain a clean and concise
codebase.
These guidelines provide a foundation for writing Python code that is readable, maintainable, and follows
best practices. It is important to adapt these guidelines based on the specific requirements and
conventions of your development team and project.
CODE REVIEW CHECKLIST (PASSWORD MANAGER)
A code review checklist for a password manager application covering common vulnerabilities related to
input validation, authentication, and data protection
1. Input Validation: Are all user inputs properly validated and sanitized to prevent common
vulnerabilities like SQL injection, cross-site scripting (XSS), and command injection? Are input fields
properly restricted in terms of length and format to prevent buffer overflows and input-based attacks?
Are file uploads and other input mechanisms properly validated and checked for potential security
risks?
2. Authentication: Is the password manager implementing strong and secure password hashing
algorithms like bcrypt or Argon2? Are password policies enforced, such as requiring a minimum length,
complexity, and expiration? Is there protection against brute-force attacks, such as account lockouts or
rate limiting?
3. Session Management: Are sessions securely managed with unique session identifiers generated for
each user session? Are session timeouts implemented to ensure idle sessions are automatically logged
out? Is session fixation prevented by regenerating session identifiers upon successful login?
4. Secure Communication: Are secure communication protocols like HTTPS/TLS used for transmitting
sensitive data, such as login credentials and passwords? Is the application properly configured to
validate server certificates and prevent man-in-the-middle attacks?
5. Password Storage and Encryption: Are passwords properly encrypted and stored using strong
encryption algorithms like bcrypt or Argon2? Is there proper salting and stretching of passwords to
mitigate against password cracking attempts? Is there protection against password leaks due to
potential vulnerabilities in the storage or retrieval process?
6. Access Controls: Are proper access controls implemented to ensure that only authorized users can
access sensitive functions and data? Is there proper segregation of duties to prevent unauthorized
access or misuse of privileged functionalities? Are access control mechanisms regularly reviewed and
updated to reflect changes in user roles and responsibilities?
7. Error Handling and Logging: Are errors properly handled to avoid revealing sensitive information to
potential attackers? Is logging implemented to capture relevant security events and exceptions for
monitoring and auditing purposes? Are log files protected from unauthorized access and regularly
reviewed for potential security incidents?
8. Data Encryption: Is sensitive data encrypted when stored or transmitted, such as passwords, account
information, or backup files? Are encryption algorithms and key management practices in line with
industry standards and best practices? Is encryption used for any data synchronization or backup
processes to protect against unauthorized access?
9. Third-Party Libraries and Dependencies: Are third-party libraries and dependencies regularly updated
with the latest security patches and releases? Are the security risks associated with third-party
components assessed and mitigated? Are trusted sources used for obtaining third-party libraries, and
are their integrity and security verified?
10. Testing and Code Review: Has the code undergone thorough testing, including functional testing,
security testing, and vulnerability scanning? Has the code undergone peer code reviews to identify
potential security vulnerabilities and adherence to secure coding practices? Are there unit tests and
integration tests in place to ensure proper functionality and security of the password manager?
Remember that this checklist is not exhaustive, and additional security considerations may be necessary
based on the specific requirements and threat landscape of the password manager application.
PROGRAM ALGORITHM FOR THE PASSWORD MANAGER
FIRSTPAGE.PY
1. Import the necessary modules: `tkinter`, `sqlite3`, `messagebox`, `*` from tkinter, `backend`, `PIL`, `random_pass_gen`,
`bcrypt`, and `cryptography.fernet`.
2. Set up the connection to the SQLite database and create a cursor object.
- Define the `__init__` method that creates the elements on the page.
- Define the `__init__` method that creates the elements on the page.
- Add labels, entry fields, and buttons for signup and login.
- Define the `__init__` method that creates the elements on the page.
- Add labels, entry fields, and buttons for login and signup.
- Define the `__init__` method that creates the elements on the page.
- Implement functions for saving, generating, searching, deleting, and updating passwords.
- Define the `__init__` method that sets up the application window and creates frames for different pages.
10. Instantiate the `Application` class, set the window size, title, and start the main loop.
RANDOM_PASS_GEN.PY
1. Import the random module and rename it as rd for convenience.
2. Define four strings: caps, small, nums, and special_char, which represent uppercase letters, lowercase letters, digits, and
special characters, respectively.
3. Create a list all_pass by concatenating the four strings above, representing all possible characters for the password.
4. Shuffle the all_pass list using the shuffle() method from the random module to randomize the order of characters.
5. Initialize an empty list called password to store the randomly generated characters.
- In each iteration, randomly select a character from the all_pass list using the choice() method from the random module.
- Append the selected character to the password list.
7. Shuffle the password list using the shuffle() method to further randomize the order of characters.
8. Join the characters in the password list into a string using the join() method with an empty string as the separator.
BACKEND.PY
1. Import the sqlite3 module, which allows Python to interact with SQLite databases.
3. Define a method named create_tab within the Backend class. This method is responsible for creating the "users" table in
the SQLite database named "data.db". The "users" table has three columns: "user_id" (INTEGER PRIMARY KEY), "username"
(CHAR(25)), and "password" (CHAR(30)). It uses a with statement to establish a connection to the database, creates a cursor
object, executes an SQL query to create the table if it does not already exist, and commits the changes.
4. Define a method named create_table within the Backend class. This method is responsible for creating the "password"
table in the SQLite database. The "password" table has four columns: "password_id" (INTEGER PRIMARY KEY), "website"
(CHAR(50)), "username" (CHAR(25)), and "password" (CHAR(20)). It follows a similar process as create_tab to create the table
if it does not exist.
5. Define a method named create_password within the Backend class. This method is used to insert a new password record
into the "password" table. It takes three parameters: "website", "username", and "password". It establishes a connection to
the database, creates a cursor object, executes an SQL query to insert a new row into the "password" table with the provided
values, and commits the changes.
6. Define a method named view_any within the Backend class. This method is responsible for retrieving a password
associated with a given website from the "password" table. It takes the "website" parameter and performs a SELECT query to
fetch the corresponding password from the table. It uses fetchone() to retrieve the result and returns the password.
7. Define a method named update within the Backend class. This method is used to update the username and password
associated with a given website in the "password" table. It takes three parameters: "username", "password", and "website".
It establishes a connection to the database, creates a cursor object, executes an SQL query to update the "username" and
"password" columns in the "password" table based on the provided website, and commits the changes.
8. Define a method named delete within the Backend class. This method is responsible for deleting a password record
associated with a given website from the "password" table. It takes the "website" parameter and performs a DELETE query to
remove the corresponding row from the table.
9. Define a method named create_user within the Backend class. This method is used to insert a new user record into the
"users" table. It takes two parameters: "username" and "password". It establishes a connection to the database, creates a
cursor object, executes an SQL query to insert a new row into the "users" table with the provided values, and commits the
changes.
FIRSTPAGE.PY
# Import all modules
import tkinter as tk
import _tkinter
import sqlite3
import bcrypt
# Define
bk = Backend
conn = sqlite3.connect("data.db")
cursor = conn.cursor()
encryption_key = b'qfRbKPFgVL2pDHzbu6TAPAYKwRnq0fLjAvCA_Xn3S1k='
cipher = Fernet(encryption_key)
class Firstpage(tk.Frame):
tk.Frame.__init__(self, parent)
label1.place(x=170, y=50)
img = ImageTk.PhotoImage(Image.open("Images/padlock-icon.jpg"))
label5.image = img
label5.place(x=250, y=110)
btn1 = tk.Button(self, text="Sign Up", bg="light blue", font=("Arial", 12), relief=GROOVE, command=lambda:
controller.show_frame(Signuppage), cursor="hand2")
btn1.place(x=240, y=450)
btn2.place(x=380, y=450)
# Sign up page
class Signuppage(tk.Frame):
tk.Frame.__init__(self, parent)
def register():
get_username = username.get()
get_password = password.get()
else:
encoded_password = get_password.encode("utf-8")
username.delete(0, END)
password.delete(0, END)
username.focus()
controller.show_frame(Loginpage)
else:
l1.place(x=300, y=50)
user.place(x=200, y=150)
username.place(x=400, y=150)
pass_.place(x=200, y=210)
password.place(x=400, y=210)
btn3.place(x=490, y=310)
l2.place(x=275, y=440)
btn1.place(x=275, y=470)
# Login page
class Loginpage(tk.Frame):
tk.Frame.__init__(self, parent)
def signin():
get_username = username.get()
get_password = password.get()
result = cursor.fetchone()
if result:
if bcrypt.checkpw(get_password.encode("utf-8"), result[0]):
controller.show_frame(Passwordsaver)
else:
else:
else:
l1.place(x=300, y=50)
user.place(x=200, y=200)
username.place(x=400, y=200)
pass_.place(x=200, y=300)
password.place(x=400, y=300)
btn4.place(x=500, y=360)
l2.place(x=290, y=470)
btn1.place(x=290, y=500)
class Passwordsaver(tk.Frame):
tk.Frame.__init__(self, parent)
def saver():
get_website = entry.get().lower()
get_username = entry4.get().lower()
get_password = entry2.get()
Username: {get_username}
Password: {get_password}
""")
if answer:
cipher_password = cipher.encrypt(get_password.encode())
entry.delete(0, "end")
entry4.delete(0, "end")
entry2.delete(0, "end")
entry.focus()
else:
def random_pass():
try:
entry2.delete(0, "end")
length = int(entry3.get())
password = rpg.pass_gen(length)
# pc.copy(password)
entry2.insert(tk.END, password)
entry3.delete(0, "end")
except ValueError:
def search():
try:
searcher = entry.get().lower()
decrypted_password = cipher.decrypt(searched).decode()
entry2.delete(0, "end")
entry.delete(0, "end")
if searched is None:
else:
except TypeError:
entry2.delete(0, "end")
def remove():
deleter = entry.get().lower()
if answer:
bk.delete(self, deleter)
entry.delete(0, "end")
def change():
get_website = entry.get().lower()
get_username = entry4.get().lower()
get_password = entry2.get()
Username: {get_username}
Password: {get_password}
""")
if answer:
cipher_password = cipher.encrypt(get_password.encode())
entry.delete(0, "end")
entry4.delete(0, "end")
entry2.delete(0, "end")
entry.focus()
label.place(x=160, y=220)
entry.place(x=280, y=222)
label4.place(x=160, y=270)
entry4.place(x=283, y=272)
label2.place(x=160, y=320)
entry2.place(x=280, y=322)
label3.place(x=160, y=370)
entry3.place(x=400, y=372)
btn.place(x=160, y=430)
btn2.place(x=160, y=490)
btn3.place(x=318, y=490)
# btn5.place(x=160, y=540)
btn6.place(x=240, y=540)
btn4.place(x=240, y=600)
class Application(tk.Tk):
window = tk.Frame(self)
window.pack()
window.grid_rowconfigure(0, minsize=700)
window.grid_columnconfigure(0, minsize=700)
self.frames = {}
self.frames[i] = frame
self.show_frame(Firstpage)
frame = self.frames[page]
frame.tkraise()
app = Application()
app.maxsize(700, 700)
app.title("Password Manager")
app.mainloop()
BACKEND.PY
import sqlite3
class Backend:
def create_tab(self):
cursor = connection.cursor()
username CHAR(25),
password CHAR(30)
)""")
connection.commit()
def create_table(self):
cursor = connection.cursor()
website CHAR(50),
username CHAR(25),
password CHAR(20)
)""")
connection.commit()
cursor = connection.cursor()
connection.commit()
def view_all(self):
cursor = connection.cursor()
return all_data
cursor = connection.cursor()
rows = cursor.fetchone()
connection.commit()
return row
cursor = connection.cursor()
cursor.execute("UPDATE password SET username=?, password=? WHERE website=?", (username, password, website))
connection.commit()
cursor = connection.cursor()
connection.commit()
cursor = connection.cursor()
connection.commit()
Identifying and fixing vulnerabilities or insecure coding practices found during a code review in a password
manager requires a systematic approach. By following these steps, you can effectively identify and
remediate vulnerabilities or insecure coding practices in a password manager, enhancing its security and
protecting user data:
1. Understand the Vulnerabilities: Review the code review checklist findings and understand the specific
vulnerabilities or insecure coding practices identified. Ensure you have a clear understanding of the
risks associated with each vulnerability.
2. Prioritize the Vulnerabilities: Assess the severity and potential impact of each vulnerability. Prioritize
fixing critical vulnerabilities that pose a significant security risk. Consider the likelihood of exploitation
and the potential impact on user data and system integrity.
3. Analyze the Code: Examine the relevant sections of code where the vulnerabilities are identified.
Understand the flow and logic of the code to pinpoint the root cause of the vulnerabilities. Look for
potential input validation issues, insecure storage or transmission of sensitive data, weak
authentication mechanisms, or other security flaws.
4. Develop a Remediation Plan: Based on the analysis, create a plan to address each vulnerability.
Determine the specific changes or improvements needed to mitigate the risk. This may involve
modifying existing code, adding additional security checks, implementing encryption or secure
communication protocols, or adopting secure coding practices.
5. Fix the Vulnerabilities: Apply the necessary changes to the codebase to address the vulnerabilities.
Follow secure coding practices and apply the recommended fixes based on the checklist findings.
Modify the code to ensure proper input validation, secure authentication and session management,
secure storage and encryption of passwords, and other necessary security measures.
6. Test and Validate: Thoroughly test the updated code to ensure that the vulnerabilities have been
successfully addressed and fixed. Perform functional testing, security testing, and vulnerability
scanning to verify the effectiveness of the remediation efforts. Validate that the fixes do not introduce
new issues or regressions.
7. Review and Iterate: Conduct a secondary code review to validate the effectiveness of the fixes and
ensure that no vulnerabilities were overlooked. Address any feedback or recommendations from the
review process. Continuously monitor and reassess the codebase to identify and address any future
vulnerabilities or evolving security risks.
8. Documentation and Communication: Document the fixes and changes made to address the
vulnerabilities. Update relevant documentation, including code comments, README files, and security
guidelines. Communicate the changes to the development team and stakeholders to raise awareness
about the security improvements implemented.
9. Stay Vigilant: Remember that security is an ongoing process. Stay informed about the latest security
best practices, vulnerabilities, and emerging threats. Regularly review and update your codebase to
incorporate new security measures and address any new vulnerabilities that may arise.