Overview
The asynchrony library is designed with security as a core principle. This guide covers security considerations, best practices, and potential risks.
Security Rating: EXCELLENT ⭐⭐⭐⭐⭐
Built-in Security Features
Memory Safety
- ✅ No unsafe functions (strcpy, sprintf, malloc, free)
- ✅ No raw pointers in public API
- ✅ Dynamic containers (std::deque) prevent buffer overflows
- ✅ RAII principles ensure automatic cleanup
- ✅ No use-after-free vulnerabilities
Thread Safety
- ✅ Proper synchronization with mutexes and semaphores
- ✅ Correct memory ordering (acquire/release semantics)
- ✅ No race conditions
- ✅ Atomic operations for lock-free updates
- ✅ No data races
Exception Safety
- ✅ Exceptions caught at thread boundaries
- ✅ Two-level exception catching for robustness
- ✅ Critical exceptions identified and handled
- ✅ No exception leaks to threads
- ✅ Graceful degradation on errors
Type Safety
- ✅ Strong typing throughout
- ✅ C++20 concepts for compile-time checking
- ✅ No unsafe casts
- ✅ No type confusion vulnerabilities
- ✅ Template-based type safety
Resource Management
- ✅ RAII principles throughout
- ✅ std::jthread ensures thread cleanup
- ✅ resource_wrap ensures resource return
- ✅ No resource leaks
- ✅ Graceful shutdown procedures
Callback Security
Callbacks are user-provided code and should be implemented securely.
✅ Good Callback Practices
worker.queue([](auto&& item) {
try {
item.process();
} catch (const std::exception& ex) {
std::cerr << "Error: " << ex.what() << std::endl;
}
});
worker.queue([](auto&& item) {
item.update();
});
worker.queue([](auto&& item) {
auto data = std::move(item);
process(data);
});
❌ Bad Callback Practices
worker.queue([](auto&& item) {
while (true) {
item.process();
}
});
worker.queue([&worker](auto&& item) {
worker.queue(item);
});
worker.queue([](auto&& item) {
throw std::runtime_error("Unhandled error");
});
worker.queue([ptr = nullptr](auto&& item) {
*ptr = item;
});
Deadlock Prevention
Circular Dependencies
Never queue items from within a callback:
}};
void queue(T &&item) noexcept(false)
Queue a work item for processing.
Blocking Operations
Avoid blocking operations in callbacks:
worker.
queue([](
auto&& item) {
std::this_thread::sleep_for(std::chrono::seconds(10));
});
worker.
queue([](
auto&& item) {
item.process();
});
Lock Ordering
If using locks in callbacks, maintain consistent lock ordering:
std::mutex lock1, lock2;
worker.
queue([&](
auto&& item) {
std::scoped_lock l(lock1, lock2);
});
Resource Exhaustion Prevention
Queue Depth Control
Control queue depth to prevent memory exhaustion:
const size_t MAX_QUEUE_DEPTH = 1000;
size_t current_depth = 0;
for (auto& item : items) {
if (current_depth < MAX_QUEUE_DEPTH) {
worker.
queue(std::move(item));
current_depth++;
} else {
std::cerr << "Queue full, dropping item" << std::endl;
}
}
Resource Pool Capacity
Set resource pool capacity appropriately:
for (int i = 0; i < std::thread::hardware_concurrency(); ++i) {
pool.checkin(Connection{});
}
Exception Handling
Callback Exceptions
Exceptions in callbacks are caught and logged:
worker.
queue([](
auto&& item) {
throw std::runtime_error("Error");
});
worker.
queue([](
auto&& item) {
});
Critical Exceptions
Critical exceptions (std::bad_alloc, etc.) are handled specially:
try {
worker.
queue(large_item);
} catch (const std::bad_alloc& ex) {
std::cerr << "Out of memory" << std::endl;
}
Thread Safety
Queue Operations
All queue operations are thread-safe:
std::thread t1([&]() { worker.
queue(item1); });
std::thread t2([&]() { worker.
queue(item2); });
t1.join();
t2.join();
Resource Pool Operations
All resource pool operations are thread-safe:
std::thread t1([&]() {
auto res = pool.
checkout(); });
std::thread t2([&]() {
auto res = pool.
checkout(); });
t1.join();
t2.join();
auto checkout() -> resource_wrap< T >
Shutdown Safety
Graceful Shutdown
Shutdown is graceful and safe:
{
for (int i = 0; i < 100; ++i) {
}
}
Shutdown Timeout
Shutdown has a timeout to prevent indefinite hangs:
Monitoring and Diagnostics
JSON Serialization
Get worker state as JSON:
#include <nlohmann/json.hpp>
auto state = worker.toJson();
std::cout << state.dump(2) << std::endl;
Monitoring Best Practices
auto state = worker.toJson();
auto queue_size = state["itemsSize"];
if (queue_size > THRESHOLD) {
std::cerr << "Warning: Queue depth high" << std::endl;
}
auto outstanding = state["outstandingCallback"];
if (outstanding > 0) {
std::cerr << "Callbacks executing: " << outstanding << std::endl;
}
Security Checklist
Before deploying asynchrony-based code:
- Callbacks handle exceptions properly
- Callbacks don't block indefinitely
- No circular dependencies between workers
- Queue depth is controlled
- Resource pool capacity is appropriate
- Memory usage is monitored
- Thread count is appropriate
- Error handling is comprehensive
- Security review completed
Vulnerability Reporting
If you discover a security vulnerability:
- Do not open a public issue
- Email security details to: githu.nosp@m.b@si.nosp@m.ddiqs.nosp@m.oft..nosp@m.com
- Include:
- Description of vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if available)
We will:
- Acknowledge receipt within 48 hours
- Investigate the vulnerability
- Develop and test a fix
- Release a patched version
- Credit the reporter (if desired)
Additional Resources
FAQ
Q: Is the library safe for production use? A: Yes, the library is designed for production use with proper callback implementation.
Q: Can callbacks be exploited? A: Callbacks are user-provided code. Implement them securely following the guidelines in this document.
Q: What happens if a callback throws an exception? A: The exception is caught and logged. The worker thread continues processing.
Q: Can the queue cause memory exhaustion? A: Yes, if you queue unlimited items. Control queue depth in your application code.
Q: Is the library thread-safe? A: Yes, all public operations are thread-safe.
Q: Can deadlock occur? A: Only if user code creates circular dependencies. Follow the guidelines to prevent this.
Q: What about timing attacks? A: The library is not cryptographic, so timing attacks are not a concern.
Q: How do I report a security issue? A: Email security details to githu.nosp@m.b@si.nosp@m.ddiqs.nosp@m.oft..nosp@m.com (do not open public issues).